Merge remote branch 'smgfs/master'
This commit is contained in:
commit
7fd0f84cce
|
@ -41,6 +41,9 @@ INCS += -I$(FT_SRCDIR)/$(SRC)/ftmod/ftmod_sangoma_boost
|
|||
if SNGSS7
|
||||
INCS += -I/usr/include/sng_ss7/
|
||||
endif
|
||||
if SNGISDN
|
||||
INCS += -I/usr/include/sng_isdn/
|
||||
endif
|
||||
|
||||
MY_CFLAGS = $(INCS) $(FTDM_CFLAGS) -DFTDM_CONFIG_DIR=\"@confdir@\" -DFTDM_MOD_DIR=\"$(moddir)\" @COMP_VENDOR_CFLAGS@ @DEFS@
|
||||
COMPILE = $(CC) $(MY_CFLAGS) $(INCS)
|
||||
|
@ -70,6 +73,7 @@ $(SRC)/hashtable_itr.c \
|
|||
$(SRC)/ftdm_io.c \
|
||||
$(SRC)/ftdm_queue.c \
|
||||
$(SRC)/ftdm_sched.c \
|
||||
$(SRC)/ftdm_call_utils.c \
|
||||
$(SRC)/ftdm_config.c \
|
||||
$(SRC)/ftdm_callerid.c \
|
||||
$(SRC)/fsk.c \
|
||||
|
@ -264,14 +268,19 @@ ftmod_pritap_la_LIBADD = $(MYLIB)
|
|||
endif
|
||||
|
||||
if SNGSS7
|
||||
ftmod_sangoma_ss7_la_SOURCES = $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c \
|
||||
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c \
|
||||
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c \
|
||||
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c \
|
||||
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c \
|
||||
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c \
|
||||
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_timers.c \
|
||||
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c
|
||||
ftmod_sangoma_ss7_la_SOURCES = $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c \
|
||||
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c \
|
||||
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c \
|
||||
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c \
|
||||
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c \
|
||||
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c \
|
||||
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c \
|
||||
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_timers.c \
|
||||
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c \
|
||||
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c \
|
||||
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c \
|
||||
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sts.c \
|
||||
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c
|
||||
ftmod_sangoma_ss7_la_CFLAGS = $(AM_CFLAGS) $(MY_CFLAGS) -D_GNU_SOURCE
|
||||
ftmod_sangoma_ss7_la_LDFLAGS = -module -avoid-version -lsng_ss7
|
||||
ftmod_sangoma_ss7_la_LIBADD = $(MYLIB)
|
||||
|
@ -285,17 +294,16 @@ ftmod_sangoma_isdn_la_SOURCES = $(SRC)/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_is
|
|||
$(SRC)/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c \
|
||||
$(SRC)/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cntrl.c \
|
||||
$(SRC)/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_cfg.c \
|
||||
$(SRC)/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_in.c \
|
||||
$(SRC)/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_rcv.c \
|
||||
$(SRC)/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c \
|
||||
$(SRC)/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_out.c
|
||||
|
||||
|
||||
ftmod_sangoma_isdn_la_CFLAGS = $(AM_CFLAGS) $(MY_CFLAGS)
|
||||
ftmod_sangoma_isdn_la_CFLAGS = $(AM_CFLAGS) $(MY_CFLAGS) -D_GNU_SOURCE
|
||||
ftmod_sangoma_isdn_la_LDFLAGS = -module -avoid-version -lsng_isdn
|
||||
ftmod_sangoma_isdn_la_LIBADD = $(MYLIB)
|
||||
endif
|
||||
|
||||
|
||||
|
||||
if OPENR2
|
||||
ftmod_r2_la_SOURCES = $(SRC)/ftmod/ftmod_r2/ftmod_r2.c
|
||||
ftmod_r2_la_CFLAGS = $(AM_CFLAGS) $(MY_CFLAGS)
|
||||
|
|
|
@ -193,6 +193,18 @@ AM_CONDITIONAL([SNGISDN],[test "${have_sng_isdn}" = "yes"])
|
|||
AC_CHECK_LIB([openr2], [openr2_context_set_io_type], [have_openr2="yes"])
|
||||
AM_CONDITIONAL([OPENR2],[test "${have_openr2}" = "yes"])
|
||||
|
||||
if test "${have_sng_isdn}" = "yes"; then
|
||||
if test "${build}" == "${host}"
|
||||
then
|
||||
case "${host}" in
|
||||
x86_64-*)
|
||||
# X86_64 machines need additional flags when compiling against libsng_isdn
|
||||
CFLAGS="$CFLAGS -DBIT_64 -DALIGN_64BIT"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
|
||||
COMP_VENDOR_CFLAGS="$COMP_VENDOR_CFLAGS"
|
||||
AC_SUBST(COMP_VENDOR_CFLAGS)
|
||||
AC_CONFIG_FILES([Makefile
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
#define FREETDM_LIMIT_REALM "__freetdm"
|
||||
#define FREETDM_VAR_PREFIX "freetdm_"
|
||||
#define FREETDM_VAR_PREFIX_LEN 8
|
||||
#define FREETDM_VAR_PREFIX_LEN (sizeof(FREETDM_VAR_PREFIX)-1)
|
||||
|
||||
SWITCH_MODULE_LOAD_FUNCTION(mod_freetdm_load);
|
||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_freetdm_shutdown);
|
||||
|
@ -87,6 +87,7 @@ static struct {
|
|||
analog_option_t analog_options;
|
||||
switch_hash_t *ss7_configs;
|
||||
int sip_headers;
|
||||
uint8_t crash_on_assert;
|
||||
} globals;
|
||||
|
||||
/* private data attached to each fs session */
|
||||
|
@ -1301,11 +1302,14 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
|
|||
}
|
||||
}
|
||||
|
||||
ftdm_channel_clear_vars(ftdmchan);
|
||||
span_id = ftdm_channel_get_span_id(ftdmchan);
|
||||
chan_id = ftdm_channel_get_id(ftdmchan);
|
||||
|
||||
for (h = var_event->headers; h; h = h->next) {
|
||||
if (!strncasecmp(h->name, FREETDM_VAR_PREFIX, FREETDM_VAR_PREFIX_LEN)) {
|
||||
char *v = h->name + FREETDM_VAR_PREFIX_LEN;
|
||||
if (!zstr(v)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding outbound freetdm variable %s=%s to channel %d:%d\n", v, h->value, span_id, chan_id);
|
||||
ftdm_channel_add_var(ftdmchan, v, h->value);
|
||||
}
|
||||
}
|
||||
|
@ -1316,9 +1320,6 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
|
|||
switch_caller_profile_t *caller_profile;
|
||||
switch_channel_t *channel = switch_core_session_get_channel(*new_session);
|
||||
|
||||
span_id = ftdm_channel_get_span_id(ftdmchan);
|
||||
chan_id = ftdm_channel_get_id(ftdmchan);
|
||||
|
||||
switch_core_session_add_stream(*new_session, NULL);
|
||||
if ((tech_pvt = (private_t *) switch_core_session_alloc(*new_session, sizeof(private_t))) != 0) {
|
||||
tech_init(tech_pvt, *new_session, ftdmchan);
|
||||
|
@ -1402,6 +1403,9 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session
|
|||
switch_core_session_t *session = NULL;
|
||||
private_t *tech_pvt = NULL;
|
||||
switch_channel_t *channel = NULL;
|
||||
ftdm_iterator_t *iter = NULL;
|
||||
const char *var_name = NULL;
|
||||
const char *var_value = NULL;
|
||||
uint32_t spanid, chanid;
|
||||
char name[128];
|
||||
ftdm_caller_data_t *channel_caller_data = ftdm_channel_get_caller_data(sigmsg->channel);
|
||||
|
@ -1510,6 +1514,13 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session
|
|||
if (channel_caller_data->raw_data_len) {
|
||||
switch_channel_set_variable_printf(channel, "freetdm_custom_call_data", "%s", channel_caller_data->raw_data);
|
||||
}
|
||||
/* Add any channel variable to the dial plan */
|
||||
iter = ftdm_channel_get_var_iterator(sigmsg->channel);
|
||||
for ( ; iter; iter = ftdm_iterator_next(iter)) {
|
||||
ftdm_channel_get_current_var(iter, &var_name, &var_value);
|
||||
snprintf(name, sizeof(name), FREETDM_VAR_PREFIX "%s", var_name);
|
||||
switch_channel_set_variable_printf(channel, name, "%s", var_value);
|
||||
}
|
||||
|
||||
switch_channel_set_state(channel, CS_INIT);
|
||||
if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) {
|
||||
|
@ -2106,10 +2117,10 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal)
|
|||
}
|
||||
break;
|
||||
case FTDM_SIGEVENT_SIGSTATUS_CHANGED:
|
||||
{
|
||||
ftdm_signaling_status_t *sigstatus = (ftdm_signaling_status_t*)(sigmsg->raw_data);
|
||||
{
|
||||
ftdm_signaling_status_t sigstatus = sigmsg->raw_data ? *((ftdm_signaling_status_t*)(sigmsg->raw_data)) : sigmsg->sigstatus;
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%d:%d signalling changed to :%s\n",
|
||||
spanid, chanid, ftdm_signaling_status2str(*sigstatus));
|
||||
spanid, chanid, ftdm_signaling_status2str(sigstatus));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -2389,6 +2400,8 @@ static switch_status_t load_config(void)
|
|||
globals.debug = atoi(val);
|
||||
} else if (!strcasecmp(var, "hold-music")) {
|
||||
switch_set_string(globals.hold_music, val);
|
||||
} else if (!strcasecmp(var, "crash-on-assert")) {
|
||||
globals.crash_on_assert = switch_true(val);
|
||||
} else if (!strcasecmp(var, "sip-headers")) {
|
||||
globals.sip_headers = switch_true(val);
|
||||
} else if (!strcasecmp(var, "enable-analog-option")) {
|
||||
|
@ -2619,6 +2632,32 @@ static switch_status_t load_config(void)
|
|||
uint32_t span_id = 0, to = 0, max = 0;
|
||||
ftdm_span_t *span = NULL;
|
||||
analog_option_t analog_options = ANALOG_OPTION_NONE;
|
||||
|
||||
if (name) {
|
||||
zstatus = ftdm_span_find_by_name(name, &span);
|
||||
} else {
|
||||
if (switch_is_number(id)) {
|
||||
span_id = atoi(id);
|
||||
zstatus = ftdm_span_find(span_id, &span);
|
||||
}
|
||||
|
||||
if (zstatus != FTDM_SUCCESS) {
|
||||
zstatus = ftdm_span_find_by_name(id, &span);
|
||||
}
|
||||
}
|
||||
|
||||
if (zstatus != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Error finding FreeTDM span id:%s name:%s\n", switch_str_nil(id), switch_str_nil(name));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!span_id) {
|
||||
span_id = ftdm_span_get_id(span);
|
||||
}
|
||||
|
||||
/* some defaults first */
|
||||
SPAN_CONFIG[span_id].limit_backend = "hash";
|
||||
SPAN_CONFIG[span_id].limit_reset_event = FTDM_LIMIT_RESET_ON_TIMEOUT;
|
||||
|
||||
for (param = switch_xml_child(myspan, "param"); param; param = param->next) {
|
||||
char *var = (char *) switch_xml_attr_soft(param, "name");
|
||||
|
@ -2633,6 +2672,28 @@ static switch_status_t load_config(void)
|
|||
context = val;
|
||||
} else if (!strcasecmp(var, "dialplan")) {
|
||||
dialplan = val;
|
||||
} else if (!strcasecmp(var, "call_limit_backend")) {
|
||||
SPAN_CONFIG[span_id].limit_backend = val;
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Using limit backend %s for span %d\n", SPAN_CONFIG[span_id].limit_backend, span_id);
|
||||
} else if (!strcasecmp(var, "call_limit_rate")) {
|
||||
int calls;
|
||||
int seconds;
|
||||
if (sscanf(val, "%d/%d", &calls, &seconds) != 2) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Invalid %s parameter, format example: 3/1 for 3 calls per second\n", var);
|
||||
} else {
|
||||
if (calls < 1 || seconds < 1) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Invalid %s parameter value, minimum call limit must be 1 per second\n", var);
|
||||
} else {
|
||||
SPAN_CONFIG[span_id].limit_calls = calls;
|
||||
SPAN_CONFIG[span_id].limit_seconds = seconds;
|
||||
}
|
||||
}
|
||||
} else if (!strcasecmp(var, "call_limit_reset_event")) {
|
||||
if (!strcasecmp(val, "answer")) {
|
||||
SPAN_CONFIG[span_id].limit_reset_event = FTDM_LIMIT_RESET_ON_ANSWER;
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Invalid %s parameter value, only accepted event is 'answer'\n", var);
|
||||
}
|
||||
} else if (!strcasecmp(var, "dial-regex")) {
|
||||
dial_regex = val;
|
||||
} else if (!strcasecmp(var, "enable-callerid")) {
|
||||
|
@ -3352,12 +3413,16 @@ static switch_status_t load_config(void)
|
|||
boost_span = boost_spans[i];
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Starting boost span %d\n", ftdm_span_get_id(boost_span));
|
||||
if (ftdm_span_start(boost_span) == FTDM_FAIL) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Error starting boost FreeTDM span %d, error: %s\n",
|
||||
ftdm_span_get_id(boost_span), ftdm_span_get_last_error(boost_span));
|
||||
continue;
|
||||
ftdm_log(FTDM_LOG_ERROR, "Error starting boost FreeTDM span %d, error: %s\n",
|
||||
ftdm_span_get_id(boost_span), ftdm_span_get_last_error(boost_span));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (globals.crash_on_assert) {
|
||||
ftdm_log(FTDM_LOG_WARNING, "Crash on assert enabled\n");
|
||||
ftdm_global_set_crash_policy(FTDM_CRASH_ON_ASSERT);
|
||||
}
|
||||
|
||||
switch_xml_free(xml);
|
||||
|
||||
|
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* Copyright (c) 2010, Sangoma Technologies
|
||||
* David Yat Sin <dyatsin@sangoma.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "private/ftdm_core.h"
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_span_set_npi(const char *npi_string, uint8_t *target)
|
||||
{
|
||||
if (!strcasecmp(npi_string, "isdn") || !strcasecmp(npi_string, "e164")) {
|
||||
*target = FTDM_NPI_ISDN;
|
||||
} else if (!strcasecmp(npi_string, "data")) {
|
||||
*target = FTDM_NPI_DATA;
|
||||
} else if (!strcasecmp(npi_string, "telex")) {
|
||||
*target = FTDM_NPI_TELEX;
|
||||
} else if (!strcasecmp(npi_string, "national")) {
|
||||
*target = FTDM_NPI_NATIONAL;
|
||||
} else if (!strcasecmp(npi_string, "private")) {
|
||||
*target = FTDM_NPI_PRIVATE;
|
||||
} else if (!strcasecmp(npi_string, "reserved")) {
|
||||
*target = FTDM_NPI_RESERVED;
|
||||
} else if (!strcasecmp(npi_string, "unknown")) {
|
||||
*target = FTDM_NPI_UNKNOWN;
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_WARNING, "Invalid NPI value (%s)\n", npi_string);
|
||||
*target = FTDM_NPI_UNKNOWN;
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_span_set_ton(const char *ton_string, uint8_t *target)
|
||||
{
|
||||
if (!strcasecmp(ton_string, "national")) {
|
||||
*target = FTDM_TON_NATIONAL;
|
||||
} else if (!strcasecmp(ton_string, "international")) {
|
||||
*target = FTDM_TON_INTERNATIONAL;
|
||||
} else if (!strcasecmp(ton_string, "local")) {
|
||||
*target = FTDM_TON_SUBSCRIBER_NUMBER;
|
||||
} else if (!strcasecmp(ton_string, "unknown")) {
|
||||
*target = FTDM_TON_UNKNOWN;
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_WARNING, "Invalid TON value (%s)\n", ton_string);
|
||||
*target = FTDM_TON_UNKNOWN;
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_span_set_bearer_capability(const char *bc_string, ftdm_bearer_cap_t *target)
|
||||
{
|
||||
if (!strcasecmp(bc_string, "speech")) {
|
||||
*target = FTDM_BEARER_CAP_SPEECH;
|
||||
} else if (!strcasecmp(bc_string, "unrestricted-digital")) {
|
||||
*target = FTDM_BEARER_CAP_64K_UNRESTRICTED;
|
||||
} else if (!strcasecmp(bc_string, "3.1Khz")) {
|
||||
*target = FTDM_BEARER_CAP_3_1KHZ_AUDIO;
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_WARNING, "Unsupported Bearer Capability value (%s)\n", bc_string);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_span_set_bearer_layer1(const char *bc_string, ftdm_user_layer1_prot_t *target)
|
||||
{
|
||||
if (!strcasecmp(bc_string, "v110")) {
|
||||
*target = FTDM_USER_LAYER1_PROT_V110;
|
||||
} else if (!strcasecmp(bc_string, "ulaw")) {
|
||||
*target = FTDM_USER_LAYER1_PROT_ULAW;
|
||||
} else if (!strcasecmp(bc_string, "alaw")) {
|
||||
*target =FTDM_USER_LAYER1_PROT_ALAW ;
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_WARNING, "Unsupported Bearer Layer1 Prot value (%s)\n", bc_string);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_is_number(char *number)
|
||||
{
|
||||
if (!number) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
for ( ; *number; number++) {
|
||||
if (!isdigit(*number)) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
|
@ -51,6 +51,7 @@
|
|||
#include "ftdm_cpu_monitor.h"
|
||||
|
||||
#define SPAN_PENDING_CHANS_QUEUE_SIZE 1000
|
||||
#define SPAN_PENDING_SIGNALS_QUEUE_SIZE 1000
|
||||
#define FTDM_READ_TRACE_INDEX 0
|
||||
#define FTDM_WRITE_TRACE_INDEX 1
|
||||
|
||||
|
@ -260,6 +261,14 @@ static ftdm_status_t ftdm_set_caller_data(ftdm_span_t *span, ftdm_caller_data_t
|
|||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (caller_data->dnis.plan == FTDM_NPI_INVALID) {
|
||||
caller_data->dnis.plan = span->default_caller_data.dnis.plan;
|
||||
}
|
||||
|
||||
if (caller_data->dnis.type == FTDM_TON_INVALID) {
|
||||
caller_data->dnis.type = span->default_caller_data.dnis.type;
|
||||
}
|
||||
|
||||
if (caller_data->cid_num.plan == FTDM_NPI_INVALID) {
|
||||
caller_data->cid_num.plan = span->default_caller_data.cid_num.plan;
|
||||
}
|
||||
|
@ -283,6 +292,20 @@ static ftdm_status_t ftdm_set_caller_data(ftdm_span_t *span, ftdm_caller_data_t
|
|||
if (caller_data->rdnis.type == FTDM_NPI_INVALID) {
|
||||
caller_data->rdnis.type = span->default_caller_data.rdnis.type;
|
||||
}
|
||||
|
||||
if (caller_data->bearer_capability == FTDM_INVALID_INT_PARM) {
|
||||
caller_data->bearer_capability = span->default_caller_data.bearer_capability;
|
||||
}
|
||||
|
||||
if (caller_data->bearer_layer1 == FTDM_INVALID_INT_PARM) {
|
||||
caller_data->bearer_layer1 = span->default_caller_data.bearer_layer1;
|
||||
}
|
||||
|
||||
if (FTDM_FAIL == ftdm_is_number(caller_data->cid_num.digits)) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "dropping caller id number %s since we only accept digits\n", caller_data->cid_num.digits);
|
||||
caller_data->cid_num.digits[0] = '\0';
|
||||
}
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -386,8 +409,6 @@ static ftdm_status_t ftdm_channel_destroy(ftdm_channel_t *ftdmchan)
|
|||
ftdm_buffer_destroy(&ftdmchan->fsk_buffer);
|
||||
ftdmchan->pre_buffer_size = 0;
|
||||
|
||||
hashtable_destroy(ftdmchan->variable_hash);
|
||||
|
||||
ftdm_safe_free(ftdmchan->dtmf_hangup_buf);
|
||||
|
||||
if (ftdmchan->tone_session.buffer) {
|
||||
|
@ -449,6 +470,9 @@ static ftdm_status_t ftdm_span_destroy(ftdm_span_t *span)
|
|||
if (span->pendingchans) {
|
||||
ftdm_queue_destroy(&span->pendingchans);
|
||||
}
|
||||
if (span->pendingsignals) {
|
||||
ftdm_queue_destroy(&span->pendingsignals);
|
||||
}
|
||||
ftdm_mutex_unlock(span->mutex);
|
||||
ftdm_mutex_destroy(&span->mutex);
|
||||
ftdm_safe_free(span->signal_data);
|
||||
|
@ -798,7 +822,6 @@ FT_DECLARE(ftdm_status_t) ftdm_span_add_channel(ftdm_span_t *span, ftdm_socket_t
|
|||
|
||||
ftdm_buffer_create(&new_chan->digit_buffer, 128, 128, 0);
|
||||
ftdm_buffer_create(&new_chan->gen_dtmf_buffer, 128, 128, 0);
|
||||
new_chan->variable_hash = create_hashtable(16, ftdm_hash_hashfromstring, ftdm_hash_equalkeys);
|
||||
|
||||
new_chan->dtmf_hangup_buf = ftdm_calloc (span->dtmf_hangup_len + 1, sizeof (char));
|
||||
|
||||
|
@ -1168,14 +1191,6 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_set_state(const char *file, const char *f
|
|||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (ftdm_test_flag(ftdmchan->span, FTDM_SPAN_SUSPENDED)) {
|
||||
if (state != FTDM_CHANNEL_STATE_RESTART && state != FTDM_CHANNEL_STATE_DOWN) {
|
||||
ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_ERROR, "Ignored state change request from %s to %s, span %s is suspended\n",
|
||||
ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state), ftdmchan->span->name);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
|
||||
ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_ERROR, "Ignored state change request from %s to %s, the previous state change has not been processed yet\n",
|
||||
ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state));
|
||||
|
@ -1472,7 +1487,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_group(uint32_t group_id, ftdm_dir
|
|||
ftdm_group_channel_use_count(group, &count);
|
||||
|
||||
if (count >= group->chan_count) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "All circuits are busy (%d channels used out of %d available).\n", count, group->chan_count);
|
||||
ftdm_log(FTDM_LOG_WARNING, "All circuits are busy (%d channels used out of %d available).\n", count, group->chan_count);
|
||||
*ftdmchan = NULL;
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
@ -1569,7 +1584,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_span(uint32_t span_id, ftdm_direc
|
|||
ftdm_span_channel_use_count(span, &count);
|
||||
|
||||
if (count >= span->chan_count) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "All circuits are busy: active=%i max=%i.\n", count, span->chan_count);
|
||||
ftdm_log(FTDM_LOG_WARNING, "All circuits are busy: active=%i max=%i.\n", count, span->chan_count);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
|
@ -1935,7 +1950,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_answer(const char *file, const char
|
|||
ftdm_channel_lock(ftdmchan);
|
||||
|
||||
if (ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring answer because the call is already terminating\n");
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring answer because the call is already TERMINATING\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -1947,14 +1962,27 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_answer(const char *file, const char
|
|||
goto done;
|
||||
}
|
||||
|
||||
|
||||
if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS) {
|
||||
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS, 1);
|
||||
}
|
||||
|
||||
/* set state unlocks the channel so we need to re-confirm that the channel hasn't gone to hell */
|
||||
if (ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring answer because the call has moved to TERMINATING while we're moving to PROGRESS\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS_MEDIA) {
|
||||
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, 1);
|
||||
}
|
||||
|
||||
/* set state unlocks the channel so we need to re-confirm that the channel hasn't gone to hell */
|
||||
if (ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring answer because the call has moved to TERMINATING while we're moving to UP\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_UP, 1);
|
||||
|
||||
done:
|
||||
|
@ -1966,24 +1994,12 @@ done:
|
|||
/* lock must be acquired by the caller! */
|
||||
static ftdm_status_t call_hangup(ftdm_channel_t *chan, const char *file, const char *func, int line)
|
||||
{
|
||||
ftdm_set_flag(chan, FTDM_CHANNEL_USER_HANGUP);
|
||||
if (chan->state != FTDM_CHANNEL_STATE_DOWN) {
|
||||
if (chan->state == FTDM_CHANNEL_STATE_HANGUP) {
|
||||
/* make user's life easier, and just ignore double hangup requests */
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
if (chan->state == FTDM_CHANNEL_STATE_TERMINATING && ftdm_test_flag(chan, FTDM_CHANNEL_STATE_CHANGE)) {
|
||||
/* the signaling stack is already terminating the call but has not yet notified the user about it
|
||||
* with SIGEVENT_STOP, we must flag this channel as hangup and wait for the SIGEVENT_STOP before
|
||||
* proceeding, at that point we will move the channel to hangup, but the SIGEVENT_STOP will not
|
||||
* be sent to the user since they already made clear they want to hangup!
|
||||
* */
|
||||
ftdm_set_flag(chan, FTDM_CHANNEL_USER_HANGUP);
|
||||
ftdm_wait_for_flag_cleared(chan, FTDM_CHANNEL_STATE_CHANGE, 5000);
|
||||
if (ftdm_test_flag(chan, FTDM_CHANNEL_STATE_CHANGE)) {
|
||||
ftdm_log_chan(chan, FTDM_LOG_CRIT, "Failed to hangup, state change for %d/%s is still pending!\n", chan->state, ftdm_channel_state2str(chan->state));
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
}
|
||||
ftdm_channel_set_state(file, func, line, chan, FTDM_CHANNEL_STATE_HANGUP, 1);
|
||||
} else {
|
||||
/* the signaling stack did not touch the state,
|
||||
|
@ -2008,6 +2024,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_hangup_with_cause(const char *file,
|
|||
FT_DECLARE(ftdm_status_t) _ftdm_channel_call_hangup(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
ftdm_channel_lock(ftdmchan);
|
||||
ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_CLEARING;
|
||||
call_hangup(ftdmchan, file, func, line);
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
return FTDM_SUCCESS;
|
||||
|
@ -2081,8 +2098,13 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch
|
|||
{
|
||||
ftdm_status_t status = FTDM_SUCCESS;
|
||||
ftdm_channel_lock(ftdmchan);
|
||||
switch (indication) {
|
||||
|
||||
if (ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring answer because the call has moved to TERMINATING while we're moving to PROGRESS\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
switch (indication) {
|
||||
/* FIXME: ring and busy cannot be used with all signaling stacks
|
||||
* (particularly isdn stacks I think, we should emulate or just move to hangup with busy cause) */
|
||||
case FTDM_CHANNEL_INDICATE_RING:
|
||||
|
@ -2109,6 +2131,13 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch
|
|||
if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS) {
|
||||
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS, 1);
|
||||
}
|
||||
|
||||
/* set state unlocks the channel so we need to re-confirm that the channel hasn't gone to hell */
|
||||
if (ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring answer because the call has moved to TERMINATING while we're moving to PROGRESS\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, 1);
|
||||
}
|
||||
break;
|
||||
|
@ -2119,6 +2148,7 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch
|
|||
break;
|
||||
}
|
||||
|
||||
done:
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
|
@ -2128,7 +2158,8 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_place(const char *file, const char
|
|||
{
|
||||
ftdm_status_t status = FTDM_FAIL;
|
||||
|
||||
ftdm_assert(ftdmchan != NULL, "null channel");
|
||||
ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "null channel");
|
||||
ftdm_assert_return(ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND), FTDM_FAIL, "Call place, but outbound flag not set\n");
|
||||
|
||||
ftdm_channel_lock(ftdmchan);
|
||||
|
||||
|
@ -2218,9 +2249,10 @@ static void close_dtmf_debug(ftdm_channel_t *ftdmchan)
|
|||
}
|
||||
#endif
|
||||
|
||||
static ftdm_status_t ftdm_channel_clear_vars(ftdm_channel_t *ftdmchan);
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
assert(ftdmchan != NULL);
|
||||
ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "Null channel can't be done!\n");
|
||||
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
|
||||
|
@ -2248,6 +2280,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan)
|
|||
#ifdef FTDM_DEBUG_DTMF
|
||||
close_dtmf_debug(ftdmchan);
|
||||
#endif
|
||||
ftdm_channel_clear_vars(ftdmchan);
|
||||
|
||||
ftdmchan->init_state = FTDM_CHANNEL_STATE_DOWN;
|
||||
ftdmchan->state = FTDM_CHANNEL_STATE_DOWN;
|
||||
|
@ -2274,14 +2307,12 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_close(ftdm_channel_t **ftdmchan)
|
|||
ftdm_channel_t *check;
|
||||
ftdm_status_t status = FTDM_FAIL;
|
||||
|
||||
assert(ftdmchan != NULL);
|
||||
ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "null channel double pointer provided!\n");
|
||||
ftdm_assert_return(*ftdmchan != NULL, FTDM_FAIL, "null channel pointer provided!\n");
|
||||
|
||||
check = *ftdmchan;
|
||||
*ftdmchan = NULL;
|
||||
|
||||
if (!check) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (ftdm_test_flag(check, FTDM_CHANNEL_CONFIGURED)) {
|
||||
ftdm_mutex_lock(check->mutex);
|
||||
if (ftdm_test_flag(check, FTDM_CHANNEL_OPEN)) {
|
||||
|
@ -3375,8 +3406,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_write(ftdm_channel_t *ftdmchan, void *dat
|
|||
ftdm_size_t max = datasize;
|
||||
unsigned int i = 0;
|
||||
|
||||
assert(ftdmchan != NULL);
|
||||
assert(ftdmchan->fio != NULL);
|
||||
ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "null channel on write!\n");
|
||||
ftdm_assert_return(ftdmchan->fio != NULL, FTDM_FAIL, "null I/O on write!\n");
|
||||
|
||||
if (!ftdmchan->buffer_delay &&
|
||||
((ftdmchan->dtmf_buffer && ftdm_buffer_inuse(ftdmchan->dtmf_buffer)) ||
|
||||
|
@ -3428,16 +3459,16 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_write(ftdm_channel_t *ftdmchan, void *dat
|
|||
return status;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_clear_vars(ftdm_channel_t *ftdmchan)
|
||||
static ftdm_status_t ftdm_channel_clear_vars(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
if(ftdmchan->variable_hash) {
|
||||
ftdm_channel_lock(ftdmchan);
|
||||
|
||||
if (ftdmchan->variable_hash) {
|
||||
hashtable_destroy(ftdmchan->variable_hash);
|
||||
}
|
||||
ftdmchan->variable_hash = create_hashtable(16, ftdm_hash_hashfromstring, ftdm_hash_equalkeys);
|
||||
ftdmchan->variable_hash = NULL;
|
||||
|
||||
if(!ftdmchan->variable_hash)
|
||||
return FTDM_FAIL;
|
||||
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -3445,34 +3476,98 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_add_var(ftdm_channel_t *ftdmchan, const c
|
|||
{
|
||||
char *t_name = 0, *t_val = 0;
|
||||
|
||||
if(!ftdmchan->variable_hash || !var_name || !value)
|
||||
{
|
||||
ftdm_status_t status = FTDM_FAIL;
|
||||
|
||||
if (!var_name || !value) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
ftdm_channel_lock(ftdmchan);
|
||||
|
||||
if (!ftdmchan->variable_hash) {
|
||||
/* initialize on first use */
|
||||
ftdmchan->variable_hash = create_hashtable(16, ftdm_hash_hashfromstring, ftdm_hash_equalkeys);
|
||||
if (!ftdmchan->variable_hash) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
t_name = ftdm_strdup(var_name);
|
||||
t_val = ftdm_strdup(value);
|
||||
|
||||
if(hashtable_insert(ftdmchan->variable_hash, t_name, t_val, HASHTABLE_FLAG_FREE_KEY | HASHTABLE_FLAG_FREE_VALUE)) {
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
return FTDM_FAIL;
|
||||
hashtable_insert(ftdmchan->variable_hash, t_name, t_val, HASHTABLE_FLAG_FREE_KEY | HASHTABLE_FLAG_FREE_VALUE);
|
||||
|
||||
status = FTDM_SUCCESS;
|
||||
|
||||
done:
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
FT_DECLARE(const char *) ftdm_channel_get_var(ftdm_channel_t *ftdmchan, const char *var_name)
|
||||
{
|
||||
if(!ftdmchan->variable_hash || !var_name)
|
||||
{
|
||||
const char *var = NULL;
|
||||
|
||||
ftdm_channel_lock(ftdmchan);
|
||||
|
||||
if (!ftdmchan->variable_hash || !var_name) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
var = (const char *)hashtable_search(ftdmchan->variable_hash, (void *)var_name);
|
||||
|
||||
done:
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
|
||||
return var;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_iterator_t *) ftdm_channel_get_var_iterator(const ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
ftdm_hash_iterator_t *iter = NULL;
|
||||
|
||||
ftdm_channel_lock(ftdmchan);
|
||||
|
||||
iter = ftdmchan->variable_hash == NULL ? NULL : hashtable_first(ftdmchan->variable_hash);
|
||||
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_get_current_var(ftdm_iterator_t *iter, const char **var_name, const char **var_val)
|
||||
{
|
||||
const void *key = NULL;
|
||||
void *val = NULL;
|
||||
|
||||
*var_name = NULL;
|
||||
*var_val = NULL;
|
||||
|
||||
if (!iter) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
hashtable_this(iter, &key, NULL, &val);
|
||||
|
||||
*var_name = key;
|
||||
*var_val = val;
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_iterator_t *) ftdm_iterator_next(ftdm_iterator_t *iter)
|
||||
{
|
||||
if (!iter) {
|
||||
return NULL;
|
||||
}
|
||||
return (const char *) hashtable_search(ftdmchan->variable_hash, (void *)var_name);
|
||||
return hashtable_next(iter);
|
||||
}
|
||||
|
||||
static struct {
|
||||
ftdm_io_interface_t *pika_interface;
|
||||
} interfaces;
|
||||
|
||||
|
||||
FT_DECLARE(char *) ftdm_api_execute(const char *cmd)
|
||||
{
|
||||
ftdm_io_interface_t *fio = NULL;
|
||||
|
@ -4104,6 +4199,9 @@ static ftdm_status_t post_configure_span_channels(ftdm_span_t *span)
|
|||
if (ftdm_test_flag(span, FTDM_SPAN_USE_CHAN_QUEUE)) {
|
||||
status = ftdm_queue_create(&span->pendingchans, SPAN_PENDING_CHANS_QUEUE_SIZE);
|
||||
}
|
||||
if (status == FTDM_SUCCESS && ftdm_test_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE)) {
|
||||
status = ftdm_queue_create(&span->pendingsignals, SPAN_PENDING_SIGNALS_QUEUE_SIZE);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -4369,10 +4467,39 @@ FT_DECLARE(ftdm_status_t) ftdm_group_create(ftdm_group_t **group, const char *na
|
|||
return status;
|
||||
}
|
||||
|
||||
static ftdm_status_t ftdm_span_trigger_signal(const ftdm_span_t *span, ftdm_sigmsg_t *sigmsg)
|
||||
{
|
||||
return span->signal_cb(sigmsg);
|
||||
}
|
||||
|
||||
static ftdm_status_t ftdm_span_queue_signal(const ftdm_span_t *span, ftdm_sigmsg_t *sigmsg)
|
||||
{
|
||||
ftdm_sigmsg_t *new_sigmsg = NULL;
|
||||
|
||||
ftdm_assert_return((sigmsg->raw_data == NULL), FTDM_FAIL, "No raw data should be used with asynchronous notification\n");
|
||||
|
||||
new_sigmsg = ftdm_calloc(1, sizeof(*sigmsg));
|
||||
if (!new_sigmsg) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
memcpy(new_sigmsg, sigmsg, sizeof(*sigmsg));
|
||||
|
||||
ftdm_queue_enqueue(span->pendingsignals, new_sigmsg);
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_span_trigger_signals(const ftdm_span_t *span)
|
||||
{
|
||||
ftdm_sigmsg_t *sigmsg = NULL;
|
||||
while ((sigmsg = ftdm_queue_dequeue(span->pendingsignals))) {
|
||||
ftdm_span_trigger_signal(span, sigmsg);
|
||||
ftdm_safe_free(sigmsg);
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t *sigmsg)
|
||||
{
|
||||
ftdm_status_t status = FTDM_FAIL;
|
||||
|
||||
if (sigmsg->channel) {
|
||||
ftdm_mutex_lock(sigmsg->channel->mutex);
|
||||
}
|
||||
|
@ -4381,10 +4508,13 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
|
|||
switch (sigmsg->event_id) {
|
||||
|
||||
case FTDM_SIGEVENT_SIGSTATUS_CHANGED:
|
||||
if (*((ftdm_signaling_status_t*)(sigmsg->raw_data)) == FTDM_SIG_STATE_UP) {
|
||||
ftdm_set_flag(sigmsg->channel, FTDM_CHANNEL_SIG_UP);
|
||||
} else {
|
||||
ftdm_clear_flag(sigmsg->channel, FTDM_CHANNEL_SIG_UP);
|
||||
{
|
||||
ftdm_signaling_status_t sigstatus = ftdm_test_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE) ? sigmsg->sigstatus : *((ftdm_signaling_status_t*)(sigmsg->raw_data));
|
||||
if (sigstatus == FTDM_SIG_STATE_UP) {
|
||||
ftdm_set_flag(sigmsg->channel, FTDM_CHANNEL_SIG_UP);
|
||||
} else {
|
||||
ftdm_clear_flag(sigmsg->channel, FTDM_CHANNEL_SIG_UP);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -4407,10 +4537,12 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
|
|||
break;
|
||||
|
||||
}
|
||||
|
||||
/* call the user callback only if set */
|
||||
if (span->signal_cb) {
|
||||
status = span->signal_cb(sigmsg);
|
||||
|
||||
/* if the signaling module uses a queue for signaling notifications, then enqueue it */
|
||||
if (ftdm_test_flag(span, FTDM_SPAN_USE_SIGNALS_QUEUE)) {
|
||||
ftdm_span_queue_signal(span, sigmsg);
|
||||
} else {
|
||||
ftdm_span_trigger_signal(span, sigmsg);
|
||||
}
|
||||
|
||||
done:
|
||||
|
@ -4418,7 +4550,7 @@ done:
|
|||
ftdm_mutex_unlock(sigmsg->channel->mutex);
|
||||
}
|
||||
|
||||
return status;
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
static void *ftdm_cpu_monitor_run(ftdm_thread_t *me, void *obj)
|
||||
|
|
|
@ -329,6 +329,7 @@ FT_DECLARE(ftdm_status_t) ftdm_interrupt_wait(ftdm_interrupt_t *interrupt, int m
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
#else
|
||||
pollagain:
|
||||
ints[0].fd = interrupt->readfd;
|
||||
ints[0].events = POLLIN;
|
||||
ints[0].revents = 0;
|
||||
|
@ -343,6 +344,9 @@ FT_DECLARE(ftdm_status_t) ftdm_interrupt_wait(ftdm_interrupt_t *interrupt, int m
|
|||
res = poll(ints, num, ms);
|
||||
|
||||
if (res == -1) {
|
||||
if (errno == EINTR) {
|
||||
goto pollagain;
|
||||
}
|
||||
ftdm_log(FTDM_LOG_CRIT, "interrupt poll failed (%s)\n", strerror(errno));
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
@ -369,12 +373,23 @@ FT_DECLARE(ftdm_status_t) ftdm_interrupt_signal(ftdm_interrupt_t *interrupt)
|
|||
if (!SetEvent(interrupt->event)) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Failed to signal interrupt\n");
|
||||
return FTDM_FAIL;
|
||||
|
||||
}
|
||||
#else
|
||||
int err;
|
||||
if ((err = write(interrupt->writefd, "w", 1)) != 1) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Failed to signal interrupt: %s\n", errno, strerror(errno));
|
||||
return FTDM_FAIL;
|
||||
struct pollfd testpoll;
|
||||
testpoll.revents = 0;
|
||||
testpoll.events = POLLIN;
|
||||
testpoll.fd = interrupt->readfd;
|
||||
err = poll(&testpoll, 1, 0);
|
||||
if (err == 0 && !(testpoll.revents & POLLIN)) {
|
||||
/* we just try to notify if there is nothing on the read fd already,
|
||||
* otherwise users that never call interrupt wait eventually will
|
||||
* eventually have the pipe buffer filled */
|
||||
if ((err = write(interrupt->writefd, "w", 1)) != 1) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Failed to signal interrupt: %s\n", errno, strerror(errno));
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return FTDM_SUCCESS;
|
||||
|
@ -390,6 +405,7 @@ FT_DECLARE(ftdm_status_t) ftdm_interrupt_destroy(ftdm_interrupt_t **ininterrupt)
|
|||
#else
|
||||
close(interrupt->readfd);
|
||||
close(interrupt->writefd);
|
||||
|
||||
interrupt->readfd = -1;
|
||||
interrupt->writefd = -1;
|
||||
#endif
|
||||
|
@ -402,6 +418,7 @@ FT_DECLARE(ftdm_status_t) ftdm_interrupt_multiple_wait(ftdm_interrupt_t *interru
|
|||
{
|
||||
int numdevices = 0;
|
||||
unsigned i;
|
||||
|
||||
#if defined(__WINDOWS__)
|
||||
DWORD res = 0;
|
||||
HANDLE ints[20];
|
||||
|
@ -414,6 +431,7 @@ FT_DECLARE(ftdm_status_t) ftdm_interrupt_multiple_wait(ftdm_interrupt_t *interru
|
|||
for (i = 0; i < size; i++) {
|
||||
ints[i] = interrupts[i]->event;
|
||||
if (interrupts[i]->device != FTDM_INVALID_SOCKET) {
|
||||
|
||||
ints[size+numdevices] = interrupts[i]->device;
|
||||
numdevices++;
|
||||
}
|
||||
|
@ -440,7 +458,7 @@ FT_DECLARE(ftdm_status_t) ftdm_interrupt_multiple_wait(ftdm_interrupt_t *interru
|
|||
struct pollfd ints[size*2];
|
||||
|
||||
memset(&ints, 0, sizeof(ints));
|
||||
|
||||
pollagain:
|
||||
for (i = 0; i < size; i++) {
|
||||
ints[i].events = POLLIN;
|
||||
ints[i].revents = 0;
|
||||
|
@ -449,6 +467,7 @@ FT_DECLARE(ftdm_status_t) ftdm_interrupt_multiple_wait(ftdm_interrupt_t *interru
|
|||
ints[size+numdevices].events = POLLIN;
|
||||
ints[size+numdevices].revents = 0;
|
||||
ints[size+numdevices].fd = interrupts[i]->device;
|
||||
|
||||
numdevices++;
|
||||
}
|
||||
}
|
||||
|
@ -456,6 +475,9 @@ FT_DECLARE(ftdm_status_t) ftdm_interrupt_multiple_wait(ftdm_interrupt_t *interru
|
|||
res = poll(ints, size + numdevices, ms);
|
||||
|
||||
if (res == -1) {
|
||||
if (errno == EINTR) {
|
||||
goto pollagain;
|
||||
}
|
||||
ftdm_log(FTDM_LOG_CRIT, "interrupt poll failed (%s)\n", strerror(errno));
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
|
|
@ -2534,46 +2534,6 @@ static FIO_SPAN_GET_SIG_STATUS_FUNCTION(sangoma_boost_get_span_sig_status)
|
|||
return sangoma_boost_data->sigmod->get_span_sig_status(span, status);
|
||||
}
|
||||
|
||||
/* TODO: move these ones to a common private header so other ISDN mods can use them */
|
||||
static void ftdm_span_set_npi(const char *npi_string, uint8_t *target)
|
||||
{
|
||||
if (!strcasecmp(npi_string, "isdn") || !strcasecmp(npi_string, "e164")) {
|
||||
*target = FTDM_NPI_ISDN;
|
||||
} else if (!strcasecmp(npi_string, "data")) {
|
||||
*target = FTDM_NPI_DATA;
|
||||
} else if (!strcasecmp(npi_string, "telex")) {
|
||||
*target = FTDM_NPI_TELEX;
|
||||
} else if (!strcasecmp(npi_string, "national")) {
|
||||
*target = FTDM_NPI_NATIONAL;
|
||||
} else if (!strcasecmp(npi_string, "private")) {
|
||||
*target = FTDM_NPI_PRIVATE;
|
||||
} else if (!strcasecmp(npi_string, "reserved")) {
|
||||
*target = FTDM_NPI_RESERVED;
|
||||
} else if (!strcasecmp(npi_string, "unknown")) {
|
||||
*target = FTDM_NPI_UNKNOWN;
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_WARNING, "Invalid NPI value (%s)\n", npi_string);
|
||||
*target = FTDM_NPI_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
static void ftdm_span_set_ton(const char *ton_string, uint8_t *target)
|
||||
{
|
||||
if (!strcasecmp(ton_string, "national")) {
|
||||
*target = FTDM_TON_NATIONAL;
|
||||
} else if (!strcasecmp(ton_string, "international")) {
|
||||
*target = FTDM_TON_INTERNATIONAL;
|
||||
} else if (!strcasecmp(ton_string, "local")) {
|
||||
*target = FTDM_TON_SUBSCRIBER_NUMBER;
|
||||
} else if (!strcasecmp(ton_string, "unknown")) {
|
||||
*target = FTDM_TON_UNKNOWN;
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_WARNING, "Invalid TON value (%s)\n", ton_string);
|
||||
*target = FTDM_TON_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Initialises an sangoma boost span from configuration variables
|
||||
* \param span Span to configure
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -46,116 +46,28 @@
|
|||
|
||||
#include <sng_isdn.h>
|
||||
|
||||
#define MAX_SPANS_PER_NFAS_LINK 8 /* TODO: Confirm this value */
|
||||
#define NUM_E1_CHANNELS_PER_SPAN 32
|
||||
#define NUM_T1_CHANNELS_PER_SPAN 24
|
||||
#define NUM_BRI_CHANNELS_PER_SPAN 2
|
||||
/* Theoretical limit for MAX_SPANS_PER_NFAS_LINK is 31,
|
||||
but set to 8 for now to save some memor */
|
||||
|
||||
/* Should never have DEBUG_MODE defined when used in production */
|
||||
#if 0
|
||||
#undef DEBUG_MODE
|
||||
#define FORCE_SEFGAULT
|
||||
#else
|
||||
#define DEBUG_MODE
|
||||
#define FORCE_SEGFAULT *(int *) 0 = 0;
|
||||
#endif
|
||||
#define MAX_SPANS_PER_NFAS_LINK 8
|
||||
#define NUM_E1_CHANNELS_PER_SPAN 32
|
||||
#define NUM_T1_CHANNELS_PER_SPAN 24
|
||||
#define NUM_BRI_CHANNELS_PER_SPAN 2
|
||||
#define SNGISDN_EVENT_QUEUE_SIZE 100
|
||||
#define SNGISDN_EVENT_POLL_RATE 100
|
||||
|
||||
/* TODO: rename all *_cc_* to *_an_* */
|
||||
|
||||
typedef struct sngisdn_glare_data {
|
||||
int16_t suId;
|
||||
uint32_t suInstId;
|
||||
uint32_t spInstId;
|
||||
int16_t dChan;
|
||||
ConEvnt setup;
|
||||
uint8_t ces;
|
||||
}sngisdn_glare_data_t;
|
||||
|
||||
|
||||
/* Channel specific data */
|
||||
typedef struct sngisdn_chan_data {
|
||||
ftdm_channel_t *ftdmchan;
|
||||
uint32_t flags;
|
||||
uint8_t ces; /* not used for now */
|
||||
uint8_t dchan_id;
|
||||
uint32_t suInstId; /* instance ID generated locally */
|
||||
uint32_t spInstId; /* instance ID generated by stack */
|
||||
|
||||
uint8_t globalFlg;
|
||||
sngisdn_glare_data_t glare;
|
||||
} sngisdn_chan_data_t;
|
||||
|
||||
/* Span specific data */
|
||||
typedef struct sngisdn_span_data {
|
||||
ftdm_span_t *ftdm_span;
|
||||
uint8_t link_id;
|
||||
uint8_t switchtype;
|
||||
uint8_t signalling; /* SNGISDN_SIGNALING_CPE or SNGISDN_SIGNALING_NET */
|
||||
uint8_t cc_id;
|
||||
uint8_t dchan_id;
|
||||
uint8_t span_id;
|
||||
uint8_t tei;
|
||||
uint8_t keep_link_up;
|
||||
uint8_t trace_flags;
|
||||
} sngisdn_span_data_t;
|
||||
|
||||
/* dchan_data can have more than 1 span when running NFAS */
|
||||
typedef struct sngisdn_dchan_data {
|
||||
uint8_t num_spans;
|
||||
sngisdn_span_data_t *spans[MAX_L1_LINKS+1];
|
||||
uint16_t num_chans;
|
||||
/* worst case for number of channel is when using NFAS, and NFAS is only used on T1,
|
||||
so we can use MAX_SPANS_PER_NFAS_LINK*NUM_T1_CHANNELS_PER_SPAN instead of
|
||||
MAX_SPANS_PER_NFAS_LINK*NUM_E1_CHANNELS_PER_SPAN
|
||||
*/
|
||||
/* Never seen NFAS on E1 yet, so use NUM_T1_CHANNELS_PER_SPAN */
|
||||
/* b-channels are arranged by physical id's not logical */
|
||||
sngisdn_chan_data_t *channels[MAX_SPANS_PER_NFAS_LINK*NUM_T1_CHANNELS_PER_SPAN];
|
||||
}sngisdn_dchan_data_t;
|
||||
|
||||
typedef struct sngisdn_cc {
|
||||
/* TODO: use flags instead of config_done and activation_done */
|
||||
uint8_t config_done;
|
||||
uint8_t activation_done;
|
||||
uint8_t switchtype;
|
||||
ftdm_trunk_type_t trunktype;
|
||||
uint32_t last_suInstId;
|
||||
ftdm_mutex_t *request_mutex;
|
||||
sngisdn_chan_data_t *active_spInstIds[MAX_INSTID];
|
||||
sngisdn_chan_data_t *active_suInstIds[MAX_INSTID];
|
||||
}sngisdn_cc_t;
|
||||
|
||||
/* Global sngisdn data */
|
||||
typedef struct ftdm_sngisdn_data {
|
||||
uint8_t gen_config_done;
|
||||
uint8_t num_cc; /* 1 ent per switchtype */
|
||||
struct sngisdn_cc ccs[MAX_VARIANTS+1];
|
||||
uint8_t num_dchan;
|
||||
sngisdn_dchan_data_t dchans[MAX_L1_LINKS+1];
|
||||
}ftdm_sngisdn_data_t;
|
||||
|
||||
typedef enum {
|
||||
FLAG_RESET_RX = (1 << 0),
|
||||
FLAG_RESET_TX = (1 << 1),
|
||||
FLAG_REMOTE_REL = (1 << 2),
|
||||
FLAG_LOCAL_REL = (1 << 3),
|
||||
FLAG_REMOTE_ABORT = (1 << 4),
|
||||
FLAG_LOCAL_ABORT = (1 << 4),
|
||||
FLAG_GLARE = (1 << 5),
|
||||
FLAG_INFID_RESUME = (1 << 17),
|
||||
FLAG_INFID_PAUSED = (1 << 18),
|
||||
FLAG_CKT_MN_BLOCK_RX = (1 << 19),
|
||||
FLAG_CKT_MN_BLOCK_TX = (1 << 20),
|
||||
FLAG_CKT_MN_UNBLK_RX = (1 << 21),
|
||||
FLAG_CKT_MN_UNBLK_TX = (1 << 22),
|
||||
FLAG_GRP_HW_BLOCK_RX = (1 << 23),
|
||||
FLAG_GRP_HW_BLOCK_TX = (1 << 24),
|
||||
FLAG_GRP_MN_BLOCK_RX = (1 << 25),
|
||||
FLAG_GRP_MN_BLOCK_TX = (1 << 28),
|
||||
FLAG_GRP_HW_UNBLK_RX = (1 << 27),
|
||||
FLAG_GRP_HW_UNBLK_TX = (1 << 28),
|
||||
FLAG_GRP_MN_UNBLK_RX = (1 << 29),
|
||||
FLAG_GRP_MN_UNBLK_TX = (1 << 30)
|
||||
FLAG_LOCAL_ABORT = (1 << 5),
|
||||
FLAG_GLARE = (1 << 6),
|
||||
FLAG_DELAYED_REL = (1 << 7),
|
||||
FLAG_SENT_PROCEED = (1 << 8),
|
||||
} sngisdn_flag_t;
|
||||
|
||||
|
||||
|
@ -182,62 +94,222 @@ typedef enum {
|
|||
SNGISDN_TRACE_Q931 = 2,
|
||||
} sngisdn_tracetype_t;
|
||||
|
||||
typedef enum {
|
||||
SNGISDN_OPT_DEFAULT = 0,
|
||||
SNGISDN_OPT_TRUE = 1,
|
||||
SNGISDN_OPT_FALSE = 2,
|
||||
} sngisdn_opt_t;
|
||||
|
||||
#define sngisdn_set_flag(obj, flag) ((obj)->flags |= (flag))
|
||||
#define sngisdn_clear_flag(obj, flag) ((obj)->flags &= ~(flag))
|
||||
#define sngisdn_test_flag(obj, flag) ((obj)->flags & flag)
|
||||
|
||||
#define sngisdn_set_trace_flag(obj, flag) ((obj)->trace_flags |= (flag))
|
||||
#define sngisdn_clear_trace_flag(obj, flag) ((obj)->trace_flags &= ~(flag))
|
||||
#define sngisdn_test_trace_flag(obj, flag) ((obj)->trace_flags & flag)
|
||||
typedef enum {
|
||||
SNGISDN_AVAIL_DOWN = 1,
|
||||
SNGISDN_AVAIL_PWR_SAVING = 5,
|
||||
SNGISDN_AVAIL_UP = 10,
|
||||
} sngisdn_avail_t;
|
||||
|
||||
typedef enum {
|
||||
SNGISDN_EVENT_CON_IND = 1,
|
||||
SNGISDN_EVENT_CON_CFM,
|
||||
SNGISDN_EVENT_CNST_IND,
|
||||
SNGISDN_EVENT_DISC_IND,
|
||||
SNGISDN_EVENT_REL_IND,
|
||||
SNGISDN_EVENT_DAT_IND,
|
||||
SNGISDN_EVENT_SSHL_IND,
|
||||
SNGISDN_EVENT_SSHL_CFM,
|
||||
SNGISDN_EVENT_RMRT_IND,
|
||||
SNGISDN_EVENT_RMRT_CFM,
|
||||
SNGISDN_EVENT_FLC_IND,
|
||||
SNGISDN_EVENT_FAC_IND,
|
||||
SNGISDN_EVENT_STA_CFM,
|
||||
SNGISDN_EVENT_SRV_IND,
|
||||
SNGISDN_EVENT_SRV_CFM,
|
||||
SNGISDN_EVENT_RST_CFM,
|
||||
SNGISDN_EVENT_RST_IND,
|
||||
} ftdm_sngisdn_event_id_t;
|
||||
|
||||
typedef struct sngisdn_glare_data {
|
||||
int16_t suId;
|
||||
uint32_t suInstId;
|
||||
uint32_t spInstId;
|
||||
int16_t dChan;
|
||||
ConEvnt setup;
|
||||
uint8_t ces;
|
||||
}sngisdn_glare_data_t;
|
||||
|
||||
|
||||
/* Channel specific data */
|
||||
typedef struct sngisdn_chan_data {
|
||||
ftdm_channel_t *ftdmchan;
|
||||
uint32_t flags;
|
||||
uint8_t ces; /* used only for BRI, otherwise always 0 */
|
||||
uint8_t dchan_id;
|
||||
uint32_t suInstId; /* instance ID generated locally */
|
||||
uint32_t spInstId; /* instance ID generated by stack */
|
||||
|
||||
uint8_t globalFlg;
|
||||
sngisdn_glare_data_t glare;
|
||||
} sngisdn_chan_data_t;
|
||||
|
||||
/* Span specific data */
|
||||
typedef struct sngisdn_span_data {
|
||||
ftdm_span_t *ftdm_span;
|
||||
uint8_t link_id;
|
||||
uint8_t switchtype;
|
||||
uint8_t signalling; /* SNGISDN_SIGNALING_CPE or SNGISDN_SIGNALING_NET */
|
||||
uint8_t cc_id;
|
||||
uint8_t dchan_id;
|
||||
uint8_t span_id;
|
||||
uint8_t tei;
|
||||
uint8_t min_digits;
|
||||
uint8_t trace_flags; /* TODO: change to flags, so we can use ftdm_test_flag etc.. */
|
||||
uint8_t overlap_dial;
|
||||
uint8_t setup_arb;
|
||||
uint8_t facility;
|
||||
ftdm_sched_t *sched;
|
||||
ftdm_queue_t *event_queue;
|
||||
} sngisdn_span_data_t;
|
||||
|
||||
typedef struct sngisdn_event_data {
|
||||
|
||||
int16_t suId;
|
||||
int16_t dChan;
|
||||
uint32_t suInstId;
|
||||
uint32_t spInstId;
|
||||
uint8_t ces;
|
||||
uint8_t action;
|
||||
uint8_t evntType;
|
||||
|
||||
sngisdn_chan_data_t *sngisdn_info;
|
||||
sngisdn_span_data_t *signal_data;
|
||||
|
||||
ftdm_sngisdn_event_id_t event_id;
|
||||
|
||||
union
|
||||
{
|
||||
ConEvnt conEvnt;
|
||||
CnStEvnt cnStEvnt;
|
||||
DiscEvnt discEvnt;
|
||||
RelEvnt relEvnt;
|
||||
InfoEvnt infoEvnt;
|
||||
SsHlEvnt ssHlEvnt;
|
||||
RmRtEvnt rmRtEvnt;
|
||||
StaEvnt staEvnt;
|
||||
FacEvnt facEvnt;
|
||||
Srv srvEvnt;
|
||||
Rst rstEvnt;
|
||||
}event;
|
||||
|
||||
} sngisdn_event_data_t;
|
||||
|
||||
/* dchan_data can have more than 1 span when running NFAS */
|
||||
typedef struct sngisdn_dchan_data {
|
||||
uint8_t num_spans;
|
||||
sngisdn_span_data_t *spans[MAX_L1_LINKS+1];
|
||||
uint16_t num_chans;
|
||||
/* worst case for number of channel is when using NFAS, and NFAS is only used on T1,
|
||||
so we can use MAX_SPANS_PER_NFAS_LINK*NUM_T1_CHANNELS_PER_SPAN instead of
|
||||
MAX_SPANS_PER_NFAS_LINK*NUM_E1_CHANNELS_PER_SPAN
|
||||
*/
|
||||
/* Never seen NFAS on E1 yet, so use NUM_T1_CHANNELS_PER_SPAN */
|
||||
/* b-channels are arranged by physical id's not logical */
|
||||
sngisdn_chan_data_t *channels[MAX_SPANS_PER_NFAS_LINK*NUM_T1_CHANNELS_PER_SPAN];
|
||||
}sngisdn_dchan_data_t;
|
||||
|
||||
typedef struct sngisdn_cc {
|
||||
/* TODO: use flags instead of config_done and activation_done */
|
||||
uint8_t config_done;
|
||||
uint8_t activation_done;
|
||||
uint8_t switchtype;
|
||||
ftdm_trunk_type_t trunktype;
|
||||
uint32_t last_suInstId;
|
||||
ftdm_mutex_t *mutex;
|
||||
sngisdn_chan_data_t *active_spInstIds[MAX_INSTID];
|
||||
sngisdn_chan_data_t *active_suInstIds[MAX_INSTID];
|
||||
}sngisdn_cc_t;
|
||||
|
||||
/* Global sngisdn data */
|
||||
typedef struct ftdm_sngisdn_data {
|
||||
uint8_t gen_config_done;
|
||||
uint8_t num_cc; /* 1 ent per switchtype */
|
||||
struct sngisdn_cc ccs[MAX_VARIANTS+1];
|
||||
uint8_t num_dchan;
|
||||
sngisdn_dchan_data_t dchans[MAX_L1_LINKS+1];
|
||||
}ftdm_sngisdn_data_t;
|
||||
|
||||
|
||||
/* TODO implement these 2 functions */
|
||||
#define ISDN_FUNC_TRACE_ENTER(a)
|
||||
#define ISDN_FUNC_TRACE_EXIT(a)
|
||||
|
||||
/* Global Structs */
|
||||
extern ftdm_sngisdn_data_t g_sngisdn_data;
|
||||
|
||||
/* Configuration functions */
|
||||
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);
|
||||
|
||||
|
||||
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 check_for_state_change(ftdm_channel_t *ftdmchan);
|
||||
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);
|
||||
void sngisdn_snd_setup_ack(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_progress(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_alert(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_connect(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_release(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare);
|
||||
void sngisdn_snd_reset(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_con_complete(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_info_req(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_status_enq(ftdm_channel_t *ftdmchan);
|
||||
|
||||
/* Inbound Call Control functions */
|
||||
void sngisdn_rcv_con_ind (signed short suId, uint32_t suInstId, uint32_t spInstId, ConEvnt *conEvnt, signed short dChan, uint8_t ces);
|
||||
void sngisdn_rcv_con_cfm (signed short suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, signed short dChan, uint8_t ces);
|
||||
void sngisdn_rcv_cnst_ind (signed short suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, uint8_t evntType, signed short dChan, uint8_t ces);
|
||||
void sngisdn_rcv_disc_ind (signed short suId, uint32_t suInstId, uint32_t spInstId, DiscEvnt *discEvnt);
|
||||
void sngisdn_rcv_rel_ind (signed short suId, uint32_t suInstId, uint32_t spInstId, RelEvnt *relEvnt);
|
||||
void sngisdn_rcv_dat_ind (signed short suId, uint32_t suInstId, uint32_t spInstId, InfoEvnt *infoEvnt);
|
||||
void sngisdn_rcv_sshl_ind (signed short suId, uint32_t suInstId, uint32_t spInstId, SsHlEvnt *ssHlEvnt, uint8_t action);
|
||||
void sngisdn_rcv_sshl_cfm (signed short suId, uint32_t suInstId, uint32_t spInstId, SsHlEvnt *ssHlEvnt, uint8_t action);
|
||||
void sngisdn_rcv_rmrt_ind (signed short suId, uint32_t suInstId, uint32_t spInstId, RmRtEvnt *rmRtEvnt, uint8_t action);
|
||||
void sngisdn_rcv_rmrt_cfm (signed short suId, uint32_t suInstId, uint32_t spInstId, RmRtEvnt *rmRtEvnt, uint8_t action);
|
||||
void sngisdn_rcv_flc_ind (signed short suId, uint32_t suInstId, uint32_t spInstId, StaEvnt *staEvnt);
|
||||
void sngisdn_rcv_fac_ind (signed short suId, uint32_t suInstId, uint32_t spInstId, FacEvnt *facEvnt, uint8_t evntType, signed short dChan, uint8_t ces);
|
||||
void sngisdn_rcv_sta_cfm ( signed short suId, uint32_t suInstId, uint32_t spInstId, StaEvnt *staEvnt);
|
||||
void sngisdn_rcv_srv_ind ( signed short suId, Srv *srvEvnt, signed short dChan, uint8_t ces);
|
||||
void sngisdn_rcv_srv_cfm ( signed short suId, Srv *srvEvnt, signed short dChan, uint8_t ces);
|
||||
void sngisdn_rcv_rst_cfm ( signed short suId, Rst *rstEvnt, signed short dChan, uint8_t ces, uint8_t evtType);
|
||||
void sngisdn_rcv_rst_ind ( signed short suId, Rst *rstEvnt, signed short dChan, uint8_t ces, uint8_t evtType);
|
||||
void sngisdn_rcv_con_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, ConEvnt *conEvnt, int16_t dChan, uint8_t ces);
|
||||
void sngisdn_rcv_con_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, int16_t dChan, uint8_t ces);
|
||||
void sngisdn_rcv_cnst_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, CnStEvnt *cnStEvnt, uint8_t evntType, int16_t dChan, uint8_t ces);
|
||||
void sngisdn_rcv_disc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, DiscEvnt *discEvnt);
|
||||
void sngisdn_rcv_rel_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, RelEvnt *relEvnt);
|
||||
void sngisdn_rcv_dat_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, InfoEvnt *infoEvnt);
|
||||
void sngisdn_rcv_sshl_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, SsHlEvnt *ssHlEvnt, uint8_t action);
|
||||
void sngisdn_rcv_sshl_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, SsHlEvnt *ssHlEvnt, uint8_t action);
|
||||
void sngisdn_rcv_rmrt_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, RmRtEvnt *rmRtEvnt, uint8_t action);
|
||||
void sngisdn_rcv_rmrt_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, RmRtEvnt *rmRtEvnt, uint8_t action);
|
||||
void sngisdn_rcv_flc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, StaEvnt *staEvnt);
|
||||
void sngisdn_rcv_fac_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, FacEvnt *facEvnt, uint8_t evntType, int16_t dChan, uint8_t ces);
|
||||
void sngisdn_rcv_sta_cfm ( int16_t suId, uint32_t suInstId, uint32_t spInstId, StaEvnt *staEvnt);
|
||||
void sngisdn_rcv_srv_ind ( int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces);
|
||||
void sngisdn_rcv_srv_cfm ( int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces);
|
||||
void sngisdn_rcv_rst_cfm ( int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces, uint8_t evntType);
|
||||
void sngisdn_rcv_rst_ind ( int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces, uint8_t evntType);
|
||||
|
||||
void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event);
|
||||
void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event);
|
||||
void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event);
|
||||
void sngisdn_process_disc_ind (sngisdn_event_data_t *sngisdn_event);
|
||||
void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event);
|
||||
void sngisdn_process_dat_ind (sngisdn_event_data_t *sngisdn_event);
|
||||
void sngisdn_process_sshl_ind (sngisdn_event_data_t *sngisdn_event);
|
||||
void sngisdn_process_sshl_cfm (sngisdn_event_data_t *sngisdn_event);
|
||||
void sngisdn_process_rmrt_ind (sngisdn_event_data_t *sngisdn_event);
|
||||
void sngisdn_process_rmrt_cfm (sngisdn_event_data_t *sngisdn_event);
|
||||
void sngisdn_process_flc_ind (sngisdn_event_data_t *sngisdn_event);
|
||||
void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event);
|
||||
void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event);
|
||||
|
||||
void sngisdn_process_srv_ind (sngisdn_event_data_t *sngisdn_event);
|
||||
void sngisdn_process_srv_cfm (sngisdn_event_data_t *sngisdn_event);
|
||||
void sngisdn_process_rst_cfm (sngisdn_event_data_t *sngisdn_event);
|
||||
void sngisdn_process_rst_ind (sngisdn_event_data_t *sngisdn_event);
|
||||
|
||||
void sngisdn_rcv_phy_ind(SuId suId, Reason reason);
|
||||
void sngisdn_rcv_q921_ind(BdMngmt *status);
|
||||
|
@ -246,14 +318,43 @@ void sngisdn_rcv_q931_ind(InMngmt *status);
|
|||
void sngisdn_rcv_q931_trace(InMngmt *trc, Buffer *mBuf);
|
||||
void sngisdn_rcv_cc_ind(CcMngmt *status);
|
||||
void sngisdn_rcv_sng_log(uint8_t level, char *fmt,...);
|
||||
void sngisdn_rcv_sng_assert(char *message);
|
||||
|
||||
uint8_t sngisdn_get_infoTranCap_from_stack(ftdm_bearer_cap_t bearer_capability);
|
||||
uint8_t sngisdn_get_usrInfoLyr1Prot_from_stack(ftdm_user_layer1_prot_t layer1_prot);
|
||||
ftdm_bearer_cap_t sngisdn_get_infoTranCap_from_user(uint8_t bearer_capability);
|
||||
ftdm_user_layer1_prot_t sngisdn_get_usrInfoLyr1Prot_from_user(uint8_t layer1_prot);
|
||||
|
||||
static __inline__ uint32_t sngisdn_test_flag(sngisdn_chan_data_t *sngisdn_info, sngisdn_flag_t flag)
|
||||
{
|
||||
return (uint32_t) sngisdn_info->flags & flag;
|
||||
}
|
||||
static __inline__ void sngisdn_clear_flag(sngisdn_chan_data_t *sngisdn_info, sngisdn_flag_t flag)
|
||||
{
|
||||
sngisdn_info->flags &= ~flag;
|
||||
}
|
||||
|
||||
static __inline__ void sngisdn_set_flag(sngisdn_chan_data_t *sngisdn_info, sngisdn_flag_t flag)
|
||||
{
|
||||
sngisdn_info->flags |= flag;
|
||||
}
|
||||
|
||||
#define sngisdn_set_trace_flag(obj, flag) ((obj)->trace_flags |= (flag))
|
||||
#define sngisdn_clear_trace_flag(obj, flag) ((obj)->trace_flags &= ~(flag))
|
||||
#define sngisdn_test_trace_flag(obj, flag) ((obj)->trace_flags & flag)
|
||||
|
||||
|
||||
void handle_sng_log(uint8_t level, char *fmt,...);
|
||||
void sngisdn_set_span_sig_status(ftdm_span_t *ftdmspan, ftdm_signaling_status_t status);
|
||||
void sngisdn_delayed_release(void* p_sngisdn_info);
|
||||
void sngisdn_delayed_connect(void* p_sngisdn_info);
|
||||
void sngisdn_delayed_disconnect(void* p_sngisdn_info);
|
||||
|
||||
/* Stack management functions */
|
||||
ftdm_status_t sng_isdn_stack_cfg(ftdm_span_t *span);
|
||||
ftdm_status_t sng_isdn_stack_activate(ftdm_span_t *span);
|
||||
|
||||
|
||||
|
||||
#endif /* __FTMOD_SNG_ISDN_H__ */
|
||||
|
||||
|
|
|
@ -47,7 +47,8 @@ ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span)
|
|||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data;
|
||||
switch(span->trunk_type) {
|
||||
case FTDM_TRUNK_T1:
|
||||
if (!strcasecmp(switch_name, "ni2")) {
|
||||
if (!strcasecmp(switch_name, "ni2") ||
|
||||
!strcasecmp(switch_name, "national")) {
|
||||
signal_data->switchtype = SNGISDN_SWITCH_NI2;
|
||||
} else if (!strcasecmp(switch_name, "5ess")) {
|
||||
signal_data->switchtype = SNGISDN_SWITCH_5ESS;
|
||||
|
@ -127,6 +128,7 @@ ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span)
|
|||
dchan_data->channels[chan_id] = (sngisdn_chan_data_t*)ftdmchan->call_data;
|
||||
dchan_data->num_chans++;
|
||||
}
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -144,7 +146,7 @@ ftdm_status_t parse_signalling(const char* signalling, ftdm_span_t *span)
|
|||
|
||||
signal_data->signalling = SNGISDN_SIGNALING_CPE;
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Unsupported signalling %s\n", signalling);
|
||||
ftdm_log(FTDM_LOG_ERROR, "Unsupported signalling/interface %s\n", signalling);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
|
@ -156,10 +158,34 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_
|
|||
const char *var, *val;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data;
|
||||
/* Set defaults here */
|
||||
signal_data->keep_link_up = 1;
|
||||
signal_data->tei = 0;
|
||||
|
||||
|
||||
signal_data->min_digits = 8;
|
||||
signal_data->overlap_dial = SNGISDN_OPT_DEFAULT;
|
||||
signal_data->setup_arb = SNGISDN_OPT_DEFAULT;
|
||||
|
||||
span->default_caller_data.bearer_capability = IN_ITC_SPEECH;
|
||||
|
||||
/* Cannot set default bearer_layer1 yet, as we do not know the switchtype */
|
||||
span->default_caller_data.bearer_layer1 = FTDM_INVALID_INT_PARM;
|
||||
|
||||
if (span->trunk_type == FTDM_TRUNK_BRI ||
|
||||
span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
|
||||
|
||||
ftdm_span_set_npi("unknown", &span->default_caller_data.dnis.plan);
|
||||
ftdm_span_set_ton("unknown", &span->default_caller_data.dnis.type);
|
||||
ftdm_span_set_npi("unknown", &span->default_caller_data.cid_num.plan);
|
||||
ftdm_span_set_ton("unknown", &span->default_caller_data.cid_num.type);
|
||||
ftdm_span_set_npi("unknown", &span->default_caller_data.rdnis.plan);
|
||||
ftdm_span_set_ton("unknown", &span->default_caller_data.rdnis.type);
|
||||
} else {
|
||||
ftdm_span_set_npi("e164", &span->default_caller_data.dnis.plan);
|
||||
ftdm_span_set_ton("national", &span->default_caller_data.dnis.type);
|
||||
ftdm_span_set_npi("e164", &span->default_caller_data.cid_num.plan);
|
||||
ftdm_span_set_ton("national", &span->default_caller_data.cid_num.type);
|
||||
ftdm_span_set_npi("e164", &span->default_caller_data.rdnis.plan);
|
||||
ftdm_span_set_ton("national", &span->default_caller_data.rdnis.type);
|
||||
}
|
||||
|
||||
for (paramindex = 0; ftdm_parameters[paramindex].var; paramindex++) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Sangoma ISDN key=value, %s=%s\n", ftdm_parameters[paramindex].var, ftdm_parameters[paramindex].val);
|
||||
var = ftdm_parameters[paramindex].var;
|
||||
|
@ -169,7 +195,8 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_
|
|||
if (parse_switchtype(val, span) != FTDM_SUCCESS) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
} else if (!strcasecmp(var, "signalling")) {
|
||||
} else if (!strcasecmp(var, "signalling") ||
|
||||
!strcasecmp(var, "interface")) {
|
||||
if (parse_signalling(val, span) != FTDM_SUCCESS) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
@ -180,15 +207,48 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_
|
|||
return FTDM_FAIL;
|
||||
}
|
||||
signal_data->tei = tei;
|
||||
} else if (!strcasecmp(var, "keep_link_up")) {
|
||||
} else if (!strcasecmp(var, "overlap")) {
|
||||
if (!strcasecmp(val, "yes")) {
|
||||
signal_data->keep_link_up = 1;
|
||||
signal_data->overlap_dial = SNGISDN_OPT_TRUE;
|
||||
} else if (!strcasecmp(val, "no")) {
|
||||
signal_data->keep_link_up = 0;
|
||||
signal_data->overlap_dial = SNGISDN_OPT_FALSE;
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Invalid keep_link_up value, valid values are (yes/no)");
|
||||
return FTDM_FAIL;
|
||||
ftdm_log(FTDM_LOG_ERROR, "Invalid value for parameter:%s:%s\n", var, val);
|
||||
}
|
||||
} else if (!strcasecmp(var, "setup arbitration")) {
|
||||
if (!strcasecmp(val, "yes")) {
|
||||
signal_data->setup_arb = SNGISDN_OPT_TRUE;
|
||||
} else if (!strcasecmp(val, "no")) {
|
||||
signal_data->setup_arb = SNGISDN_OPT_FALSE;
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Invalid value for parameter:%s:%s\n", var, val);
|
||||
}
|
||||
} else if (!strcasecmp(var, "facility")) {
|
||||
if (!strcasecmp(val, "yes")) {
|
||||
signal_data->facility = SNGISDN_OPT_TRUE;
|
||||
} else if (!strcasecmp(val, "no")) {
|
||||
signal_data->facility = SNGISDN_OPT_FALSE;
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Invalid value for parameter:%s:%s\n", var, val);
|
||||
}
|
||||
} else if (!strcasecmp(var, "min_digits")) {
|
||||
signal_data->min_digits = atoi(val);
|
||||
} else if (!strcasecmp(var, "outbound-called-ton")) {
|
||||
ftdm_span_set_ton(val, &span->default_caller_data.dnis.type);
|
||||
} else if (!strcasecmp(var, "outbound-called-npi")) {
|
||||
ftdm_span_set_npi(val, &span->default_caller_data.dnis.plan);
|
||||
} else if (!strcasecmp(var, "outbound-calling-ton")) {
|
||||
ftdm_span_set_ton(val, &span->default_caller_data.cid_num.type);
|
||||
} else if (!strcasecmp(var, "outbound-calling-npi")) {
|
||||
ftdm_span_set_npi(val, &span->default_caller_data.cid_num.plan);
|
||||
} else if (!strcasecmp(var, "outbound-rdnis-ton")) {
|
||||
ftdm_span_set_ton(val, &span->default_caller_data.rdnis.type);
|
||||
} else if (!strcasecmp(var, "outbound-rdnis-npi")) {
|
||||
ftdm_span_set_npi(val, &span->default_caller_data.rdnis.plan);
|
||||
} else if (!strcasecmp(var, "outbound-bearer_cap")) {
|
||||
ftdm_span_set_bearer_capability(val, &span->default_caller_data.bearer_capability);
|
||||
} else if (!strcasecmp(var, "outbound-bearer_layer1")) {
|
||||
ftdm_span_set_bearer_layer1(val, &span->default_caller_data.bearer_layer1);
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_WARNING, "Ignoring unknown parameter %s\n", ftdm_parameters[paramindex].var);
|
||||
}
|
||||
|
@ -202,6 +262,14 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_
|
|||
ftdm_log(FTDM_LOG_ERROR, "%s: signalling not specified", span->name);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (span->default_caller_data.bearer_layer1 == FTDM_INVALID_INT_PARM) {
|
||||
if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN) {
|
||||
span->default_caller_data.bearer_layer1 = IN_UIL1_G711ULAW;
|
||||
} else {
|
||||
span->default_caller_data.bearer_layer1 = IN_UIL1_G711ALAW;
|
||||
}
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ void sngisdn_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status
|
|||
sig.span_id = ftdmchan->span_id;
|
||||
sig.channel = ftdmchan;
|
||||
sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED;
|
||||
sig.raw_data = &status;
|
||||
sig.sigstatus = status;
|
||||
ftdm_span_send_signal(ftdmchan->span, &sig);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -223,17 +223,17 @@ ftdm_status_t sng_isdn_stack_cfg_phy_psap(ftdm_span_t *span)
|
|||
switch(span->trunk_type) {
|
||||
case FTDM_TRUNK_E1:
|
||||
cfg.t.cfg.s.l1PSAP.chan = 16;
|
||||
cfg.t.cfg.s.l1PSAP.type = SNG_LINKTYPE_PRI;
|
||||
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_LINKTYPE_PRI;
|
||||
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_LINKTYPE_BRI;
|
||||
cfg.t.cfg.s.l1PSAP.type = SNG_L1_TYPE_BRI;
|
||||
break;
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_ERROR, "%s:Unsupported trunk type %d\n", span->name, span->trunk_type);
|
||||
|
@ -280,10 +280,10 @@ ftdm_status_t sng_isdn_stack_cfg_q921_gen(void)
|
|||
cfg.t.cfg.s.bdGen.nmbASPLnks = MAX_L1_LINKS+1;
|
||||
|
||||
#ifdef LAPD_3_4
|
||||
cfg.t.cfg.s.bdGen.timeRes = 10; /* timer resolution */
|
||||
cfg.t.cfg.s.bdGen.timeRes = 100; /* timer resolution = 1 sec */
|
||||
#endif
|
||||
cfg.t.cfg.s.bdGen.poolTrUpper = POOL_UP_TR; /* upper pool threshold */
|
||||
cfg.t.cfg.s.bdGen.poolTrLower = POOL_LW_TR; /* lower pool threshold */
|
||||
cfg.t.cfg.s.bdGen.poolTrUpper = 2; /* upper pool threshold */
|
||||
cfg.t.cfg.s.bdGen.poolTrLower = 1; /* lower pool threshold */
|
||||
|
||||
if (sng_isdn_q921_config(&pst, &cfg)) {
|
||||
return FTDM_FAIL;
|
||||
|
@ -315,9 +315,9 @@ ftdm_status_t sng_isdn_stack_cfg_q921_msap(ftdm_span_t *span)
|
|||
|
||||
cfg.t.cfg.s.bdMSAP.lnkNmb = signal_data->link_id;
|
||||
|
||||
cfg.t.cfg.s.bdMSAP.maxOutsFrms = 2; /* MAC window */
|
||||
cfg.t.cfg.s.bdMSAP.tQUpperTrs = 16; /* Tx Queue Upper Threshold */
|
||||
cfg.t.cfg.s.bdMSAP.tQLowerTrs = 8; /* Tx Queue Lower Threshold */
|
||||
cfg.t.cfg.s.bdMSAP.maxOutsFrms = 24; /* MAC window */
|
||||
cfg.t.cfg.s.bdMSAP.tQUpperTrs = 32; /* Tx Queue Upper Threshold */
|
||||
cfg.t.cfg.s.bdMSAP.tQLowerTrs = 24; /* Tx Queue Lower Threshold */
|
||||
cfg.t.cfg.s.bdMSAP.selector = 0; /* Selector 0 */
|
||||
/* TODO: check if bdMSAP parameters can be initialized by calling stack_pst_init */
|
||||
cfg.t.cfg.s.bdMSAP.mem.region = S_REG; /* Memory region */
|
||||
|
@ -327,8 +327,8 @@ ftdm_status_t sng_isdn_stack_cfg_q921_msap(ftdm_span_t *span)
|
|||
cfg.t.cfg.s.bdMSAP.dstProcId = SFndProcId(); /* destination proc id */
|
||||
cfg.t.cfg.s.bdMSAP.dstEnt = ENTL1; /* entity */
|
||||
cfg.t.cfg.s.bdMSAP.dstInst = S_INST; /* instance */
|
||||
cfg.t.cfg.s.bdMSAP.t201Tmr = 5; /* T201 */
|
||||
cfg.t.cfg.s.bdMSAP.t202Tmr = 200; /* T202 */
|
||||
cfg.t.cfg.s.bdMSAP.t201Tmr = 1; /* T201 - should be equal to t200Tmr */
|
||||
cfg.t.cfg.s.bdMSAP.t202Tmr = 2; /* T202 */
|
||||
cfg.t.cfg.s.bdMSAP.bndRetryCnt = 2; /* bind retry counter */
|
||||
cfg.t.cfg.s.bdMSAP.tIntTmr = 200; /* bind retry timer */
|
||||
cfg.t.cfg.s.bdMSAP.n202 = 3; /* N202 */
|
||||
|
@ -341,7 +341,21 @@ ftdm_status_t sng_isdn_stack_cfg_q921_msap(ftdm_span_t *span)
|
|||
cfg.t.cfg.s.bdMSAP.kpL1Up = TRUE; /* flag to keep l1 up or not */
|
||||
}
|
||||
|
||||
cfg.t.cfg.s.bdMSAP.type = sng_isdn_stack_switchtype(signal_data->switchtype);
|
||||
switch(signal_data->switchtype) {
|
||||
case SNGISDN_SWITCH_NI2:
|
||||
case SNGISDN_SWITCH_5ESS:
|
||||
case SNGISDN_SWITCH_4ESS:
|
||||
case SNGISDN_SWITCH_DMS100:
|
||||
cfg.t.cfg.s.bdMSAP.type = SW_NI2;
|
||||
break;
|
||||
case SNGISDN_SWITCH_INSNET:
|
||||
cfg.t.cfg.s.bdMSAP.type = SW_CCITT;
|
||||
break;
|
||||
case SNGISDN_SWITCH_EUROISDN:
|
||||
case SNGISDN_SWITCH_QSIG:
|
||||
cfg.t.cfg.s.bdMSAP.type = SW_ETSI;
|
||||
break;
|
||||
}
|
||||
|
||||
if (span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
|
||||
cfg.t.cfg.s.bdMSAP.teiChkTmr = 20; /* Tei check timer */
|
||||
|
@ -357,6 +371,12 @@ ftdm_status_t sng_isdn_stack_cfg_q921_msap(ftdm_span_t *span)
|
|||
cfg.t.cfg.s.bdMSAP.setUpArb = ACTIVE; /* set up arbitration */
|
||||
}
|
||||
|
||||
/* Overwrite setUpArb value if user forced it */
|
||||
if (signal_data->setup_arb == SNGISDN_OPT_TRUE) {
|
||||
cfg.t.cfg.s.bdMSAP.setUpArb = ACTIVE;
|
||||
} else if (signal_data->setup_arb == SNGISDN_OPT_FALSE) {
|
||||
cfg.t.cfg.s.bdMSAP.setUpArb = PASSIVE;
|
||||
}
|
||||
|
||||
if (sng_isdn_q921_config(&pst, &cfg)) {
|
||||
return FTDM_FAIL;
|
||||
|
@ -389,11 +409,18 @@ ftdm_status_t sng_isdn_stack_cfg_q921_dlsap(ftdm_span_t *span, uint8_t managemen
|
|||
cfg.t.cfg.s.bdDLSAP.lnkNmb = signal_data->link_id;
|
||||
|
||||
cfg.t.cfg.s.bdDLSAP.n201 = 1028; /* n201 */
|
||||
cfg.t.cfg.s.bdDLSAP.k = 7; /* k */
|
||||
if (span->trunk_type == FTDM_TRUNK_BRI_PTMP ||
|
||||
span->trunk_type == FTDM_TRUNK_BRI) {
|
||||
|
||||
cfg.t.cfg.s.bdDLSAP.k = 1; /* Based on q.921 recommendations */
|
||||
} else {
|
||||
cfg.t.cfg.s.bdDLSAP.k = 7; /* k */
|
||||
}
|
||||
|
||||
cfg.t.cfg.s.bdDLSAP.n200 = 3; /* n200 */
|
||||
cfg.t.cfg.s.bdDLSAP.congTmr = 300; /* congestion timer */
|
||||
cfg.t.cfg.s.bdDLSAP.t200Tmr = 1; /* t1 changed from 25 */
|
||||
cfg.t.cfg.s.bdDLSAP.t203Tmr = 3; /* t3 changed from 50 */
|
||||
cfg.t.cfg.s.bdDLSAP.t200Tmr = 1; /* t1 changed from 25 */
|
||||
cfg.t.cfg.s.bdDLSAP.t203Tmr = 10; /* t3 changed from 50 */
|
||||
cfg.t.cfg.s.bdDLSAP.mod = 128; /* modulo */
|
||||
cfg.t.cfg.s.bdDLSAP.selector = 0; /* Selector 0 */
|
||||
cfg.t.cfg.s.bdDLSAP.mem.region = S_REG; /* Memory region */
|
||||
|
@ -483,7 +510,7 @@ ftdm_status_t sng_isdn_stack_cfg_q931_gen(void)
|
|||
/* upper pool threshold */
|
||||
cfg.t.cfg.s.inGen.poolTrUpper = INGEN_POOL_UP_TR;
|
||||
/* time resolution */
|
||||
cfg.t.cfg.s.inGen.timeRes = 10;
|
||||
cfg.t.cfg.s.inGen.timeRes = 100; /* timer resolution = 1 sec */
|
||||
|
||||
cfg.t.cfg.s.inGen.sm.dstEnt = ENTSM;
|
||||
|
||||
|
@ -594,6 +621,12 @@ ftdm_status_t sng_isdn_stack_cfg_q931_dlsap(ftdm_span_t *span)
|
|||
|
||||
cfg.t.cfg.s.inDLSAP.tCbId = signal_data->cc_id;
|
||||
|
||||
if (signal_data->facility == SNGISDN_OPT_TRUE) {
|
||||
cfg.t.cfg.s.inDLSAP.facilityHandling = IN_FACILITY_STANDRD;
|
||||
} else {
|
||||
cfg.t.cfg.s.inDLSAP.facilityHandling = 0;
|
||||
}
|
||||
|
||||
/* TODO : NFAS configuration */
|
||||
cfg.t.cfg.s.inDLSAP.nfasInt = FALSE; /* pass this later */
|
||||
|
||||
|
@ -687,38 +720,46 @@ ftdm_status_t sng_isdn_stack_cfg_q931_dlsap(ftdm_span_t *span)
|
|||
cfg.t.cfg.s.inDLSAP.cndSubsc = TRUE; /* calling adddress delivery service subscription */
|
||||
|
||||
/* TODO: Fill in these timers with proper values - eventually pass them */
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t301.enb = FALSE;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t301.val = 35;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t302.enb = FALSE;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t302.val = 35;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t303.enb = FALSE;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t303.val = 35;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t301.enb = TRUE;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t301.val = 180;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t302.enb = TRUE;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t302.val = 15;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t303.enb = TRUE;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t303.val = 4;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t304.enb = TRUE;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t304.val = 35;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t304.val = 30;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t305.enb = TRUE;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t305.val = 35;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t305.val = 30;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t306.enb = FALSE;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t306.val = 35;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t307.enb = FALSE;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t307.val = 35;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t308.enb = TRUE;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t308.val = 35;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t310.enb = FALSE;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t310.val = 35;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t312.enb = FALSE;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t312.val = 35;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t308.val = 4;
|
||||
|
||||
if (signal_data->signalling == SNGISDN_SIGNALING_NET) {
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t310.enb = TRUE;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t310.val = 10;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t312.enb = TRUE;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t312.val = cfg.t.cfg.s.inDLSAP.tmr.t303.val+2;
|
||||
} else {
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t310.enb = TRUE;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t310.val = 120;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t312.enb = FALSE;
|
||||
}
|
||||
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t313.enb = TRUE;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t313.val = 35;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t313.val = 4;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t316.enb = TRUE;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t316.val = 35;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t316c.enb = TRUE;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t316.val = 120;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t316c.enb = FALSE;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t316c.val = 35;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t318.enb = FALSE;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t318.val = 35;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t319.enb = FALSE;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t319.val = 35;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t318.enb = TRUE;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t318.val = 4;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t319.enb = TRUE;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t319.val = 4;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t322.enb = TRUE;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t322.val = 35;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t322.val = 4;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t332.enb = FALSE;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t332.val = 35;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.tRst.enb = TRUE;
|
||||
|
@ -893,8 +934,9 @@ ftdm_status_t sng_isdn_stack_cfg_cc_gen(void)
|
|||
stack_pst_init(&cfg.t.cfg.s.ccGenCfg.smPst);
|
||||
cfg.t.cfg.s.ccGenCfg.smPst.dstEnt = ENTSM;
|
||||
|
||||
cfg.t.cfg.s.ccGenCfg.poolTrLower = 2;
|
||||
cfg.t.cfg.s.ccGenCfg.poolTrUpper = 4;
|
||||
cfg.t.cfg.s.ccGenCfg.poolTrUpper = 2;
|
||||
cfg.t.cfg.s.ccGenCfg.poolTrLower = 1;
|
||||
|
||||
cfg.t.cfg.s.ccGenCfg.nmbSaps = MAX_VARIANTS+1; /* Set to number of variants + 1 */
|
||||
|
||||
if (sng_isdn_cc_config(&pst, &cfg)) {
|
||||
|
@ -1013,7 +1055,7 @@ uint8_t sng_isdn_stack_switchtype(sngisdn_switchtype_t switchtype)
|
|||
case SNGISDN_SWITCH_QSIG:
|
||||
return SW_QSIG;
|
||||
case SNGISDN_SWITCH_INSNET:
|
||||
return SW_QSIG;
|
||||
return SW_INSNET;
|
||||
case SNGISDN_SWITCH_INVALID:
|
||||
ftdm_log(FTDM_LOG_ERROR, "%s:Invalid switchtype:%d\n", switchtype);
|
||||
break;
|
||||
|
|
|
@ -46,8 +46,11 @@ ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t tra
|
|||
ftdm_status_t sng_isdn_cntrl_q931(ftdm_span_t *span, uint8_t action, uint8_t subaction);
|
||||
ftdm_status_t sng_isdn_cntrl_q921(ftdm_span_t *span, uint8_t action, uint8_t subaction);
|
||||
|
||||
|
||||
extern ftdm_sngisdn_data_t g_sngisdn_data;
|
||||
|
||||
ftdm_status_t sng_isdn_stack_stop(ftdm_span_t *span);
|
||||
|
||||
|
||||
ftdm_status_t sng_isdn_stack_activate(ftdm_span_t *span)
|
||||
{
|
||||
|
@ -77,6 +80,12 @@ ftdm_status_t sng_isdn_stack_activate(ftdm_span_t *span)
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t sng_isdn_stack_stop(ftdm_span_t *span)
|
||||
{
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
ftdm_status_t sng_isdn_activate_phy(ftdm_span_t *span)
|
||||
{
|
||||
|
@ -302,6 +311,7 @@ void stack_resp_hdr_init(Header *hdr)
|
|||
}
|
||||
|
||||
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
|
|
|
@ -0,0 +1,942 @@
|
|||
/*
|
||||
* Copyright (c) 2010, Sangoma Technologies
|
||||
* David Yat Sin <dyatsin@sangoma.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "ftmod_sangoma_isdn.h"
|
||||
|
||||
extern ftdm_status_t cpy_calling_num_from_stack(ftdm_caller_data_t *ftdm, CgPtyNmb *cgPtyNmb);
|
||||
extern ftdm_status_t cpy_called_num_from_stack(ftdm_caller_data_t *ftdm, CdPtyNmb *cdPtyNmb);
|
||||
extern ftdm_status_t cpy_redir_num_from_stack(ftdm_caller_data_t *ftdm, RedirNmb *redirNmb);
|
||||
extern ftdm_status_t cpy_calling_name_from_stack(ftdm_caller_data_t *ftdm, Display *display);
|
||||
|
||||
/* Remote side transmit a SETUP */
|
||||
void sngisdn_process_con_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;
|
||||
int16_t dChan = sngisdn_event->dChan;
|
||||
uint8_t ces = sngisdn_event->ces;
|
||||
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
|
||||
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
ConEvnt *conEvnt = &sngisdn_event->event.conEvnt;
|
||||
|
||||
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) ||
|
||||
ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) {
|
||||
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Received SETUP but channel is in USE, saving call for later processing\n");
|
||||
/* the flag the channel as having a collision */
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_GLARE);
|
||||
|
||||
/* save the SETUP for processing once the channel has gone to DOWN */
|
||||
memcpy(&sngisdn_info->glare.setup, conEvnt, sizeof(*conEvnt));
|
||||
sngisdn_info->glare.suId = suId;
|
||||
sngisdn_info->glare.suInstId = suInstId; /* Do not generate a suInstId now, we will generate when glared call gets extracted */
|
||||
sngisdn_info->glare.spInstId = spInstId;
|
||||
sngisdn_info->glare.dChan = dChan;
|
||||
sngisdn_info->glare.ces = ces;
|
||||
break;
|
||||
}
|
||||
|
||||
sngisdn_info->suInstId = get_unique_suInstId(suId);
|
||||
sngisdn_info->spInstId = spInstId;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex);
|
||||
g_sngisdn_data.ccs[suId].active_suInstIds[sngisdn_info->suInstId] = sngisdn_info;
|
||||
ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex);
|
||||
|
||||
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");
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_REL);
|
||||
ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_TEMPORARY_FAILURE;
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
|
||||
break;
|
||||
}
|
||||
/* 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);
|
||||
|
||||
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 (conEvnt->facilityStr.eh.pres) {
|
||||
/* Verify whether the Caller Name will come in a subsequent FACILITY message */
|
||||
uint16_t ret_val;
|
||||
uint8_t facility_str[255];
|
||||
char retrieved_str[255];
|
||||
memcpy(facility_str, (uint8_t*)&conEvnt->facilityStr.facilityStr.val, conEvnt->facilityStr.facilityStr.len);
|
||||
|
||||
ret_val = sng_isdn_retrieve_facility_caller_name(facility_str, conEvnt->facilityStr.facilityStr.len, retrieved_str);
|
||||
/*
|
||||
return values for "sng_isdn_retrieve_facility_information_following":
|
||||
If there will be no information following, or fails to decode IE, returns -1
|
||||
If there will be no information following, but current FACILITY IE contains a caller name, returns 0
|
||||
If there will be information following, returns 1
|
||||
*/
|
||||
|
||||
if (ret_val == 1) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Expecting Caller name in FACILITY\n");
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_GET_CALLERID);
|
||||
break;
|
||||
} else if (ret_val == 0) {
|
||||
strcpy(ftdmchan->caller_data.cid_name, retrieved_str);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (signal_data->overlap_dial == SNGISDN_OPT_TRUE && !conEvnt->sndCmplt.eh.pres) {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_COLLECT);
|
||||
} else {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING);
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_TERMINATING:
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Processing SETUP in TERMINATING state, saving SETUP info for later processing\n");
|
||||
ftdm_assert(!sngisdn_test_flag(sngisdn_info, FLAG_GLARE), "Trying to save GLARE info, but we already had a glare\n");
|
||||
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_GLARE);
|
||||
|
||||
/* save the SETUP for processing once the channel has gone to DOWN */
|
||||
memcpy(&sngisdn_info->glare.setup, conEvnt, sizeof(*conEvnt));
|
||||
sngisdn_info->glare.suId = suId;
|
||||
sngisdn_info->glare.suInstId = suInstId; /* Do not generate a suInstId now, we will generate when glared call gets extracted */
|
||||
sngisdn_info->glare.spInstId = spInstId;
|
||||
sngisdn_info->glare.dChan = dChan;
|
||||
sngisdn_info->glare.ces = ces;
|
||||
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_DIALING: /* glare */
|
||||
if (signal_data->signalling == SNGISDN_SIGNALING_NET) {
|
||||
/* Save inbound call info so we can send a RELEASE when this channel goes to a different state */
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Processing SETUP in DIALING state, rejecting inbound call\n");
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_DELAYED_REL);
|
||||
|
||||
sngisdn_info->glare.suId = suId;
|
||||
sngisdn_info->glare.suInstId = get_unique_suInstId(suId);
|
||||
sngisdn_info->glare.spInstId = spInstId;
|
||||
|
||||
sngisdn_info->glare.dChan = dChan;
|
||||
sngisdn_info->glare.ces = ces;
|
||||
ftdmchan->caller_data.hangup_cause = 0x2C; /* Channel requested not available */
|
||||
ftdm_sched_timer(signal_data->sched, "delayed_release", 1, sngisdn_delayed_release, (void*) sngisdn_info, NULL);
|
||||
} else {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Processing SETUP in DIALING state, saving SETUP info for later processing\n");
|
||||
|
||||
/* the flag the channel as having a collision */
|
||||
ftdm_assert(!sngisdn_test_flag(sngisdn_info, FLAG_GLARE), "Trying to save GLARE info, but we already had a glare");
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_GLARE);
|
||||
|
||||
/* save the SETUP for processing once the channel has gone to DOWN */
|
||||
memcpy(&sngisdn_info->glare.setup, conEvnt, sizeof(*conEvnt));
|
||||
sngisdn_info->glare.suId = suId;
|
||||
sngisdn_info->glare.suInstId = suInstId; /* Do not generate a suInstId now, we will generate when glared call gets extracted */
|
||||
sngisdn_info->glare.spInstId = spInstId;
|
||||
sngisdn_info->glare.dChan = dChan;
|
||||
sngisdn_info->glare.ces = ces;
|
||||
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing SETUP in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
break;
|
||||
}
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
uint8_t ces = sngisdn_event->ces;
|
||||
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
|
||||
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
|
||||
|
||||
/* Function does not require any info from conStEvnt struct for now */
|
||||
/* CnStEvnt *cnStEvnt = &sngisdn_event->event.cnStEvnt; */
|
||||
|
||||
ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n");
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing CONNECT/CONNECT ACK (suId:%u suInstId:%u spInstId:%u ces:%d)\n", suId, suInstId, spInstId, ces);
|
||||
|
||||
if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP &&
|
||||
((sngisdn_span_data_t*)ftdmchan->span->signal_data)->signalling == SNGISDN_SIGNALING_NET) {
|
||||
|
||||
if(sngisdn_info->ces == CES_MNGMNT) {
|
||||
/* We assign the call to the first TE */
|
||||
sngisdn_info->ces = ces;
|
||||
} else {
|
||||
/* We already assigned this call, do nothing */
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Call already assigned, ignoring connect\n");
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
||||
switch(ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
case FTDM_CHANNEL_STATE_DIALING:
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_UP);
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing CONNECT/CONNECT ACK in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
|
||||
/* Start the disconnect procedure */
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch(ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
/* This is the only valid state we should get a CONNECT ACK on */
|
||||
/* do nothing */
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing CONNECT/CONNECT ACK in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
|
||||
/* Start the disconnect procedure */
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
uint8_t ces = sngisdn_event->ces;
|
||||
uint8_t evntType = sngisdn_event->evntType;
|
||||
|
||||
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
|
||||
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
|
||||
|
||||
CnStEvnt *cnStEvnt = &sngisdn_event->event.cnStEvnt;
|
||||
|
||||
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",
|
||||
(evntType == MI_ALERTING)?"ALERT":
|
||||
(evntType == MI_CALLPROC)?"PROCEED":
|
||||
(evntType == MI_PROGRESS)?"PROGRESS":
|
||||
(evntType == MI_SETUPACK)?"SETUP ACK":
|
||||
(evntType == MI_INFO)?"INFO":"UNKNOWN",
|
||||
suId, suInstId, spInstId, ces);
|
||||
|
||||
switch(evntType) {
|
||||
case MI_ALERTING:
|
||||
case MI_CALLPROC:
|
||||
case MI_PROGRESS:
|
||||
switch(ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_DIALING:
|
||||
if (evntType == MI_PROGRESS) {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
|
||||
} else {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
if (evntType == MI_PROGRESS) {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
/* We are already in progress media, we can't go to any higher state except up */
|
||||
/* Do nothing */
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing ALERT/PROCEED/PROGRESS in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
|
||||
/* Start the disconnect procedure */
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case MI_SETUPACK:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Processing SETUP_ACK, but overlap sending not implemented (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
|
||||
break;
|
||||
case MI_INFO:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing INFO (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
|
||||
|
||||
if (cnStEvnt->cdPtyNmb.eh.pres) {
|
||||
switch(ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_COLLECT:
|
||||
{
|
||||
ftdm_size_t min_digits = ((sngisdn_span_data_t*)ftdmchan->span->signal_data)->min_digits;
|
||||
ftdm_size_t num_digits;
|
||||
|
||||
cpy_called_num_from_stack(&ftdmchan->caller_data, &cnStEvnt->cdPtyNmb);
|
||||
num_digits = strlen(ftdmchan->caller_data.dnis.digits);
|
||||
|
||||
if (cnStEvnt->sndCmplt.eh.pres || num_digits >= min_digits) {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING);
|
||||
} else {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "received %d of %d digits\n", num_digits, min_digits);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_RING:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Receiving more digits %s, but we already proceeded with call\n", cnStEvnt->cdPtyNmb.nmbDigits.val);
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "\n", suId, suInstId, spInstId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Unhandled STATUS event\n");
|
||||
break;
|
||||
}
|
||||
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
|
||||
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
|
||||
|
||||
DiscEvnt *discEvnt = &sngisdn_event->event.discEvnt;
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing DISCONNECT (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
|
||||
|
||||
ftdm_assert(!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE), "State change flag pending\n");
|
||||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_RING:
|
||||
case FTDM_CHANNEL_STATE_DIALING:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
if (discEvnt->causeDgn[0].eh.pres && discEvnt->causeDgn[0].causeVal.pres) {
|
||||
ftdmchan->caller_data.hangup_cause = discEvnt->causeDgn[0].causeVal.val;
|
||||
} else {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "DISCONNECT did not have a cause code\n");
|
||||
ftdmchan->caller_data.hangup_cause = 0;
|
||||
}
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_REMOTE_REL);
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_COLLECT:
|
||||
case FTDM_CHANNEL_STATE_GET_CALLERID:
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_DOWN:
|
||||
/* somehow we are in down, nothing we can do locally */
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Received DISCONNECT but we are in DOWN state\n");
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
|
||||
/* This is a race condition. We just sent a DISCONNECT, on this channel */
|
||||
/* Do nothing */
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received DISCONNECT in an invalid state (%s)\n",
|
||||
ftdm_channel_state2str(ftdmchan->state));
|
||||
/* start reset procedure */
|
||||
|
||||
/* Start the release procedure */
|
||||
ftdm_set_flag(sngisdn_info, FLAG_REMOTE_REL);
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
break;
|
||||
}
|
||||
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
|
||||
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
|
||||
|
||||
RelEvnt *relEvnt = &sngisdn_event->event.relEvnt;
|
||||
|
||||
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");
|
||||
|
||||
if ((suInstId && (sngisdn_info->glare.suInstId == suInstId)) ||
|
||||
(spInstId && (sngisdn_info->glare.spInstId == spInstId))) {
|
||||
|
||||
/* This hangup is for a glared saved call */
|
||||
ftdm_clear_flag(sngisdn_info, FLAG_DELAYED_REL);
|
||||
clear_call_glare_data(sngisdn_info);
|
||||
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
/* check whether the ftdm channel is in a state to accept a call */
|
||||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
|
||||
/* go to DOWN */
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_DOWN:
|
||||
/* do nothing, just drop the message */
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_DIALING:
|
||||
/* Remote side rejected our SETUP message on outbound call */
|
||||
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) {
|
||||
sng_isdn_set_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN);
|
||||
}
|
||||
/* fall-through */
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
case FTDM_CHANNEL_STATE_RING:
|
||||
/* If we previously had a glare on this channel,
|
||||
this RELEASE could be for the previous call. Confirm whether call_data has
|
||||
not changed while we were waiting for ftdmchan->mutex by comparing suInstId's */
|
||||
if (((sngisdn_chan_data_t*)ftdmchan->call_data)->suInstId == suInstId ||
|
||||
((sngisdn_chan_data_t*)ftdmchan->call_data)->spInstId == spInstId) {
|
||||
if (relEvnt->causeDgn[0].eh.pres && relEvnt->causeDgn[0].causeVal.pres) {
|
||||
ftdmchan->caller_data.hangup_cause = relEvnt->causeDgn[0].causeVal.val;
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "cause:%d\n", ftdmchan->caller_data.hangup_cause);
|
||||
} else {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "RELEASE COMPLETE did not have a cause code\n");
|
||||
ftdmchan->caller_data.hangup_cause = 0;
|
||||
}
|
||||
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_REMOTE_ABORT);
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
|
||||
} else {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "RELEASE was for previous call (suInstId:%u spInstId:%u)\n", suInstId, spInstId);
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_COLLECT:
|
||||
case FTDM_CHANNEL_STATE_GET_CALLERID:
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_TERMINATING:
|
||||
if (sngisdn_test_flag(sngisdn_info, FLAG_GLARE) &&
|
||||
sngisdn_info->glare.suInstId != suInstId) {
|
||||
/* This release if for the outbound call that we already started clearing */
|
||||
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Received RELEASE for local glared call\n");
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_REMOTE_ABORT);
|
||||
} else {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Received release before we could clear local call\n");
|
||||
/* FS core took too long to respond to the SIG STOP event */
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_REMOTE_ABORT);
|
||||
/* set abort flag so that we do not transmit another release complete on this channel once FS core is done */
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received RELEASE in an invalid state (%s)\n",
|
||||
ftdm_channel_state2str(ftdmchan->state));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
|
||||
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
|
||||
|
||||
/* Function does not require any info from infoEvnt struct for now */
|
||||
/* InfoEvnt *infoEvnt = &sngisdn_event->event.infoEvnt; */
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing DATA IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
|
||||
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
|
||||
|
||||
/* Function does not require any info from ssHlEvnt struct for now */
|
||||
/* SsHlEvnt *ssHlEvnt = &sngisdn_event->event.ssHlEvnt; */
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing SSHL IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
/* Function does not require any info from ssHlEvnt struct for now */
|
||||
/* SsHlEvnt *ssHlEvnt = &sngisdn_event->event.ssHlEvnt; */
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing SSHL CFM (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
|
||||
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
|
||||
|
||||
/* Function does not require any info from ssHlEvnt struct for now */
|
||||
/* RmRtEvnt *rmRtEvnt = &sngisdn_event->event.rmRtEvnt; */
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing RESUME/RETRIEVE IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
|
||||
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
|
||||
|
||||
/* Function does not require any info from ssHlEvnt struct for now */
|
||||
/* RmRtEvnt *rmRtEvnt = &sngisdn_event->event.rmRtEvnt; */
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing RESUME/RETRIEVE CFM (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
|
||||
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
|
||||
|
||||
/* Function does not require any info from ssHlEvnt struct for now */
|
||||
/* StaEvnt *staEvnt = &sngisdn_event->event.staEvnt; */
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing FLOW CONTROL IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
|
||||
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
|
||||
|
||||
FacEvnt *facEvnt = &sngisdn_event->event.facEvnt;
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing FACILITY IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
|
||||
|
||||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_GET_CALLERID:
|
||||
/* Update the caller ID Name */
|
||||
if (facEvnt->facElmt.facStr.pres) {
|
||||
uint8_t facility_str[255];
|
||||
memcpy(facility_str, (uint8_t*)&facEvnt->facElmt.facStr.val, facEvnt->facElmt.facStr.len);
|
||||
char retrieved_str[255];
|
||||
if (sng_isdn_retrieve_facility_caller_name(facility_str, facEvnt->facElmt.facStr.len, retrieved_str) != FTDM_SUCCESS) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Failed to retrieve Caller Name from Facility IE\n");
|
||||
}
|
||||
}
|
||||
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING);
|
||||
break;
|
||||
default:
|
||||
/* We do not support other FACILITY types for now, so do nothing */
|
||||
break;
|
||||
}
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info;
|
||||
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
|
||||
|
||||
StaEvnt *staEvnt = &sngisdn_event->event.staEvnt;
|
||||
|
||||
uint8_t call_state = 0;
|
||||
|
||||
if (staEvnt->callSte.eh.pres && staEvnt->callSte.callGlblSte.pres) {
|
||||
call_state = staEvnt->callSte.callGlblSte.val;
|
||||
}
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Processing STATUS CONFIRM (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");
|
||||
|
||||
if (staEvnt->causeDgn[0].eh.pres && staEvnt->causeDgn[0].causeVal.pres) {
|
||||
if (staEvnt->callSte.eh.pres && staEvnt->callSte.callGlblSte.pres) {
|
||||
call_state = staEvnt->callSte.callGlblSte.val;
|
||||
} else {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Received STATUS without call state\n");
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
switch (staEvnt->causeDgn[0].causeVal.val) {
|
||||
case FTDM_CAUSE_RESPONSE_TO_STATUS_ENQUIRY:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Status Check OK:%d", call_state);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
case FTDM_CAUSE_WRONG_CALL_STATE:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Message incompatible with call state (call_state:%d channel-state:%s cause:%d) (suId:%u suInstId:%u spInstId:%u)\n", call_state, ftdm_channel_state2str(ftdmchan->state), staEvnt->causeDgn[0].causeVal.val, suId, suInstId, spInstId);
|
||||
break;
|
||||
case FTDM_CAUSE_RECOVERY_ON_TIMER_EXPIRE:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Recovery on timer expire (call_state:%d channel-state:%s cause:%d) (suId:%u suInstId:%u spInstId:%u)\n", call_state, ftdm_channel_state2str(ftdmchan->state), staEvnt->causeDgn[0].causeVal.val, suId, suInstId, spInstId);
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "STATUS CONFIRM (call_state:%d channel-state:%s cause:%d) (suId:%u suInstId:%u spInstId:%u)\n", call_state, ftdm_channel_state2str(ftdmchan->state), staEvnt->causeDgn[0].causeVal.val, suId, suInstId, spInstId);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Section 4.3.30 from INT Interface - Service Definition */
|
||||
ftdmchan->caller_data.hangup_cause = staEvnt->causeDgn[0].causeVal.val;
|
||||
|
||||
switch(call_state) {
|
||||
/* Sere ITU-T Q931 for definition of call states */
|
||||
case 0: /* Remote switch thinks there are no calls on this channel */
|
||||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_COLLECT:
|
||||
case FTDM_CHANNEL_STATE_DIALING:
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_REMOTE_ABORT);
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_TERMINATING:
|
||||
/* We are in the process of clearing local states,
|
||||
just make sure we will not send any messages to remote switch */
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_REMOTE_ABORT);
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_HANGUP:
|
||||
/* This cannot happen, state_advance always sets
|
||||
ftdmchan to STATE_HANGUP_COMPLETE when in STATE_HANGUP
|
||||
and we called check_for_state_change earlier so something is very wrong here!!! */
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "How can we we in FTDM_CHANNEL_STATE_HANGUP after checking for state change?\n");
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
|
||||
/* We were waiting for remote switch to send RELEASE COMPLETE
|
||||
but this will not happen, so just clear local state */
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_DOWN:
|
||||
/* If our local state is down as well, then there is nothing to do */
|
||||
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 1:
|
||||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
/* Remote side is still waiting for our CONNECT message */
|
||||
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
||||
ftdm_sched_timer(((sngisdn_span_data_t*)ftdmchan->span->signal_data)->sched, "delayed_connect", 1, sngisdn_delayed_connect, (void*) sngisdn_info, NULL);
|
||||
break;
|
||||
}
|
||||
/* Fall-through */
|
||||
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 2: /* overlap sending/receiving */
|
||||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_COLLECT:
|
||||
/* T302 Timeout reached */
|
||||
/* Send the call to user, and see if they accept it */
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "T302 Timer expired, proceeding with call\n");
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RING);
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Remote switch expecting OVERLAP receive, but we are already PROCEEDING\n");
|
||||
sngisdn_snd_disconnect(ftdmchan);
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_DOWN:
|
||||
case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
|
||||
/* We hung up locally, but remote switch doesn't know send disconnect again*/
|
||||
sngisdn_snd_disconnect(ftdmchan);
|
||||
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 3:
|
||||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
/* Remote side is still waiting for our CONNECT message */
|
||||
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
||||
ftdm_sched_timer(((sngisdn_span_data_t*)ftdmchan->span->signal_data)->sched, "delayed_connect", 1, sngisdn_delayed_connect, (void*) sngisdn_info, NULL);
|
||||
break;
|
||||
}
|
||||
/* Fall-through */
|
||||
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 8: /* Remote switch is in "Connect Request state" */
|
||||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
/* This is ok. We sent a Connect, and we are waiting for a connect ack */
|
||||
/* Do nothing */
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
|
||||
/* We hung up locally, but remote switch doesn't know send disconnect again*/
|
||||
sngisdn_snd_disconnect(ftdmchan);
|
||||
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 10: /* Remote switch is in active state */
|
||||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
/* This is ok, they are in active state and we are in active state */
|
||||
/* Do nothing */
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
|
||||
/* We sent a disconnect message, but remote side missed it ? */
|
||||
ftdm_sched_timer(((sngisdn_span_data_t*)ftdmchan->span->signal_data)->sched, "delayed_disconnect", 1, sngisdn_delayed_disconnect, (void*) sngisdn_info, NULL);
|
||||
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 9:
|
||||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
/* 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:
|
||||
/* Stack is in the process of clearing the call*/
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
|
||||
/* Do nothing as we will get a RELEASE COMPLETE */
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
/* Function does not require any info from ssHlEvnt struct for now */
|
||||
/*Srv *srvEvnt = &sngisdn_event->event.srvEvnt;*/
|
||||
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Processing SERVICE IND (suId:%u dChan:%d ces:%d)\n", suId, dChan, ces);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
/* Function does not require any info from ssHlEvnt struct for now */
|
||||
/*Srv *srvEvnt = &sngisdn_event->event.srvEvnt;*/
|
||||
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Processing SERVICE CFM (suId:%u dChan:%d ces:%d)\n", suId, dChan, ces);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
/* Function does not require any info from ssHlEvnt struct for now */
|
||||
/*Rst *rstEvnt = &sngisdn_event->event.rstEvnt;*/
|
||||
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Processing RESTART CFM (suId:%u dChan:%d ces:%d type:%d)\n", suId, dChan, ces, evntType);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
/* Function does not require any info from ssHlEvnt struct for now */
|
||||
/*Rst *rstEvnt = &sngisdn_event->event.rstEvnt;*/
|
||||
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Processing RESTART CFM (suId:%u dChan:%d ces:%d %s)\n", suId, dChan, ces,
|
||||
(evntType == IN_LNK_DWN)?"LNK_DOWN":
|
||||
(evntType == IN_LNK_UP)?"LNK_UP":
|
||||
(evntType == IN_INDCHAN)?"b-channel":
|
||||
(evntType == IN_LNK_DWN_DM_RLS)?"Nfas service procedures":
|
||||
(evntType == IN_SWCHD_BU_DCHAN)?"NFAS switchover to backup":"Unknown");
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
|
@ -1,935 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2010, Sangoma Technologies
|
||||
* David Yat Sin <davidy@sangoma.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "ftmod_sangoma_isdn.h"
|
||||
|
||||
extern ftdm_status_t cpy_calling_num_from_sngisdn(ftdm_caller_data_t *ftdm, CgPtyNmb *cgPtyNmb);
|
||||
extern ftdm_status_t cpy_called_num_from_sngisdn(ftdm_caller_data_t *ftdm, CdPtyNmb *cdPtyNmb);
|
||||
extern ftdm_status_t cpy_called_name_from_sngisdn(ftdm_caller_data_t *ftdm, CgPtyNmb *cgPtyNmb);
|
||||
extern ftdm_status_t cpy_calling_name_from_sngisdn(ftdm_caller_data_t *ftdm, ConEvnt *conEvnt);
|
||||
extern void sngisdn_trace_q921(char* str, uint8_t* data, uint32_t data_len);
|
||||
extern void sngisdn_trace_q931(char* str, uint8_t* data, uint32_t data_len);
|
||||
extern void get_memory_info(void);
|
||||
|
||||
extern ftdm_sngisdn_data_t g_sngisdn_data;
|
||||
|
||||
#define MAX_DECODE_STR_LEN 2000
|
||||
|
||||
/* Remote side transmit a SETUP */
|
||||
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;
|
||||
ftdm_channel_t *ftdmchan;
|
||||
/*sngisdn_span_data_t *span_info;*/
|
||||
|
||||
ftdm_log(FTDM_LOG_DEBUG, "%s suId:%d suInstId:%d spInstId:%d dChan:%d ces:%d\n", __FUNCTION__, suId, suInstId, spInstId, dChan, ces);
|
||||
|
||||
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");
|
||||
ftdm_assert(g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] == NULL, "Con Ind on busy spInstId");
|
||||
|
||||
if (conEvnt->chanId.eh.pres != PRSNT_NODEF) {
|
||||
/* TODO: Implement me */
|
||||
ftdm_log(FTDM_LOG_ERROR, "Incoming call without Channel Id not supported yet\n");
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (conEvnt->chanId.chanNmbSlotMap.pres) {
|
||||
bchan_no = conEvnt->chanId.chanNmbSlotMap.val[0];
|
||||
} else if (conEvnt->chanId.infoChanSel.pres) {
|
||||
bchan_no = conEvnt->chanId.infoChanSel.val;
|
||||
}
|
||||
|
||||
if (!bchan_no) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Failed to obtain b-channel number from SETUP message\n");
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_sngisdn_data.dchans[dChan].channels[bchan_no] == NULL) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Incoming call on unconfigured b-channel:%d\n", bchan_no);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
sngisdn_info = g_sngisdn_data.dchans[dChan].channels[bchan_no];
|
||||
ftdmchan = sngisdn_info->ftdmchan;
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
|
||||
/* check if there is a pending state change, give it a bit to clear */
|
||||
if (check_for_state_change(ftdmchan) != FTDM_SUCCESS) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Failed to wait for pending state change\n");
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Received SETUP\n");
|
||||
switch (ftdmchan->state){
|
||||
case FTDM_CHANNEL_STATE_DOWN: /* Proper state to receive a SETUP */
|
||||
sngisdn_info->suInstId = get_unique_suInstId(suId);
|
||||
sngisdn_info->spInstId = spInstId;
|
||||
g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] = sngisdn_info;
|
||||
g_sngisdn_data.ccs[suId].active_suInstIds[sngisdn_info->suInstId] = sngisdn_info;
|
||||
|
||||
/* 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");
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_REL);
|
||||
ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NORMAL_TEMPORARY_FAILURE;
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_CANCEL);
|
||||
} else {
|
||||
/* Fill in call information */
|
||||
cpy_calling_num_from_sngisdn(&ftdmchan->caller_data, &conEvnt->cgPtyNmb);
|
||||
cpy_called_num_from_sngisdn(&ftdmchan->caller_data, &conEvnt->cdPtyNmb);
|
||||
cpy_calling_name_from_sngisdn(&ftdmchan->caller_data, conEvnt);
|
||||
|
||||
/* Get ani2 */
|
||||
#if 0
|
||||
/* TODO: confirm that this works in the field */
|
||||
if (conEvnt->niOperSysAcc.eh.pres) {
|
||||
if (conEvnt->niOperSysAcc.typeAcc.pres) {
|
||||
ftdmchan->caller_data.aniII = (uint8_t)conEvnt->niOperSysAcc.typeAcc.val;
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Received ANI: type of access:%x", conEvnt->niOperSysAcc.typeAcc.val);
|
||||
}
|
||||
if (conEvnt->niOperSysAcc.typeServ.pres) {
|
||||
ftdmchan->caller_data.aniII = (uint8_t)conEvnt->niOperSysAcc.typeServ.val;
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Received ANI: type of service:%x", conEvnt->niOperSysAcc.typeServ.val);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 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);
|
||||
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_DIALING: /* glare */
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Received SETUP in DIALING state, glare, queueing incoming call\n");
|
||||
/* the flag the channel as having a collision */
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_GLARE);
|
||||
|
||||
/* save the SETUP for processing once the channel has gone to DOWN */
|
||||
memcpy(&sngisdn_info->glare.setup, conEvnt, sizeof(*conEvnt));
|
||||
sngisdn_info->glare.suId = suId;
|
||||
sngisdn_info->glare.suInstId = suInstId;
|
||||
sngisdn_info->glare.spInstId = spInstId;
|
||||
sngisdn_info->glare.dChan = dChan;
|
||||
sngisdn_info->glare.ces = ces;
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received SETUP in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
break;
|
||||
}
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Remote side transmit a CONNECT or CONNECT ACK */
|
||||
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;
|
||||
ftdm_channel_t *ftdmchan;
|
||||
|
||||
ftdm_log(FTDM_LOG_DEBUG, "%s suId:%d suInstId:%d spInstId:%d dChan:%d ces:%d\n", __FUNCTION__, suId, suInstId, spInstId, dChan, ces);
|
||||
|
||||
|
||||
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");
|
||||
|
||||
if (get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%d suInstId:%d spInstId:%d\n", suId, suInstId, spInstId);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
ftdmchan = (ftdm_channel_t*)sngisdn_info->ftdmchan;
|
||||
|
||||
if (!sngisdn_info->spInstId) {
|
||||
sngisdn_info->spInstId = spInstId;
|
||||
g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] = sngisdn_info;
|
||||
}
|
||||
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Received CONNECT/CONNECT ACK\n");
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
|
||||
/* check if there is a pending state change, give it a bit to clear */
|
||||
if (check_for_state_change(ftdmchan) != FTDM_SUCCESS) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Failed to wait for pending state change\n");
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP &&
|
||||
((sngisdn_span_data_t*)ftdmchan->span->signal_data)->signalling == SNGISDN_SIGNALING_NET) {
|
||||
|
||||
if(sngisdn_info->ces == CES_MNGMNT) {
|
||||
/* We assign the call to the first TE */
|
||||
sngisdn_info->ces = ces;
|
||||
} else {
|
||||
/* We already assigned this call, do nothing */
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Call already assigned, ignoring connect\n");
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
|
||||
switch(ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
case FTDM_CHANNEL_STATE_DIALING:
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_UP);
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received CONNECT/CONNECT ACK in an invalid state (%s)\n",
|
||||
ftdm_channel_state2str(ftdmchan->state));
|
||||
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch(ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
/* This is the only valid state we should get a CONNECT ACK on */
|
||||
/* do nothing */
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received CONNECT/CONNECT ACK in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
ftdm_channel_t *ftdmchan;
|
||||
|
||||
ftdm_log(FTDM_LOG_DEBUG, "%s suId:%d suInstId:%d spInstId:%d dChan:%d ces:%d\n", __FUNCTION__, suId, suInstId, spInstId, dChan, ces);
|
||||
|
||||
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");
|
||||
|
||||
if (get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%d suInstId:%d spInstId:%d\n", suId, suInstId, spInstId);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sngisdn_info->spInstId) {
|
||||
sngisdn_info->spInstId = spInstId;
|
||||
g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] = sngisdn_info;
|
||||
}
|
||||
|
||||
ftdmchan = (ftdm_channel_t*)sngisdn_info->ftdmchan;
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Received %s\n",
|
||||
(evntType == MI_ALERTING)?"ALERT":
|
||||
(evntType == MI_CALLPROC)?"PROCEED":
|
||||
(evntType == MI_PROGRESS)?"PROGRESS":"UNKNOWN");
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
|
||||
/* check if there is a pending state change, give it a bit to clear */
|
||||
if (check_for_state_change(ftdmchan) != FTDM_SUCCESS) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Failed to wait for pending state change\n");
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
switch(ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_DIALING:
|
||||
if (evntType == MI_PROGRESS) {
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
|
||||
} else {
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
if (evntType == MI_PROGRESS) {
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
/* Do nothing */
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received ALERT/PROCEED/PROGRESS in an invalid state (%s)\n",
|
||||
ftdm_channel_state2str(ftdmchan->state));
|
||||
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
|
||||
break;
|
||||
}
|
||||
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
ftdm_channel_t *ftdmchan = NULL;
|
||||
|
||||
ftdm_log(FTDM_LOG_DEBUG, "%s suId:%d suInstId:%d spInstId:%d\n", __FUNCTION__, suId, suInstId, spInstId);
|
||||
|
||||
ftdm_assert(spInstId != 0, "Received DISCONNECT with invalid id");
|
||||
|
||||
if (spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) {
|
||||
ftdmchan = (ftdm_channel_t*)sngisdn_info->ftdmchan;
|
||||
} else if (suInstId && get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS) {
|
||||
ftdmchan = (ftdm_channel_t*)sngisdn_info->ftdmchan;
|
||||
} else {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Could not find matching call suId:%d suInstId:%d spInstId:%d\n", suId, suInstId, spInstId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sngisdn_info->spInstId) {
|
||||
sngisdn_info->spInstId = spInstId;
|
||||
g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] = sngisdn_info;
|
||||
}
|
||||
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Received DISCONNECT\n");
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
/* check if there is a pending state change, give it a bit to clear */
|
||||
if (check_for_state_change(ftdmchan) != FTDM_SUCCESS) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Failed to wait for pending state change\n");
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_RING:
|
||||
case FTDM_CHANNEL_STATE_DIALING:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
case FTDM_CHANNEL_STATE_COLLECT:
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
if (discEvnt->causeDgn[0].eh.pres && discEvnt->causeDgn[0].causeVal.pres) {
|
||||
ftdmchan->caller_data.hangup_cause = discEvnt->causeDgn[0].causeVal.val;
|
||||
} else {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "DISCONNECT did not have a cause code\n");
|
||||
ftdmchan->caller_data.hangup_cause = 0;
|
||||
}
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_REMOTE_REL);
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
break;
|
||||
default:
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received DISCONNECT in an invalid state (%s)\n",
|
||||
ftdm_channel_state2str(ftdmchan->state));
|
||||
/* start reset procedure */
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
|
||||
break;
|
||||
}
|
||||
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
void sngisdn_rcv_rel_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, RelEvnt *relEvnt)
|
||||
{
|
||||
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
ftdm_log(FTDM_LOG_DEBUG, "%s suId:%d suInstId:%d spInstId:%d\n", __FUNCTION__, suId, suInstId, spInstId);
|
||||
|
||||
sngisdn_chan_data_t *sngisdn_info ;
|
||||
ftdm_channel_t *ftdmchan = NULL;
|
||||
|
||||
/* get the ftdmchan and ss7_chan_data from the circuit */
|
||||
if (suInstId && (get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
|
||||
ftdmchan = sngisdn_info->ftdmchan;
|
||||
} else if (spInstId && (get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS)) {
|
||||
ftdmchan = sngisdn_info->ftdmchan;
|
||||
}
|
||||
|
||||
if (ftdmchan == NULL) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Failed to find matching channel suId:%d suInstId:%d spInstId:%d\n", suId, suInstId, spInstId);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Received RELEASE/RELEASE COMPLETE\n");
|
||||
/* now that we have the right channel...put a lock on it so no-one else can use it */
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
|
||||
/* check if there is a pending state change, give it a bit to clear */
|
||||
if (check_for_state_change(ftdmchan)) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Failed to wait for pending state change\n");
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
};
|
||||
|
||||
/* check whether the ftdm channel is in a state to accept a call */
|
||||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
|
||||
/* go to DOWN */
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_DOWN:
|
||||
/* do nothing, just drop the message */
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
/* Remote side sent a SETUP, then a RELEASE COMPLETE to abort call - this is an abort */
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_REMOTE_ABORT);
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_DIALING:
|
||||
/* Remote side rejected our SETUP message on outbound call */
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_REMOTE_ABORT);
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_REMOTE_ABORT);
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
break;
|
||||
default:
|
||||
/* Should just stop the call...but a reset is easier for now (since it does hangup the call) */
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received RELEASE in an invalid state (%s)\n",
|
||||
ftdm_channel_state2str(ftdmchan->state));
|
||||
|
||||
/* go to RESTART */
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
|
||||
|
||||
break;
|
||||
/**************************************************************************/
|
||||
}
|
||||
|
||||
/* unlock the channel */
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
void sngisdn_rcv_dat_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, InfoEvnt *infoEvnt)
|
||||
{
|
||||
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
ftdm_log(FTDM_LOG_INFO, "Received DATA IND suId:%d suInstId:%d spInstId:%d\n", suId, suInstId, spInstId);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
void sngisdn_rcv_sshl_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, SsHlEvnt *ssHlEvnt, uint8_t action)
|
||||
{
|
||||
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
ftdm_log(FTDM_LOG_INFO, "Received SSHL IND suId:%d suInstId:%d spInstId:%d\n", suId, suInstId, spInstId);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
void sngisdn_rcv_sshl_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, SsHlEvnt *ssHlEvnt, uint8_t action)
|
||||
{
|
||||
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
ftdm_log(FTDM_LOG_INFO, "Received SSHL CFM suId:%d suInstId:%d spInstId:%d\n", suId, suInstId, spInstId);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
void sngisdn_rcv_rmrt_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, RmRtEvnt *rmRtEvnt, uint8_t action)
|
||||
{
|
||||
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
ftdm_log(FTDM_LOG_INFO, "Received RESUME/RETRIEVE ind suId:%d suInstId:%d spInstId:%d\n", suId, suInstId, spInstId);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
void sngisdn_rcv_rmrt_cfm (int16_t suId, uint32_t suInstId, uint32_t spInstId, RmRtEvnt *rmRtEvnt, uint8_t action)
|
||||
{
|
||||
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
ftdm_log(FTDM_LOG_INFO, "Received RESUME/RETRIEVE CFM suId:%d suInstId:%d spInstId:%d\n", suId, suInstId, spInstId);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
void sngisdn_rcv_flc_ind (int16_t suId, uint32_t suInstId, uint32_t spInstId, StaEvnt *staEvnt)
|
||||
{
|
||||
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
ftdm_log(FTDM_LOG_INFO, "Received FLOW CONTROL IND suId:%d suInstId:%d spInstId:%d\n", suId, suInstId, spInstId);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
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__);
|
||||
ftdm_log(FTDM_LOG_INFO, "Received FACILITY IND suId:%d suInstId:%d spInstId:%d\n", suId, suInstId, spInstId);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
void sngisdn_rcv_sta_cfm ( int16_t suId, uint32_t suInstId, uint32_t spInstId, StaEvnt *staEvnt)
|
||||
{
|
||||
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
ftdm_log(FTDM_LOG_DEBUG, "%s suId:%d suInstId:%d spInstId:%d\n", __FUNCTION__, suId, suInstId, spInstId);
|
||||
|
||||
sngisdn_chan_data_t *sngisdn_info ;
|
||||
ftdm_channel_t *ftdmchan = NULL;
|
||||
uint8_t call_state = 0;
|
||||
|
||||
if (staEvnt->callSte.eh.pres && staEvnt->callSte.callGlblSte.pres) {
|
||||
call_state = staEvnt->callSte.callGlblSte.val;
|
||||
}
|
||||
|
||||
/* get the ftdmchan and ss7_chan_data from the circuit */
|
||||
if (suInstId && (get_ftdmchan_by_suInstId(suId, suInstId, &sngisdn_info) == FTDM_SUCCESS)) {
|
||||
ftdmchan = sngisdn_info->ftdmchan;
|
||||
} else if (spInstId && (get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS)) {
|
||||
ftdmchan = sngisdn_info->ftdmchan;
|
||||
}
|
||||
|
||||
if (ftdmchan == NULL) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Failed to find matching channel suId:%d suInstId:%d spInstId:%d\n", suId, suInstId, spInstId);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Received STATUS CONFIRM\n");
|
||||
/* now that we have the right channel...put a lock on it so no-one else can use it */
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
|
||||
/* check if there is a pending state change, give it a bit to clear */
|
||||
if (check_for_state_change(ftdmchan)) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Failed to wait for pending state change\n");
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
};
|
||||
|
||||
if (staEvnt->causeDgn[0].eh.pres && staEvnt->causeDgn[0].causeVal.pres) {
|
||||
if (staEvnt->causeDgn[0].causeVal.val != 30) {
|
||||
|
||||
if (staEvnt->callSte.eh.pres && staEvnt->callSte.callGlblSte.pres) {
|
||||
call_state = staEvnt->callSte.callGlblSte.val;
|
||||
/* Section 4.3.30 from INT Interface - Service Definition */
|
||||
ftdmchan->caller_data.hangup_cause = staEvnt->causeDgn[0].causeVal.val;
|
||||
|
||||
|
||||
/* There is incompatibility between local and remote side call states some Q931 msgs probably got lost - initiate disconnect */
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Incompatible call states detected, remote side indicated state:%d our state:%s cause:%d\n", call_state, ftdm_channel_state2str(ftdmchan->state), staEvnt->causeDgn[0].causeVal.val);
|
||||
|
||||
switch(call_state) {
|
||||
/* Sere ITU-T Q931 for definition of call states */
|
||||
case 0: /* Remote switch thinks there are no calls on this channel */
|
||||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_COLLECT:
|
||||
case FTDM_CHANNEL_STATE_DIALING:
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_REMOTE_ABORT);
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_TERMINATING:
|
||||
/* We are in the process of clearing local states,
|
||||
just make sure we will not send any messages to remote switch */
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_REMOTE_ABORT);
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_HANGUP:
|
||||
/* This cannot happen, state_advance always sets
|
||||
ftdmchan to STATE_HANGUP_COMPLETE when in STATE_HANGUP
|
||||
and we called check_for_state_change earlier so something is very wrong here!!! */
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "How can we we in FTDM_CHANNEL_STATE_HANGUP after checking for state change?\n");
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
|
||||
/* We were waiting for remote switch to send RELEASE COMPLETE
|
||||
but this will not happen, so just clear local state */
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_DOWN:
|
||||
/* If our local state is down as well, then there is nothing to do */
|
||||
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 8: /* Remote switch is in "Connect Request state" */
|
||||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
/* This is ok. We sent a Connect, and we are waiting for a connect ack */
|
||||
/* Do nothing */
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
|
||||
/* We hung up locally, but remote switch doesn't know send disconnect again*/
|
||||
sngisdn_snd_disconnect(ftdmchan);
|
||||
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;
|
||||
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_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ftdmchan->caller_data.hangup_cause = staEvnt->causeDgn[0].causeVal.val;
|
||||
/* We could not extract the call state */
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Incompatible call states detected, but could not determine call (cause:%d)\n", ftdmchan->caller_data.hangup_cause);
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
|
||||
}
|
||||
|
||||
}
|
||||
/**************************************************************************/
|
||||
}
|
||||
|
||||
/* unlock the channel */
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
void sngisdn_rcv_srv_ind ( int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces)
|
||||
{
|
||||
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
ftdm_log(FTDM_LOG_INFO, "Received SERVICE IND suId:%d dChan:%d ces:%d\n", suId, dChan, ces);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
void sngisdn_rcv_srv_cfm ( int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces)
|
||||
{
|
||||
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
ftdm_log(FTDM_LOG_INFO, "Received SERVICE CFM suId:%d dChan:%d ces:%d\n", suId, dChan, ces);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
void sngisdn_rcv_rst_ind (int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces, uint8_t evtType)
|
||||
{
|
||||
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
ftdm_log(FTDM_LOG_INFO, "Received RESTART IND suId:%d dChan:%d ces:%d\n", suId, dChan, ces);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void sngisdn_rcv_rst_cfm ( int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces, uint8_t evtType)
|
||||
{
|
||||
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
ftdm_log(FTDM_LOG_INFO, "Received RESTART CFM suId:%d dChan:%d ces:%d\n", suId, dChan, ces);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
void sngisdn_rcv_phy_ind(SuId suId, Reason reason)
|
||||
{
|
||||
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
ftdm_log(FTDM_LOG_INFO, "[SNGISDN PHY] D-chan %d : %s\n", suId, DECODE_LL1_REASON(reason));
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
void sngisdn_rcv_q921_ind(BdMngmt *status)
|
||||
{
|
||||
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
|
||||
unsigned j,k;
|
||||
ftdm_span_t *ftdmspan = NULL;
|
||||
|
||||
for(j=1;j<=g_sngisdn_data.num_dchan;j++) {
|
||||
for(k=1;k<=g_sngisdn_data.dchans[j].num_spans;k++) {
|
||||
if (g_sngisdn_data.dchans[j].spans[k]->link_id == status->t.usta.lnkNmb) {
|
||||
ftdmspan = (ftdm_span_t*)g_sngisdn_data.dchans[j].spans[k]->ftdm_span;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ftdmspan == NULL) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Received q921 status on unconfigured span\n", status->t.usta.lnkNmb);
|
||||
#ifdef DEBUG_MODE
|
||||
FORCE_SEGFAULT
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
switch (status->t.usta.alarm.category) {
|
||||
case (LCM_CATEGORY_INTERFACE):
|
||||
ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q921] %s: %s: %s(%d): %s(%d)\n",
|
||||
ftdmspan->name,
|
||||
DECODE_LCM_CATEGORY(status->t.usta.alarm.category),
|
||||
DECODE_LCM_EVENT(status->t.usta.alarm.event), status->t.usta.alarm.event,
|
||||
DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause);
|
||||
break;
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q921] %s: %s: %s(%d): %s(%d)\n",
|
||||
ftdmspan->name,
|
||||
DECODE_LCM_CATEGORY(status->t.usta.alarm.category),
|
||||
DECODE_LLD_EVENT(status->t.usta.alarm.event), status->t.usta.alarm.event,
|
||||
DECODE_LLD_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause);
|
||||
break;
|
||||
}
|
||||
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__)
|
||||
return;
|
||||
}
|
||||
void sngisdn_rcv_q931_ind(InMngmt *status)
|
||||
{
|
||||
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
|
||||
|
||||
|
||||
ftdm_span_t *ftdmspan = NULL;
|
||||
|
||||
if (status->t.usta.alarm.cause == 287) {
|
||||
get_memory_info();
|
||||
return;
|
||||
}
|
||||
|
||||
switch (status->t.usta.alarm.category) {
|
||||
case (LCM_CATEGORY_INTERFACE):
|
||||
ftdm_log(FTDM_LOG_WARNING, "[SNGISDN Q931] s%d: %s: %s(%d): %s(%d)\n",
|
||||
status->t.usta.suId,
|
||||
DECODE_LCM_CATEGORY(status->t.usta.alarm.category),
|
||||
DECODE_LCM_EVENT(status->t.usta.alarm.event), status->t.usta.alarm.event,
|
||||
DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause);
|
||||
|
||||
/* clean this up later */
|
||||
|
||||
switch (status->t.usta.alarm.event) {
|
||||
case LCM_EVENT_UP:
|
||||
case LCM_EVENT_DOWN:
|
||||
{
|
||||
unsigned j,k;
|
||||
for(j=1;j<=g_sngisdn_data.num_dchan;j++) {
|
||||
for(k=1;k<=g_sngisdn_data.dchans[j].num_spans;k++) {
|
||||
if (g_sngisdn_data.dchans[j].spans[k]->link_id == status->t.usta.suId) {
|
||||
ftdmspan = (ftdm_span_t*)g_sngisdn_data.dchans[j].spans[k]->ftdm_span;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ftdmspan == NULL) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Received q931 LCM EVENT on unconfigured span (suId:%d)\n", status->t.usta.suId);
|
||||
return;
|
||||
}
|
||||
|
||||
sngisdn_set_span_sig_status(ftdmspan, (status->t.usta.alarm.event == LCM_EVENT_UP)?FTDM_SIG_STATE_UP:FTDM_SIG_STATE_DOWN);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_DEBUG, "[SNGISDN Q931] s%d: %s: %s(%d): %s(%d)\n",
|
||||
status->t.usta.suId,
|
||||
DECODE_LCM_CATEGORY(status->t.usta.alarm.category),
|
||||
DECODE_LCM_EVENT(status->t.usta.alarm.event), status->t.usta.alarm.event,
|
||||
DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
void sngisdn_rcv_cc_ind(CcMngmt *status)
|
||||
{
|
||||
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
ftdm_log(FTDM_LOG_INFO, "RECEIVED %s\n", __FUNCTION__);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
#define Q931_TRC_EVENT(event) (event == TL3PKTTX)?"TX": \
|
||||
(event == TL3PKTRX)?"RX":"UNKNOWN"
|
||||
|
||||
void sngisdn_rcv_q931_trace(InMngmt *trc, Buffer *mBuf)
|
||||
{
|
||||
MsgLen mlen;
|
||||
MsgLen i;
|
||||
int16_t j;
|
||||
Buffer *tmp;
|
||||
Data *cptr;
|
||||
uint8_t data;
|
||||
uint8_t tdata[1000];
|
||||
char *data_str = ftdm_calloc(1,MAX_DECODE_STR_LEN); /* TODO Find a proper size */
|
||||
|
||||
ftdm_assert(mBuf != NULLP, "Received a Q931 trace with no buffer");
|
||||
mlen = ((SsMsgInfo*)(mBuf->b_rptr))->len;
|
||||
|
||||
if (mlen != 0) {
|
||||
tmp = mBuf->b_cont;
|
||||
cptr = tmp->b_rptr;
|
||||
data = *cptr++;
|
||||
i = 0;
|
||||
|
||||
for(j=0;j<mlen;j++) {
|
||||
tdata[j]= data;
|
||||
|
||||
if (cptr == tmp->b_wptr) {
|
||||
tmp = tmp->b_cont;
|
||||
if (tmp) cptr = tmp->b_rptr;
|
||||
}
|
||||
data = *cptr++;
|
||||
}
|
||||
|
||||
sngisdn_trace_q931(data_str, tdata, mlen);
|
||||
ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q931] FRAME %s:%s\n", Q931_TRC_EVENT(trc->t.trc.evnt), data_str);
|
||||
}
|
||||
|
||||
ftdm_safe_free(data_str);
|
||||
/* We do not need to free mBuf in this case because stack does it */
|
||||
/* SPutMsg(mBuf); */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#define Q921_TRC_EVENT(event) (event == TL2FRMRX)?"RX": \
|
||||
(event == TL2FRMTX)?"TX": \
|
||||
(event == TL2TMR)?"TMR EXPIRED":"UNKNOWN"
|
||||
|
||||
void sngisdn_rcv_q921_trace(BdMngmt *trc, Buffer *mBuf)
|
||||
{
|
||||
MsgLen mlen;
|
||||
MsgLen i;
|
||||
int16_t j;
|
||||
Buffer *tmp;
|
||||
Data *cptr;
|
||||
uint8_t data;
|
||||
uint8_t tdata[16];
|
||||
char *data_str = ftdm_calloc(1,200); /* TODO Find a proper size */
|
||||
|
||||
|
||||
if (trc->t.trc.evnt == TL2TMR) {
|
||||
goto end_of_trace;
|
||||
}
|
||||
|
||||
ftdm_assert(mBuf != NULLP, "Received a Q921 trace with no buffer");
|
||||
mlen = ((SsMsgInfo*)(mBuf->b_rptr))->len;
|
||||
|
||||
if (mlen != 0) {
|
||||
tmp = mBuf->b_cont;
|
||||
cptr = tmp->b_rptr;
|
||||
data = *cptr++;
|
||||
i = 0;
|
||||
while (i < mlen) {
|
||||
j = 0;
|
||||
for(j=0;j<16;j++) {
|
||||
if (i<mlen) {
|
||||
tdata[j]= data;
|
||||
|
||||
if (cptr == tmp->b_wptr) {
|
||||
tmp = tmp->b_cont;
|
||||
if (tmp) cptr = tmp->b_rptr;
|
||||
}
|
||||
i++;
|
||||
if (i<mlen) data = *cptr++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
sngisdn_trace_q921(data_str, tdata, mlen);
|
||||
ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q921] FRAME %s:%s\n", Q921_TRC_EVENT(trc->t.trc.evnt), data_str);
|
||||
}
|
||||
end_of_trace:
|
||||
ftdm_safe_free(data_str);
|
||||
SPutMsg(mBuf);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void sngisdn_rcv_sng_log(uint8_t level, char *fmt,...)
|
||||
{
|
||||
char *data;
|
||||
int ret;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
ret = ftdm_vasprintf(&data, fmt, ap);
|
||||
if (ret == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (level) {
|
||||
case SNG_LOGLEVEL_DEBUG:
|
||||
ftdm_log(FTDM_LOG_DEBUG, "sng_isdn->%s", data);
|
||||
break;
|
||||
case SNG_LOGLEVEL_WARN:
|
||||
ftdm_log(FTDM_LOG_INFO, "sng_isdn->%s", data);
|
||||
break;
|
||||
case SNG_LOGLEVEL_INFO:
|
||||
ftdm_log(FTDM_LOG_INFO, "sng_isdn->%s", data);
|
||||
break;
|
||||
case SNG_LOGLEVEL_STATS:
|
||||
ftdm_log(FTDM_LOG_INFO, "sng_isdn->%s", data);
|
||||
break;
|
||||
case SNG_LOGLEVEL_ERROR:
|
||||
ftdm_log(FTDM_LOG_ERROR, "sng_isdn->%s", data);
|
||||
#ifdef DEBUG_MODE
|
||||
FORCE_SEGFAULT
|
||||
#endif
|
||||
break;
|
||||
case SNG_LOGLEVEL_CRIT:
|
||||
ftdm_log(FTDM_LOG_CRIT, "sng_isdn->%s", data);
|
||||
#ifdef DEBUG_MODE
|
||||
FORCE_SEGFAULT
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_INFO, "sng_isdn->%s", data);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
* indent-tabs-mode:t
|
||||
* tab-width:4
|
||||
* c-basic-offset:4
|
||||
* End:
|
||||
* For VIM:
|
||||
* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
|
@ -34,16 +34,16 @@
|
|||
|
||||
#include "ftmod_sangoma_isdn.h"
|
||||
|
||||
extern ftdm_status_t cpy_calling_num_to_sngisdn(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t *ftdm);
|
||||
extern ftdm_status_t cpy_called_num_to_sngisdn(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t *ftdm);
|
||||
extern ftdm_status_t cpy_calling_name_to_sngisdn(ConEvnt *conEvnt, ftdm_channel_t *ftdmchan);
|
||||
extern ftdm_status_t cpy_calling_num_from_user(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t *ftdm);
|
||||
extern ftdm_status_t cpy_called_num_from_user(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t *ftdm);
|
||||
extern ftdm_status_t cpy_calling_name_from_user(ConEvnt *conEvnt, ftdm_channel_t *ftdmchan);
|
||||
|
||||
void sngisdn_snd_setup(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_progress(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_connect(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_release(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare);
|
||||
|
||||
|
||||
void sngisdn_snd_setup(ftdm_channel_t *ftdmchan)
|
||||
|
@ -52,17 +52,20 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan)
|
|||
sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Sending SETUP\n");
|
||||
|
||||
ftdm_assert((!sngisdn_info->suInstId && !sngisdn_info->spInstId), "Trying to call out, but call data was not cleared\n");
|
||||
|
||||
sngisdn_info->suInstId = get_unique_suInstId(signal_data->cc_id);
|
||||
sngisdn_info->spInstId = 0;
|
||||
|
||||
ftdm_mutex_lock(g_sngisdn_data.ccs[signal_data->cc_id].mutex);
|
||||
g_sngisdn_data.ccs[signal_data->cc_id].active_suInstIds[sngisdn_info->suInstId] = sngisdn_info;
|
||||
ftdm_mutex_unlock(g_sngisdn_data.ccs[signal_data->cc_id].mutex);
|
||||
|
||||
memset(&conEvnt, 0, sizeof(conEvnt));
|
||||
|
||||
|
||||
conEvnt.bearCap[0].eh.pres = PRSNT_NODEF;
|
||||
conEvnt.bearCap[0].infoTranCap.pres = PRSNT_NODEF;
|
||||
|
||||
conEvnt.bearCap[0].infoTranCap.val = IN_ITC_SPEECH;
|
||||
conEvnt.bearCap[0].infoTranCap.val = sngisdn_get_infoTranCap_from_user(ftdmchan->caller_data.bearer_capability);
|
||||
|
||||
conEvnt.bearCap[0].codeStand0.pres = PRSNT_NODEF;
|
||||
conEvnt.bearCap[0].codeStand0.val = IN_CSTD_CCITT;
|
||||
|
@ -92,18 +95,28 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan)
|
|||
conEvnt.chanId.infoChanSel.val = ftdmchan->physical_chan_id;
|
||||
} else {
|
||||
/* PRI only params */
|
||||
if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN) {
|
||||
conEvnt.bearCap[0].usrInfoLyr1Prot.pres = PRSNT_NODEF;
|
||||
conEvnt.bearCap[0].usrInfoLyr1Prot.val = IN_UIL1_G711ULAW;
|
||||
} else {
|
||||
conEvnt.bearCap[0].usrInfoLyr1Prot.pres = PRSNT_NODEF;
|
||||
conEvnt.bearCap[0].usrInfoLyr1Prot.pres = PRSNT_NODEF;
|
||||
conEvnt.bearCap[0].usrInfoLyr1Prot.val = sngisdn_get_usrInfoLyr1Prot_from_user(ftdmchan->caller_data.bearer_layer1);
|
||||
|
||||
if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN &&
|
||||
conEvnt.bearCap[0].usrInfoLyr1Prot.val == IN_UIL1_G711ULAW) {
|
||||
|
||||
/* We are bridging a call from T1 */
|
||||
conEvnt.bearCap[0].usrInfoLyr1Prot.val = IN_UIL1_G711ALAW;
|
||||
|
||||
} else if (conEvnt.bearCap[0].usrInfoLyr1Prot.val == IN_UIL1_G711ALAW) {
|
||||
|
||||
/* We are bridging a call from E1 */
|
||||
conEvnt.bearCap[0].usrInfoLyr1Prot.val = IN_UIL1_G711ULAW;
|
||||
}
|
||||
|
||||
conEvnt.bearCap[0].lyr1Ident.pres = PRSNT_NODEF;
|
||||
conEvnt.bearCap[0].lyr1Ident.val = IN_L1_IDENT;
|
||||
|
||||
conEvnt.chanId.intType.pres = PRSNT_NODEF;
|
||||
conEvnt.chanId.intType.val = IN_IT_OTHER;
|
||||
conEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
|
||||
conEvnt.chanId.infoChanSel.val = IN_ICS_B1CHAN;
|
||||
conEvnt.chanId.chanMapType.pres = PRSNT_NODEF;
|
||||
conEvnt.chanId.chanMapType.val = IN_CMT_BCHAN;
|
||||
conEvnt.chanId.nmbMap.pres = PRSNT_NODEF;
|
||||
|
@ -130,20 +143,81 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan)
|
|||
signal_data->signalling == SNGISDN_SIGNALING_NET) {
|
||||
sngisdn_info->ces = CES_MNGMNT;
|
||||
}
|
||||
|
||||
cpy_calling_num_to_sngisdn(&conEvnt.cgPtyNmb, &ftdmchan->caller_data);
|
||||
cpy_called_num_to_sngisdn(&conEvnt.cdPtyNmb, &ftdmchan->caller_data);
|
||||
cpy_calling_name_to_sngisdn(&conEvnt, ftdmchan);
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending con request on suId:%d suInstId:%u spInstId:%u\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
|
||||
cpy_called_num_from_user(&conEvnt.cdPtyNmb, &ftdmchan->caller_data);
|
||||
cpy_calling_num_from_user(&conEvnt.cgPtyNmb, &ftdmchan->caller_data);
|
||||
cpy_calling_name_from_user(&conEvnt, ftdmchan);
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending SETUP (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
|
||||
|
||||
if (sng_isdn_con_request(signal_data->cc_id, sngisdn_info->suInstId, &conEvnt, signal_data->dchan_id, sngisdn_info->ces)) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused SETUP request\n");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Used only for BRI PTMP */
|
||||
/* Unsed only for overlap receive */
|
||||
void sngisdn_snd_setup_ack(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
CnStEvnt cnStEvnt;
|
||||
|
||||
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending SETUP ACK , but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&cnStEvnt, 0, sizeof(cnStEvnt));
|
||||
|
||||
cnStEvnt.chanId.eh.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.prefExc.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.prefExc.val = IN_PE_EXCLSVE;
|
||||
cnStEvnt.chanId.dChanInd.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.dChanInd.val = IN_DSI_NOTDCHAN;
|
||||
cnStEvnt.chanId.intIdentPres.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.intIdentPres.val = IN_IIP_IMPLICIT;
|
||||
|
||||
|
||||
if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI ||
|
||||
ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
|
||||
|
||||
/* BRI only params */
|
||||
cnStEvnt.chanId.intType.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.intType.val = IN_IT_BASIC;
|
||||
cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.infoChanSel.val = ftdmchan->physical_chan_id;
|
||||
} else {
|
||||
cnStEvnt.chanId.intType.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.intType.val = IN_IT_OTHER;
|
||||
cnStEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.infoChanSel.val = IN_ICS_B1CHAN;
|
||||
cnStEvnt.chanId.chanMapType.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.chanMapType.val = IN_CMT_BCHAN;
|
||||
cnStEvnt.chanId.nmbMap.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.nmbMap.val = IN_NM_CHNNMB;
|
||||
cnStEvnt.chanId.codeStand1.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.codeStand1.val = IN_CSTD_CCITT;
|
||||
cnStEvnt.chanId.chanNmbSlotMap.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.chanNmbSlotMap.len = 1;
|
||||
cnStEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id;
|
||||
}
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending SETUP ACK (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
|
||||
|
||||
if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &cnStEvnt, MI_SETUPACK, signal_data->dchan_id, sngisdn_info->ces)) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused SETUP ACK request\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Used only for BRI PTMP - This function is used when the NT side makes a call out,
|
||||
and one or multiple TE's reply, then NT assigns the call by sending a con_complete*/
|
||||
void sngisdn_snd_con_complete(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
CnStEvnt cnStEvnt;
|
||||
|
@ -151,9 +225,15 @@ void sngisdn_snd_con_complete(ftdm_channel_t *ftdmchan)
|
|||
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending CONNECT COMPL , but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&cnStEvnt, 0, sizeof(cnStEvnt));
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Sending CONNECT ACK\n");
|
||||
|
||||
|
||||
cnStEvnt.chanId.eh.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.prefExc.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.prefExc.val = IN_PE_EXCLSVE;
|
||||
|
@ -187,7 +267,7 @@ void sngisdn_snd_con_complete(ftdm_channel_t *ftdmchan)
|
|||
}
|
||||
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending connect ACK on suId:%d suInstId:%u spInstId:%u ces:%d\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, sngisdn_info->ces);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending CONNECT COMPL (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
|
||||
|
||||
if(sng_isdn_con_comp(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &cnStEvnt, signal_data->dchan_id, sngisdn_info->ces)) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused CONNECT ACK request\n");
|
||||
|
@ -203,9 +283,15 @@ void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan)
|
|||
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending PROGRESS, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&cnStEvnt, 0, sizeof(cnStEvnt));
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Sending PROCEED\n");
|
||||
|
||||
|
||||
cnStEvnt.chanId.eh.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.prefExc.pres = PRSNT_NODEF;
|
||||
cnStEvnt.chanId.prefExc.val = IN_PE_EXCLSVE;
|
||||
|
@ -239,7 +325,7 @@ void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan)
|
|||
}
|
||||
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending con status on suId:%d suInstId:%u spInstId:%u\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending PROCEED (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
|
||||
|
||||
if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &cnStEvnt, MI_CALLPROC, signal_data->dchan_id, sngisdn_info->ces)) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused PROCEED request\n");
|
||||
|
@ -254,9 +340,20 @@ void sngisdn_snd_progress(ftdm_channel_t *ftdmchan)
|
|||
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
memset(&cnStEvnt, 0, sizeof(cnStEvnt));
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Sending PROGRESS\n");
|
||||
if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending PROGRESS, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
return;
|
||||
}
|
||||
|
||||
if (signal_data->switchtype == SNGISDN_SWITCH_INSNET) {
|
||||
/* Trillium Q931 layer complains of invalid event when receiving PROGRESS in
|
||||
INSNET variant, so PROGRESS event is probably invalid */
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&cnStEvnt, 0, sizeof(cnStEvnt));
|
||||
|
||||
cnStEvnt.progInd.eh.pres = PRSNT_NODEF;
|
||||
cnStEvnt.progInd.location.pres = PRSNT_NODEF;
|
||||
|
@ -264,9 +361,9 @@ void sngisdn_snd_progress(ftdm_channel_t *ftdmchan)
|
|||
cnStEvnt.progInd.codeStand0.pres = PRSNT_NODEF;
|
||||
cnStEvnt.progInd.codeStand0.val = IN_CSTD_CCITT;
|
||||
cnStEvnt.progInd.progDesc.pres = PRSNT_NODEF;
|
||||
cnStEvnt.progInd.progDesc.val = IN_PD_NOTETEISDN;
|
||||
cnStEvnt.progInd.progDesc.val = IN_PD_IBAVAIL;
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending con status on suId:%d suInstId:%u spInstId:%u\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending PROGRESS (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
|
||||
if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId,&cnStEvnt, MI_PROGRESS, signal_data->dchan_id, sngisdn_info->ces)) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused PROGRESS request\n");
|
||||
}
|
||||
|
@ -280,7 +377,12 @@ void sngisdn_snd_alert(ftdm_channel_t *ftdmchan)
|
|||
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Sending ALERT\n");
|
||||
if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending ALERT, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&cnStEvnt, 0, sizeof(cnStEvnt));
|
||||
|
||||
|
@ -292,7 +394,7 @@ void sngisdn_snd_alert(ftdm_channel_t *ftdmchan)
|
|||
cnStEvnt.progInd.progDesc.pres = PRSNT_NODEF;
|
||||
cnStEvnt.progInd.progDesc.val = IN_PD_NOTETEISDN;
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending con status on suId:%d suInstId:%u spInstId:%u\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending ALERT (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
|
||||
|
||||
if(sng_isdn_con_status(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId,&cnStEvnt, MI_ALERTING, signal_data->dchan_id, sngisdn_info->ces)) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused ALERT request\n");
|
||||
|
@ -307,8 +409,13 @@ void sngisdn_snd_connect(ftdm_channel_t *ftdmchan)
|
|||
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Sending CONNECT\n");
|
||||
|
||||
if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending CONNECT, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&cnStEvnt, 0, sizeof(cnStEvnt));
|
||||
|
||||
|
||||
|
@ -344,21 +451,75 @@ void sngisdn_snd_connect(ftdm_channel_t *ftdmchan)
|
|||
cnStEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id;
|
||||
}
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending con response on suId:%d suInstId:%u spInstId:%u\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending CONNECT (suId:%d suInstId:%u spInstId:%u dchan:%d ces:%d)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
|
||||
if (sng_isdn_con_response(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &cnStEvnt, signal_data->dchan_id, sngisdn_info->ces)) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused CONNECT request\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
DiscEvnt discEvnt;
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Sending DISCONNECT\n");
|
||||
|
||||
void sngisdn_snd_info_req(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
CnStEvnt cnStEvnt;
|
||||
|
||||
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
if (ftdmchan->span->trunk_type != FTDM_TRUNK_BRI &&
|
||||
ftdmchan->span->trunk_type != FTDM_TRUNK_BRI_PTMP) {
|
||||
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring INFO REQ on non-BRI channel\n");
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&cnStEvnt, 0, sizeof(cnStEvnt));
|
||||
//ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Sending INFO REQ\n");
|
||||
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending INFO REQ (suId:%d dchan:%d ces:%d)\n", signal_data->cc_id, signal_data->dchan_id, sngisdn_info->ces);
|
||||
|
||||
if (sng_isdn_con_status(signal_data->cc_id, 0, 0, &cnStEvnt, MI_INFO, signal_data->dchan_id, sngisdn_info->ces)) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused INFO request\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void sngisdn_snd_status_enq(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
StaEvnt staEvnt;
|
||||
|
||||
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
//ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Sending STATUS ENQ\n");
|
||||
|
||||
memset(&staEvnt, 0, sizeof(StaEvnt));
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending Status ENQ on suId:%d suInstId:%u spInstId:%d dchan:%d ces:%d\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, signal_data->dchan_id, sngisdn_info->ces);
|
||||
if (sng_isdn_status_request(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &staEvnt, MI_STATENQ)) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused Status ENQ request\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
DiscEvnt discEvnt;
|
||||
|
||||
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
if (!sngisdn_info->suInstId || !sngisdn_info->spInstId) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending DISCONNECT, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
|
||||
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&discEvnt, 0, sizeof(discEvnt));
|
||||
|
||||
/* Fill discEvnt here */
|
||||
|
@ -372,20 +533,28 @@ void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan)
|
|||
discEvnt.causeDgn[0].recommend.pres = NOTPRSNT;
|
||||
discEvnt.causeDgn[0].dgnVal.pres = NOTPRSNT;
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending disc request on suId:%d suInstId:%u spInstId:%u\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending DISCONNECT (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
|
||||
if (sng_isdn_disc_request(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &discEvnt)) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused DISCONNECT request\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
void sngisdn_snd_release(ftdm_channel_t *ftdmchan)
|
||||
void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare)
|
||||
{
|
||||
RelEvnt relEvnt;
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Sending RELEASE/RELEASE COMPLETE\n");
|
||||
uint32_t suInstId, spInstId;
|
||||
|
||||
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*) ftdmchan->call_data;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
if (!sngisdn_info->suInstId) {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Sending RELEASE, but no call data, aborting (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
|
||||
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&relEvnt, 0, sizeof(relEvnt));
|
||||
|
||||
/* Fill discEvnt here */
|
||||
|
@ -400,24 +569,29 @@ void sngisdn_snd_release(ftdm_channel_t *ftdmchan)
|
|||
relEvnt.causeDgn[0].recommend.pres = NOTPRSNT;
|
||||
relEvnt.causeDgn[0].dgnVal.pres = NOTPRSNT;
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending release request on suId:%d suInstId:%u spInstId:%u\n", signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
|
||||
if (glare) {
|
||||
suInstId = sngisdn_info->glare.suInstId;
|
||||
spInstId = sngisdn_info->glare.spInstId;
|
||||
} else {
|
||||
suInstId = sngisdn_info->suInstId;
|
||||
spInstId = sngisdn_info->spInstId;
|
||||
}
|
||||
|
||||
if (sng_isdn_release_request(signal_data->cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId, &relEvnt)) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused RELEASE/RELEASE COMPLETE request\n");
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending RELEASE/RELEASE COMPLETE (suId:%d suInstId:%u spInstId:%u)\n", signal_data->cc_id, suInstId, spInstId);
|
||||
|
||||
if (glare) {
|
||||
if (sng_isdn_release_request(signal_data->cc_id, suInstId, spInstId, &relEvnt)) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused RELEASE/RELEASE COMPLETE request\n");
|
||||
}
|
||||
} else {
|
||||
if (sng_isdn_release_request(signal_data->cc_id, suInstId, spInstId, &relEvnt)) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused RELEASE/RELEASE COMPLETE request\n");
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void sngisdn_snd_reset(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Sending RESET\n");
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "%s not implemented\n", __FUNCTION__);
|
||||
/* TODO: implement me */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
|
|
|
@ -0,0 +1,930 @@
|
|||
/*
|
||||
* Copyright (c) 2010, Sangoma Technologies
|
||||
* David Yat Sin <dyatsin@sangoma.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "ftmod_sangoma_isdn.h"
|
||||
|
||||
extern void sngisdn_trace_q921(char* str, uint8_t* data, uint32_t data_len);
|
||||
extern void sngisdn_trace_q931(char* str, uint8_t* data, uint32_t data_len);
|
||||
extern void get_memory_info(void);
|
||||
|
||||
#define MAX_DECODE_STR_LEN 2000
|
||||
|
||||
|
||||
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;
|
||||
sngisdn_event_data_t *sngisdn_event;
|
||||
|
||||
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");
|
||||
|
||||
if (conEvnt->chanId.eh.pres != PRSNT_NODEF) {
|
||||
/* TODO: Implement me */
|
||||
ftdm_log(FTDM_LOG_ERROR, "Incoming call without Channel Id not supported yet\n");
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (conEvnt->chanId.chanNmbSlotMap.pres) {
|
||||
bchan_no = conEvnt->chanId.chanNmbSlotMap.val[0];
|
||||
} else if (conEvnt->chanId.infoChanSel.pres) {
|
||||
bchan_no = conEvnt->chanId.infoChanSel.val;
|
||||
}
|
||||
|
||||
if (!bchan_no) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Failed to obtain b-channel number from SETUP message\n");
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_sngisdn_data.dchans[dChan].channels[bchan_no] == NULL) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Incoming call on unconfigured b-channel:%d\n", bchan_no);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
sngisdn_info = g_sngisdn_data.dchans[dChan].channels[bchan_no];
|
||||
|
||||
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received SETUP (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
|
||||
|
||||
sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event));
|
||||
ftdm_assert(sngisdn_event, "Failed to allocate memory\n");
|
||||
memset(sngisdn_event, 0, sizeof(*sngisdn_event));
|
||||
|
||||
sngisdn_event->event_id = SNGISDN_EVENT_CON_IND;
|
||||
sngisdn_event->sngisdn_info = sngisdn_info;
|
||||
sngisdn_event->suId = suId;
|
||||
sngisdn_event->spInstId = spInstId;
|
||||
sngisdn_event->dChan = dChan;
|
||||
sngisdn_event->ces = ces;
|
||||
|
||||
ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex);
|
||||
g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] = sngisdn_info;
|
||||
ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex);
|
||||
|
||||
memcpy(&sngisdn_event->event.conEvnt, conEvnt, sizeof(*conEvnt));
|
||||
|
||||
ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
}
|
||||
|
||||
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;
|
||||
sngisdn_event_data_t *sngisdn_event;
|
||||
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
if (!sngisdn_info->spInstId) {
|
||||
ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex);
|
||||
sngisdn_info->spInstId = spInstId;
|
||||
g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] = sngisdn_info;
|
||||
ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex);
|
||||
}
|
||||
|
||||
|
||||
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received CONNECT/CONNECT ACK (suId:%u suInstId:%u spInstId:%u ces:%d)\n", suId, suInstId, spInstId, ces);
|
||||
|
||||
sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event));
|
||||
ftdm_assert(sngisdn_event, "Failed to allocate memory\n");
|
||||
memset(sngisdn_event, 0, sizeof(*sngisdn_event));
|
||||
|
||||
sngisdn_event->event_id = SNGISDN_EVENT_CON_CFM;
|
||||
sngisdn_event->sngisdn_info = sngisdn_info;
|
||||
sngisdn_event->suId = suId;
|
||||
sngisdn_event->suInstId = suInstId;
|
||||
sngisdn_event->spInstId = spInstId;
|
||||
sngisdn_event->dChan = dChan;
|
||||
sngisdn_event->ces = ces;
|
||||
memcpy(&sngisdn_event->event.cnStEvnt, cnStEvnt, sizeof(*cnStEvnt));
|
||||
|
||||
ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
}
|
||||
|
||||
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;
|
||||
sngisdn_event_data_t *sngisdn_event;
|
||||
|
||||
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) {
|
||||
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;
|
||||
}
|
||||
|
||||
if (!sngisdn_info->spInstId) {
|
||||
ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex);
|
||||
sngisdn_info->spInstId = spInstId;
|
||||
g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] = sngisdn_info;
|
||||
ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex);
|
||||
}
|
||||
|
||||
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received %s (suId:%u suInstId:%u spInstId:%u ces:%d)\n",
|
||||
(evntType == MI_ALERTING)?"ALERT":
|
||||
(evntType == MI_CALLPROC)?"PROCEED":
|
||||
(evntType == MI_PROGRESS)?"PROGRESS":
|
||||
(evntType == MI_SETUPACK)?"SETUP ACK":
|
||||
(evntType == MI_INFO)?"INFO":"UNKNOWN",
|
||||
suId, suInstId, spInstId, ces);
|
||||
|
||||
sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event));
|
||||
ftdm_assert(sngisdn_event, "Failed to allocate memory\n");
|
||||
memset(sngisdn_event, 0, sizeof(*sngisdn_event));
|
||||
|
||||
sngisdn_event->event_id = SNGISDN_EVENT_CNST_IND;
|
||||
sngisdn_event->sngisdn_info = sngisdn_info;
|
||||
sngisdn_event->suId = suId;
|
||||
sngisdn_event->suInstId = suInstId;
|
||||
sngisdn_event->spInstId = spInstId;
|
||||
sngisdn_event->dChan = dChan;
|
||||
sngisdn_event->ces = ces;
|
||||
sngisdn_event->evntType = evntType;
|
||||
|
||||
memcpy(&sngisdn_event->event.cnStEvnt, cnStEvnt, sizeof(*cnStEvnt));
|
||||
|
||||
ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
}
|
||||
|
||||
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;
|
||||
sngisdn_event_data_t *sngisdn_event;
|
||||
|
||||
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)) {
|
||||
|
||||
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");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sngisdn_info->spInstId) {
|
||||
ftdm_mutex_lock(g_sngisdn_data.ccs[suId].mutex);
|
||||
sngisdn_info->spInstId = spInstId;
|
||||
g_sngisdn_data.ccs[suId].active_spInstIds[spInstId] = sngisdn_info;
|
||||
ftdm_mutex_unlock(g_sngisdn_data.ccs[suId].mutex);
|
||||
}
|
||||
|
||||
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received DISCONNECT (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
|
||||
|
||||
sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event));
|
||||
ftdm_assert(sngisdn_event, "Failed to allocate memory\n");
|
||||
memset(sngisdn_event, 0, sizeof(*sngisdn_event));
|
||||
|
||||
sngisdn_event->event_id = SNGISDN_EVENT_DISC_IND;
|
||||
sngisdn_event->sngisdn_info = sngisdn_info;
|
||||
sngisdn_event->suId = suId;
|
||||
sngisdn_event->suInstId = suInstId;
|
||||
sngisdn_event->spInstId = spInstId;
|
||||
|
||||
memcpy(&sngisdn_event->event.discEvnt, discEvnt, sizeof(*discEvnt));
|
||||
|
||||
ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event);
|
||||
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
}
|
||||
|
||||
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;
|
||||
sngisdn_event_data_t *sngisdn_event;
|
||||
|
||||
if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
|
||||
!(suInstId && get_ftdmchan_by_suInstId(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");
|
||||
return;
|
||||
}
|
||||
|
||||
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received RELEASE/RELEASE COMPLETE (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
|
||||
|
||||
sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event));
|
||||
ftdm_assert(sngisdn_event, "Failed to allocate memory\n");
|
||||
memset(sngisdn_event, 0, sizeof(*sngisdn_event));
|
||||
|
||||
sngisdn_event->event_id = SNGISDN_EVENT_REL_IND;
|
||||
sngisdn_event->sngisdn_info = sngisdn_info;
|
||||
sngisdn_event->suId = suId;
|
||||
sngisdn_event->suInstId = suInstId;
|
||||
sngisdn_event->spInstId = spInstId;
|
||||
|
||||
memcpy(&sngisdn_event->event.relEvnt, relEvnt, sizeof(*relEvnt));
|
||||
|
||||
ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
|
||||
!(suInstId && get_ftdmchan_by_suInstId(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");
|
||||
return;
|
||||
}
|
||||
|
||||
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received DATA IND suId:%u suInstId:%u spInstId:%u\n", suId, suInstId, spInstId);
|
||||
|
||||
sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event));
|
||||
ftdm_assert(sngisdn_event, "Failed to allocate memory\n");
|
||||
memset(sngisdn_event, 0, sizeof(*sngisdn_event));
|
||||
|
||||
sngisdn_event->event_id = SNGISDN_EVENT_DAT_IND;
|
||||
sngisdn_event->sngisdn_info = sngisdn_info;
|
||||
sngisdn_event->suId = suId;
|
||||
sngisdn_event->suInstId = suInstId;
|
||||
sngisdn_event->spInstId = spInstId;
|
||||
|
||||
memcpy(&sngisdn_event->event.infoEvnt, infoEvnt, sizeof(*infoEvnt));
|
||||
|
||||
ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
|
||||
!(suInstId && get_ftdmchan_by_suInstId(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");
|
||||
return;
|
||||
}
|
||||
|
||||
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received SSHL IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
|
||||
|
||||
sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event));
|
||||
ftdm_assert(sngisdn_event, "Failed to allocate memory\n");
|
||||
memset(sngisdn_event, 0, sizeof(*sngisdn_event));
|
||||
|
||||
sngisdn_event->event_id = SNGISDN_EVENT_SSHL_IND;
|
||||
sngisdn_event->sngisdn_info = sngisdn_info;
|
||||
sngisdn_event->suId = suId;
|
||||
sngisdn_event->suInstId = suInstId;
|
||||
sngisdn_event->spInstId = spInstId;
|
||||
sngisdn_event->action = action;
|
||||
|
||||
memcpy(&sngisdn_event->event.ssHlEvnt, ssHlEvnt, sizeof(*ssHlEvnt));
|
||||
|
||||
ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
|
||||
!(suInstId && get_ftdmchan_by_suInstId(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");
|
||||
return;
|
||||
}
|
||||
|
||||
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received SSHL CFM (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
|
||||
|
||||
sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event));
|
||||
ftdm_assert(sngisdn_event, "Failed to allocate memory\n");
|
||||
memset(sngisdn_event, 0, sizeof(*sngisdn_event));
|
||||
|
||||
sngisdn_event->event_id = SNGISDN_EVENT_SSHL_CFM;
|
||||
sngisdn_event->sngisdn_info = sngisdn_info;
|
||||
sngisdn_event->suId = suId;
|
||||
sngisdn_event->suInstId = suInstId;
|
||||
sngisdn_event->spInstId = spInstId;
|
||||
sngisdn_event->action = action;
|
||||
|
||||
memcpy(&sngisdn_event->event.ssHlEvnt, ssHlEvnt, sizeof(*ssHlEvnt));
|
||||
|
||||
ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
}
|
||||
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;
|
||||
|
||||
if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
|
||||
!(suInstId && get_ftdmchan_by_suInstId(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");
|
||||
return;
|
||||
}
|
||||
|
||||
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received RMRT IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
|
||||
|
||||
sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event));
|
||||
ftdm_assert(sngisdn_event, "Failed to allocate memory\n");
|
||||
memset(sngisdn_event, 0, sizeof(*sngisdn_event));
|
||||
|
||||
sngisdn_event->event_id = SNGISDN_EVENT_RMRT_IND;
|
||||
sngisdn_event->sngisdn_info = sngisdn_info;
|
||||
sngisdn_event->suId = suId;
|
||||
sngisdn_event->suInstId = suInstId;
|
||||
sngisdn_event->spInstId = spInstId;
|
||||
sngisdn_event->action = action;
|
||||
|
||||
memcpy(&sngisdn_event->event.rmRtEvnt, rmRtEvnt, sizeof(*rmRtEvnt));
|
||||
|
||||
ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
|
||||
!(suInstId && get_ftdmchan_by_suInstId(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");
|
||||
return;
|
||||
}
|
||||
|
||||
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received RESUME/RETRIEVE CFM (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
|
||||
|
||||
sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event));
|
||||
ftdm_assert(sngisdn_event, "Failed to allocate memory\n");
|
||||
memset(sngisdn_event, 0, sizeof(*sngisdn_event));
|
||||
|
||||
sngisdn_event->event_id = SNGISDN_EVENT_RMRT_CFM;
|
||||
sngisdn_event->sngisdn_info = sngisdn_info;
|
||||
sngisdn_event->suId = suId;
|
||||
sngisdn_event->suInstId = suInstId;
|
||||
sngisdn_event->spInstId = spInstId;
|
||||
sngisdn_event->action = action;
|
||||
|
||||
memcpy(&sngisdn_event->event.rmRtEvnt, rmRtEvnt, sizeof(*rmRtEvnt));
|
||||
|
||||
ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
|
||||
!(suInstId && get_ftdmchan_by_suInstId(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");
|
||||
return;
|
||||
}
|
||||
|
||||
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received FLOW CONTROL IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
|
||||
|
||||
sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event));
|
||||
ftdm_assert(sngisdn_event, "Failed to allocate memory\n");
|
||||
memset(sngisdn_event, 0, sizeof(*sngisdn_event));
|
||||
|
||||
sngisdn_event->event_id = SNGISDN_EVENT_FLC_IND;
|
||||
sngisdn_event->sngisdn_info = sngisdn_info;
|
||||
sngisdn_event->suId = suId;
|
||||
sngisdn_event->suInstId = suInstId;
|
||||
sngisdn_event->spInstId = spInstId;
|
||||
|
||||
memcpy(&sngisdn_event->event.staEvnt, staEvnt, sizeof(*staEvnt));
|
||||
|
||||
ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
|
||||
!(suInstId && get_ftdmchan_by_suInstId(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");
|
||||
return;
|
||||
}
|
||||
|
||||
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received FACILITY IND (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
|
||||
sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event));
|
||||
ftdm_assert(sngisdn_event, "Failed to allocate memory\n");
|
||||
memset(sngisdn_event, 0, sizeof(*sngisdn_event));
|
||||
|
||||
sngisdn_event->event_id = SNGISDN_EVENT_FAC_IND;
|
||||
sngisdn_event->sngisdn_info = sngisdn_info;
|
||||
sngisdn_event->suId = suId;
|
||||
sngisdn_event->suInstId = suInstId;
|
||||
sngisdn_event->spInstId = spInstId;
|
||||
sngisdn_event->evntType = evntType;
|
||||
|
||||
memcpy(&sngisdn_event->event.facEvnt, facEvnt, sizeof(*facEvnt));
|
||||
|
||||
ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
if (!(spInstId && get_ftdmchan_by_spInstId(suId, spInstId, &sngisdn_info) == FTDM_SUCCESS) &&
|
||||
!(suInstId && get_ftdmchan_by_suInstId(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");
|
||||
return;
|
||||
}
|
||||
|
||||
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Received STATUS CONFIRM (suId:%u suInstId:%u spInstId:%u)\n", suId, suInstId, spInstId);
|
||||
|
||||
sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event));
|
||||
ftdm_assert(sngisdn_event, "Failed to allocate memory\n");
|
||||
memset(sngisdn_event, 0, sizeof(*sngisdn_event));
|
||||
|
||||
sngisdn_event->event_id = SNGISDN_EVENT_STA_CFM;
|
||||
sngisdn_event->sngisdn_info = sngisdn_info;
|
||||
sngisdn_event->suId = suId;
|
||||
sngisdn_event->suInstId = suInstId;
|
||||
sngisdn_event->spInstId = spInstId;
|
||||
|
||||
memcpy(&sngisdn_event->event.staEvnt, staEvnt, sizeof(*staEvnt));
|
||||
|
||||
ftdm_queue_enqueue(((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->event_queue, sngisdn_event);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
ftdm_log(FTDM_LOG_INFO, "Received SERVICE IND (dChan:%d ces:%u)\n", dChan, ces);
|
||||
|
||||
/* Enqueue the event to each span within the dChan */
|
||||
for(i=1; i<=g_sngisdn_data.dchans[dChan].num_spans; i++) {
|
||||
signal_data = g_sngisdn_data.dchans[dChan].spans[i];
|
||||
sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event));
|
||||
ftdm_assert(sngisdn_event, "Failed to allocate memory\n");
|
||||
memset(sngisdn_event, 0, sizeof(*sngisdn_event));
|
||||
|
||||
sngisdn_event->event_id = SNGISDN_EVENT_SRV_IND;
|
||||
sngisdn_event->suId = suId;
|
||||
sngisdn_event->dChan = dChan;
|
||||
sngisdn_event->ces = ces;
|
||||
sngisdn_event->signal_data = signal_data;
|
||||
|
||||
memcpy(&sngisdn_event->event.srvEvnt, srvEvnt, sizeof(*srvEvnt));
|
||||
ftdm_queue_enqueue((signal_data)->event_queue, sngisdn_event);
|
||||
}
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
sngisdn_event_data_t *sngisdn_event;
|
||||
|
||||
ftdm_log(FTDM_LOG_INFO, "Received SERVICE CFM (dChan:%d ces:%u)\n", dChan, ces);
|
||||
|
||||
/* Enqueue the event to each span within the dChan */
|
||||
for(i=1; i<=g_sngisdn_data.dchans[dChan].num_spans; i++) {
|
||||
signal_data = g_sngisdn_data.dchans[dChan].spans[i];
|
||||
sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event));
|
||||
ftdm_assert(sngisdn_event, "Failed to allocate memory\n");
|
||||
memset(sngisdn_event, 0, sizeof(*sngisdn_event));
|
||||
|
||||
sngisdn_event->event_id = SNGISDN_EVENT_SRV_CFM;
|
||||
sngisdn_event->suId = suId;
|
||||
sngisdn_event->dChan = dChan;
|
||||
sngisdn_event->ces = ces;
|
||||
sngisdn_event->signal_data = signal_data;
|
||||
|
||||
memcpy(&sngisdn_event->event.srvEvnt, srvEvnt, sizeof(*srvEvnt));
|
||||
ftdm_queue_enqueue((signal_data)->event_queue, sngisdn_event);
|
||||
}
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
}
|
||||
|
||||
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;
|
||||
sngisdn_event_data_t *sngisdn_event;
|
||||
|
||||
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 */
|
||||
for(i=1; i<=g_sngisdn_data.dchans[dChan].num_spans; i++) {
|
||||
signal_data = g_sngisdn_data.dchans[dChan].spans[i];
|
||||
sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event));
|
||||
ftdm_assert(sngisdn_event, "Failed to allocate memory\n");
|
||||
memset(sngisdn_event, 0, sizeof(*sngisdn_event));
|
||||
|
||||
sngisdn_event->event_id = SNGISDN_EVENT_RST_IND;
|
||||
sngisdn_event->suId = suId;
|
||||
sngisdn_event->dChan = dChan;
|
||||
sngisdn_event->ces = ces;
|
||||
sngisdn_event->evntType = evntType;
|
||||
sngisdn_event->signal_data = signal_data;
|
||||
|
||||
memcpy(&sngisdn_event->event.rstEvnt, rstEvnt, sizeof(*rstEvnt));
|
||||
ftdm_queue_enqueue(signal_data->event_queue, sngisdn_event);
|
||||
}
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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 */
|
||||
for(i=1; i<=g_sngisdn_data.dchans[dChan].num_spans; i++) {
|
||||
signal_data = g_sngisdn_data.dchans[dChan].spans[i];
|
||||
sngisdn_event = ftdm_malloc(sizeof(*sngisdn_event));
|
||||
ftdm_assert(sngisdn_event, "Failed to allocate memory\n");
|
||||
memset(sngisdn_event, 0, sizeof(*sngisdn_event));
|
||||
|
||||
sngisdn_event->event_id = SNGISDN_EVENT_RST_CFM;
|
||||
sngisdn_event->suId = suId;
|
||||
sngisdn_event->dChan = dChan;
|
||||
sngisdn_event->ces = ces;
|
||||
sngisdn_event->evntType = evntType;
|
||||
sngisdn_event->signal_data = signal_data;
|
||||
|
||||
memcpy(&sngisdn_event->event.rstEvnt, rstEvnt, sizeof(*rstEvnt));
|
||||
ftdm_queue_enqueue((signal_data)->event_queue, sngisdn_event);
|
||||
}
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
}
|
||||
|
||||
|
||||
void sngisdn_rcv_phy_ind(SuId suId, Reason reason)
|
||||
{
|
||||
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
if (reason != LL1_REASON_CON_REQ_FAIL) {
|
||||
ftdm_log(FTDM_LOG_INFO, "[SNGISDN PHY] D-chan %d : %s\n", suId, DECODE_LL1_REASON(reason));
|
||||
}
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
void sngisdn_rcv_q921_ind(BdMngmt *status)
|
||||
{
|
||||
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
|
||||
unsigned j,k;
|
||||
ftdm_span_t *ftdmspan = NULL;
|
||||
|
||||
for(j=1;j<=g_sngisdn_data.num_dchan;j++) {
|
||||
for(k=1;k<=g_sngisdn_data.dchans[j].num_spans;k++) {
|
||||
if (g_sngisdn_data.dchans[j].spans[k]->link_id == status->t.usta.lnkNmb) {
|
||||
ftdmspan = (ftdm_span_t*)g_sngisdn_data.dchans[j].spans[k]->ftdm_span;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ftdmspan == NULL) {
|
||||
ftdm_log(FTDM_LOG_WARNING, "Received q921 status on unconfigured span (lnkNmb:%d)\n", status->t.usta.lnkNmb);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (status->t.usta.alarm.category) {
|
||||
case (LCM_CATEGORY_INTERFACE):
|
||||
ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q921] %s: %s: %s(%d): %s(%d)\n",
|
||||
ftdmspan->name,
|
||||
DECODE_LCM_CATEGORY(status->t.usta.alarm.category),
|
||||
DECODE_LCM_EVENT(status->t.usta.alarm.event), status->t.usta.alarm.event,
|
||||
DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause);
|
||||
break;
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q921] %s: %s: %s(%d): %s(%d)\n",
|
||||
ftdmspan->name,
|
||||
DECODE_LCM_CATEGORY(status->t.usta.alarm.category),
|
||||
DECODE_LLD_EVENT(status->t.usta.alarm.event), status->t.usta.alarm.event,
|
||||
DECODE_LLD_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause);
|
||||
|
||||
switch (status->t.usta.alarm.event) {
|
||||
case ENTR_CONG: /* Entering Congestion */
|
||||
ftdm_log(FTDM_LOG_WARNING, "s%d: Entering Congestion\n", ftdmspan->span_id);
|
||||
ftdm_set_flag(ftdmspan, FTDM_SPAN_SUSPENDED);
|
||||
break;
|
||||
case EXIT_CONG: /* Exiting Congestion */
|
||||
ftdm_log(FTDM_LOG_WARNING, "s%d: Exiting Congestion\n", ftdmspan->span_id);
|
||||
ftdm_clear_flag(ftdmspan, FTDM_SPAN_SUSPENDED);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__)
|
||||
return;
|
||||
}
|
||||
void sngisdn_rcv_q931_ind(InMngmt *status)
|
||||
{
|
||||
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
ftdm_span_t *ftdmspan = NULL;
|
||||
|
||||
if (status->t.usta.alarm.cause == 287) {
|
||||
get_memory_info();
|
||||
return;
|
||||
}
|
||||
|
||||
switch (status->t.usta.alarm.category) {
|
||||
case (LCM_CATEGORY_INTERFACE):
|
||||
ftdm_log(FTDM_LOG_WARNING, "[SNGISDN Q931] s%d: %s: %s(%d): %s(%d)\n",
|
||||
status->t.usta.suId,
|
||||
DECODE_LCM_CATEGORY(status->t.usta.alarm.category),
|
||||
DECODE_LCM_EVENT(status->t.usta.alarm.event), status->t.usta.alarm.event,
|
||||
DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause);
|
||||
|
||||
/* clean this up later */
|
||||
|
||||
switch (status->t.usta.alarm.event) {
|
||||
case LCM_EVENT_UP:
|
||||
case LCM_EVENT_DOWN:
|
||||
{
|
||||
unsigned j,k;
|
||||
for(j=1;j<=g_sngisdn_data.num_dchan;j++) {
|
||||
for(k=1;k<=g_sngisdn_data.dchans[j].num_spans;k++) {
|
||||
if (g_sngisdn_data.dchans[j].spans[k]->link_id == status->t.usta.suId) {
|
||||
ftdmspan = (ftdm_span_t*)g_sngisdn_data.dchans[j].spans[k]->ftdm_span;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ftdmspan == NULL) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Received q931 LCM EVENT on unconfigured span (suId:%u)\n", status->t.usta.suId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (status->t.usta.alarm.event == LCM_EVENT_UP) {
|
||||
sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_UP);
|
||||
sng_isdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_UP);
|
||||
} else {
|
||||
sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_DOWN);
|
||||
sng_isdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_PWR_SAVING);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_DEBUG, "[SNGISDN Q931] s%d: %s: %s(%d): %s(%d)\n",
|
||||
status->t.usta.suId,
|
||||
DECODE_LCM_CATEGORY(status->t.usta.alarm.category),
|
||||
DECODE_LCM_EVENT(status->t.usta.alarm.event), status->t.usta.alarm.event,
|
||||
DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
void sngisdn_rcv_cc_ind(CcMngmt *status)
|
||||
{
|
||||
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
ftdm_log(FTDM_LOG_INFO, "RECEIVED %s\n", __FUNCTION__);
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
#define Q931_TRC_EVENT(event) (event == TL3PKTTX)?"TX": \
|
||||
(event == TL3PKTRX)?"RX":"UNKNOWN"
|
||||
|
||||
void sngisdn_rcv_q931_trace(InMngmt *trc, Buffer *mBuf)
|
||||
{
|
||||
MsgLen mlen;
|
||||
MsgLen i;
|
||||
int16_t j;
|
||||
Buffer *tmp;
|
||||
Data *cptr;
|
||||
uint8_t data;
|
||||
uint8_t tdata[1000];
|
||||
char *data_str = ftdm_calloc(1,MAX_DECODE_STR_LEN); /* TODO Find a proper size */
|
||||
|
||||
ftdm_assert(mBuf != NULLP, "Received a Q931 trace with no buffer");
|
||||
mlen = ((SsMsgInfo*)(mBuf->b_rptr))->len;
|
||||
|
||||
if (mlen != 0) {
|
||||
tmp = mBuf->b_cont;
|
||||
cptr = tmp->b_rptr;
|
||||
data = *cptr++;
|
||||
i = 0;
|
||||
|
||||
for(j=0;j<mlen;j++) {
|
||||
tdata[j]= data;
|
||||
|
||||
if (cptr == tmp->b_wptr) {
|
||||
tmp = tmp->b_cont;
|
||||
if (tmp) cptr = tmp->b_rptr;
|
||||
}
|
||||
data = *cptr++;
|
||||
}
|
||||
|
||||
sngisdn_trace_q931(data_str, tdata, mlen);
|
||||
ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q931] s%d FRAME %s:%s\n", trc->t.trc.suId, Q931_TRC_EVENT(trc->t.trc.evnt), data_str);
|
||||
}
|
||||
|
||||
ftdm_safe_free(data_str);
|
||||
/* We do not need to free mBuf in this case because stack does it */
|
||||
/* SPutMsg(mBuf); */
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#define Q921_TRC_EVENT(event) (event == TL2FRMRX)?"RX": \
|
||||
(event == TL2FRMTX)?"TX": \
|
||||
(event == TL2TMR)?"TMR EXPIRED":"UNKNOWN"
|
||||
|
||||
void sngisdn_rcv_q921_trace(BdMngmt *trc, Buffer *mBuf)
|
||||
{
|
||||
MsgLen mlen;
|
||||
MsgLen i;
|
||||
int16_t j;
|
||||
Buffer *tmp;
|
||||
Data *cptr;
|
||||
uint8_t data;
|
||||
uint8_t tdata[16];
|
||||
char *data_str = ftdm_calloc(1,200); /* TODO Find a proper size */
|
||||
|
||||
|
||||
if (trc->t.trc.evnt == TL2TMR) {
|
||||
goto end_of_trace;
|
||||
}
|
||||
|
||||
ftdm_assert(mBuf != NULLP, "Received a Q921 trace with no buffer");
|
||||
mlen = ((SsMsgInfo*)(mBuf->b_rptr))->len;
|
||||
|
||||
if (mlen != 0) {
|
||||
tmp = mBuf->b_cont;
|
||||
cptr = tmp->b_rptr;
|
||||
data = *cptr++;
|
||||
i = 0;
|
||||
while (i < mlen) {
|
||||
j = 0;
|
||||
for(j=0;j<16;j++) {
|
||||
if (i<mlen) {
|
||||
tdata[j]= data;
|
||||
|
||||
if (cptr == tmp->b_wptr) {
|
||||
tmp = tmp->b_cont;
|
||||
if (tmp) cptr = tmp->b_rptr;
|
||||
}
|
||||
i++;
|
||||
if (i<mlen) data = *cptr++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
sngisdn_trace_q921(data_str, tdata, mlen);
|
||||
ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q921] s%d FRAME %s:%s\n", trc->t.trc.lnkNmb, Q921_TRC_EVENT(trc->t.trc.evnt), data_str);
|
||||
}
|
||||
end_of_trace:
|
||||
ftdm_safe_free(data_str);
|
||||
SPutMsg(mBuf);
|
||||
return;
|
||||
}
|
||||
|
||||
void sngisdn_rcv_sng_assert(char *message)
|
||||
{
|
||||
ftdm_assert(0, message);
|
||||
}
|
||||
|
||||
void sngisdn_rcv_sng_log(uint8_t level, char *fmt,...)
|
||||
{
|
||||
char *data;
|
||||
int ret;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
ret = ftdm_vasprintf(&data, fmt, ap);
|
||||
if (ret == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (level) {
|
||||
case SNG_LOGLEVEL_DEBUG:
|
||||
ftdm_log(FTDM_LOG_DEBUG, "sng_isdn->%s", data);
|
||||
break;
|
||||
case SNG_LOGLEVEL_WARN:
|
||||
ftdm_log(FTDM_LOG_INFO, "sng_isdn->%s", data);
|
||||
break;
|
||||
case SNG_LOGLEVEL_INFO:
|
||||
ftdm_log(FTDM_LOG_INFO, "sng_isdn->%s", data);
|
||||
break;
|
||||
case SNG_LOGLEVEL_STATS:
|
||||
ftdm_log(FTDM_LOG_INFO, "sng_isdn->%s", data);
|
||||
break;
|
||||
case SNG_LOGLEVEL_ERROR:
|
||||
ftdm_log(FTDM_LOG_ERROR, "sng_isdn->%s", data);
|
||||
/*ftdm_assert(0, "Got an error from stack");*/
|
||||
break;
|
||||
case SNG_LOGLEVEL_CRIT:
|
||||
ftdm_log(FTDM_LOG_CRIT, "sng_isdn->%s", data);
|
||||
/*ftdm_assert(0, "Got an error from stack");*/
|
||||
break;
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_INFO, "sng_isdn->%s", data);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
* indent-tabs-mode:t
|
||||
* tab-width:4
|
||||
* c-basic-offset:4
|
||||
* End:
|
||||
* For VIM:
|
||||
* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
|
||||
*/
|
||||
|
||||
/******************************************************************************/
|
|
@ -34,25 +34,30 @@
|
|||
|
||||
#include "ftmod_sangoma_isdn.h"
|
||||
|
||||
ftdm_status_t cpy_calling_num_from_sngisdn(ftdm_caller_data_t *ftdm, CgPtyNmb *cgPtyNmb);
|
||||
ftdm_status_t cpy_called_num_from_sngisdn(ftdm_caller_data_t *ftdm, CdPtyNmb *cdPtyNmb);
|
||||
ftdm_status_t cpy_redir_num_from_sngisdn(ftdm_caller_data_t *ftdm, RedirNmb *redirNmb);
|
||||
ftdm_status_t cpy_calling_name_from_sngisdn(ftdm_caller_data_t *ftdm, ConEvnt *conEvnt);
|
||||
ftdm_status_t cpy_calling_num_from_stack(ftdm_caller_data_t *ftdm, CgPtyNmb *cgPtyNmb);
|
||||
ftdm_status_t cpy_called_num_from_stack(ftdm_caller_data_t *ftdm, CdPtyNmb *cdPtyNmb);
|
||||
ftdm_status_t cpy_redir_num_from_stack(ftdm_caller_data_t *ftdm, RedirNmb *redirNmb);
|
||||
ftdm_status_t cpy_calling_name_from_stack(ftdm_caller_data_t *ftdm, Display *display);
|
||||
|
||||
ftdm_status_t cpy_calling_num_to_sngisdn(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t *ftdm);
|
||||
ftdm_status_t cpy_called_num_to_sngisdn(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t *ftdm);
|
||||
ftdm_status_t cpy_redir_num_to_sngisdn(RedirNmb *redirNmb, ftdm_caller_data_t *ftdm);
|
||||
ftdm_status_t cpy_calling_name_to_sngisdn(ConEvnt *conEvnt, ftdm_channel_t *ftdmchan);
|
||||
ftdm_status_t cpy_calling_num_from_user(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t *ftdm);
|
||||
ftdm_status_t cpy_called_num_from_user(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t *ftdm);
|
||||
ftdm_status_t cpy_redir_num_from_user(RedirNmb *redirNmb, ftdm_caller_data_t *ftdm);
|
||||
ftdm_status_t cpy_calling_name_from_user(ConEvnt *conEvnt, ftdm_channel_t *ftdmchan);
|
||||
|
||||
ftdm_status_t sngisdn_check_free_ids(void);
|
||||
|
||||
extern ftdm_sngisdn_data_t g_sngisdn_data;
|
||||
void get_memory_info(void);
|
||||
|
||||
void clear_call_data(sngisdn_chan_data_t *sngisdn_info)
|
||||
void __inline__ 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;
|
||||
|
||||
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_DEBUG, "Clearing call data (suId:%u suInstId:%u spInstId:%u)\n", cc_id, sngisdn_info->suInstId, sngisdn_info->spInstId);
|
||||
ftdm_mutex_lock(g_sngisdn_data.ccs[cc_id].mutex);
|
||||
g_sngisdn_data.ccs[cc_id].active_spInstIds[sngisdn_info->spInstId]=NULL;
|
||||
g_sngisdn_data.ccs[cc_id].active_suInstIds[sngisdn_info->suInstId]=NULL;
|
||||
ftdm_mutex_unlock(g_sngisdn_data.ccs[cc_id].mutex);
|
||||
|
||||
sngisdn_info->suInstId = 0;
|
||||
sngisdn_info->spInstId = 0;
|
||||
|
@ -61,10 +66,33 @@ void clear_call_data(sngisdn_chan_data_t *sngisdn_info)
|
|||
return;
|
||||
}
|
||||
|
||||
uint32_t get_unique_suInstId(uint8_t cc_id)
|
||||
void __inline__ 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,
|
||||
sngisdn_info->glare.suInstId, sngisdn_info->glare.spInstId,
|
||||
sngisdn_info->suInstId, sngisdn_info->spInstId);
|
||||
|
||||
ftdm_mutex_lock(g_sngisdn_data.ccs[sngisdn_info->glare.suId].mutex);
|
||||
g_sngisdn_data.ccs[sngisdn_info->glare.suId].active_spInstIds[sngisdn_info->glare.spInstId]=NULL;
|
||||
g_sngisdn_data.ccs[sngisdn_info->glare.suId].active_suInstIds[sngisdn_info->glare.suInstId]=NULL;
|
||||
ftdm_mutex_unlock(g_sngisdn_data.ccs[sngisdn_info->glare.suId].mutex);
|
||||
|
||||
ftdm_clear_flag(sngisdn_info, FLAG_GLARE);
|
||||
memset(&sngisdn_info->glare.setup, 0, sizeof(ConEvnt));
|
||||
sngisdn_info->glare.suId = 0;
|
||||
sngisdn_info->glare.suInstId = 0;
|
||||
sngisdn_info->glare.spInstId = 0;
|
||||
sngisdn_info->glare.dChan = 0;
|
||||
sngisdn_info->glare.ces = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
uint32_t __inline__ get_unique_suInstId(uint8_t cc_id)
|
||||
{
|
||||
uint32_t suInstId;
|
||||
ftdm_mutex_lock(g_sngisdn_data.ccs[cc_id].request_mutex);
|
||||
ftdm_mutex_lock(g_sngisdn_data.ccs[cc_id].mutex);
|
||||
suInstId = g_sngisdn_data.ccs[cc_id].last_suInstId;
|
||||
|
||||
while(1) {
|
||||
|
@ -73,16 +101,16 @@ uint32_t get_unique_suInstId(uint8_t cc_id)
|
|||
}
|
||||
if (g_sngisdn_data.ccs[cc_id].active_suInstIds[suInstId] == NULL) {
|
||||
g_sngisdn_data.ccs[cc_id].last_suInstId = suInstId;
|
||||
ftdm_mutex_unlock(g_sngisdn_data.ccs[cc_id].request_mutex);
|
||||
ftdm_mutex_unlock(g_sngisdn_data.ccs[cc_id].mutex);
|
||||
return suInstId;
|
||||
}
|
||||
}
|
||||
/* Should never reach here */
|
||||
ftdm_mutex_unlock(g_sngisdn_data.ccs[cc_id].request_mutex);
|
||||
ftdm_mutex_unlock(g_sngisdn_data.ccs[cc_id].mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ftdm_status_t get_ftdmchan_by_suInstId(uint8_t cc_id, uint32_t suInstId, sngisdn_chan_data_t **sngisdn_data)
|
||||
ftdm_status_t __inline__ 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");
|
||||
|
||||
|
@ -93,7 +121,7 @@ ftdm_status_t get_ftdmchan_by_suInstId(uint8_t cc_id, uint32_t suInstId, sngisdn
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t get_ftdmchan_by_spInstId(uint8_t cc_id, uint32_t spInstId, sngisdn_chan_data_t **sngisdn_data)
|
||||
ftdm_status_t __inline__ 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");
|
||||
|
||||
|
@ -104,8 +132,21 @@ ftdm_status_t get_ftdmchan_by_spInstId(uint8_t cc_id, uint32_t spInstId, sngisdn
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t sng_isdn_set_avail_rate(ftdm_span_t *ftdmspan, sngisdn_avail_t avail)
|
||||
{
|
||||
unsigned i;
|
||||
if (ftdmspan->trunk_type == FTDM_TRUNK_BRI ||
|
||||
ftdmspan->trunk_type == FTDM_TRUNK_BRI_PTMP) {
|
||||
|
||||
ftdm_status_t cpy_calling_num_from_sngisdn(ftdm_caller_data_t *ftdm, CgPtyNmb *cgPtyNmb)
|
||||
for(i=1; i<=ftdmspan->chan_count; i++) {
|
||||
ftdm_log_chan(ftdmspan->channels[i], FTDM_LOG_DEBUG, "Setting availability rate to:%d\n", avail);
|
||||
ftdmspan->channels[i]->availability_rate = avail;
|
||||
}
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t cpy_calling_num_from_stack(ftdm_caller_data_t *ftdm, CgPtyNmb *cgPtyNmb)
|
||||
{
|
||||
if (cgPtyNmb->eh.pres != PRSNT_NODEF) {
|
||||
return FTDM_FAIL;
|
||||
|
@ -132,7 +173,7 @@ ftdm_status_t cpy_calling_num_from_sngisdn(ftdm_caller_data_t *ftdm, CgPtyNmb *c
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t cpy_called_num_from_sngisdn(ftdm_caller_data_t *ftdm, CdPtyNmb *cdPtyNmb)
|
||||
ftdm_status_t cpy_called_num_from_stack(ftdm_caller_data_t *ftdm, CdPtyNmb *cdPtyNmb)
|
||||
{
|
||||
if (cdPtyNmb->eh.pres != PRSNT_NODEF) {
|
||||
return FTDM_FAIL;
|
||||
|
@ -147,12 +188,14 @@ ftdm_status_t cpy_called_num_from_sngisdn(ftdm_caller_data_t *ftdm, CdPtyNmb *cd
|
|||
}
|
||||
|
||||
if (cdPtyNmb->nmbDigits.pres == PRSNT_NODEF) {
|
||||
ftdm_copy_string(ftdm->dnis.digits, (const char*)cdPtyNmb->nmbDigits.val, cdPtyNmb->nmbDigits.len+1);
|
||||
unsigned i = strlen(ftdm->dnis.digits);
|
||||
|
||||
ftdm_copy_string(&ftdm->dnis.digits[i], (const char*)cdPtyNmb->nmbDigits.val, cdPtyNmb->nmbDigits.len+1);
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t cpy_redir_num_from_sngisdn(ftdm_caller_data_t *ftdm, RedirNmb *redirNmb)
|
||||
ftdm_status_t cpy_redir_num_from_stack(ftdm_caller_data_t *ftdm, RedirNmb *redirNmb)
|
||||
{
|
||||
if (redirNmb->eh.pres != PRSNT_NODEF) {
|
||||
return FTDM_FAIL;
|
||||
|
@ -172,17 +215,20 @@ ftdm_status_t cpy_redir_num_from_sngisdn(ftdm_caller_data_t *ftdm, RedirNmb *red
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t cpy_calling_name_from_sngisdn(ftdm_caller_data_t *ftdm, ConEvnt *conEvnt)
|
||||
ftdm_status_t cpy_calling_name_from_stack(ftdm_caller_data_t *ftdm, Display *display)
|
||||
{
|
||||
if (conEvnt->display.eh.pres && conEvnt->display.dispInfo.pres == PRSNT_NODEF) {
|
||||
ftdm_copy_string(ftdm->cid_name, (const char*)conEvnt->display.dispInfo.val, conEvnt->display.dispInfo.len+1);
|
||||
if (display->eh.pres != PRSNT_NODEF) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
/* TODO check if caller name is contained in a Facility IE */
|
||||
if (display->dispInfo.pres != PRSNT_NODEF) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
ftdm_copy_string(ftdm->cid_name, (const char*)display->dispInfo.val, display->dispInfo.len+1);
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t cpy_calling_num_to_sngisdn(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t *ftdm)
|
||||
ftdm_status_t cpy_calling_num_from_user(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t *ftdm)
|
||||
{
|
||||
uint8_t len = strlen(ftdm->cid_num.digits);
|
||||
if (!len) {
|
||||
|
@ -210,7 +256,7 @@ ftdm_status_t cpy_calling_num_to_sngisdn(CgPtyNmb *cgPtyNmb, ftdm_caller_data_t
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t cpy_called_num_to_sngisdn(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t *ftdm)
|
||||
ftdm_status_t cpy_called_num_from_user(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t *ftdm)
|
||||
{
|
||||
uint8_t len = strlen(ftdm->dnis.digits);
|
||||
if (!len) {
|
||||
|
@ -219,19 +265,28 @@ ftdm_status_t cpy_called_num_to_sngisdn(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t *
|
|||
cdPtyNmb->eh.pres = PRSNT_NODEF;
|
||||
|
||||
cdPtyNmb->nmbPlanId.pres = PRSNT_NODEF;
|
||||
cdPtyNmb->nmbPlanId.val = ftdm->dnis.plan;
|
||||
|
||||
if (ftdm->dnis.plan == FTDM_NPI_INVALID) {
|
||||
cdPtyNmb->nmbPlanId.val = FTDM_NPI_UNKNOWN;
|
||||
} else {
|
||||
cdPtyNmb->nmbPlanId.val = ftdm->dnis.plan;
|
||||
}
|
||||
|
||||
cdPtyNmb->typeNmb0.pres = PRSNT_NODEF;
|
||||
cdPtyNmb->typeNmb0.val = ftdm->dnis.type;
|
||||
if (ftdm->dnis.type == FTDM_TON_INVALID) {
|
||||
cdPtyNmb->typeNmb0.val = FTDM_TON_UNKNOWN;
|
||||
} else {
|
||||
cdPtyNmb->typeNmb0.val = ftdm->dnis.type;
|
||||
}
|
||||
|
||||
cdPtyNmb->nmbDigits.pres = PRSNT_NODEF;
|
||||
cdPtyNmb->nmbDigits.len = len;
|
||||
|
||||
|
||||
memcpy(cdPtyNmb->nmbDigits.val, ftdm->dnis.digits, len);
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t cpy_redir_num_to_sngisdn(RedirNmb *redirNmb, ftdm_caller_data_t *ftdm)
|
||||
ftdm_status_t cpy_redir_num_from_user(RedirNmb *redirNmb, ftdm_caller_data_t *ftdm)
|
||||
{
|
||||
uint8_t len = strlen(ftdm->rdnis.digits);
|
||||
if (!len) {
|
||||
|
@ -241,10 +296,18 @@ ftdm_status_t cpy_redir_num_to_sngisdn(RedirNmb *redirNmb, ftdm_caller_data_t *f
|
|||
redirNmb->eh.pres = PRSNT_NODEF;
|
||||
|
||||
redirNmb->nmbPlanId.pres = PRSNT_NODEF;
|
||||
redirNmb->nmbPlanId.val = ftdm->rdnis.plan;
|
||||
if (ftdm->rdnis.plan == FTDM_NPI_INVALID) {
|
||||
redirNmb->nmbPlanId.val = FTDM_NPI_UNKNOWN;
|
||||
} else {
|
||||
redirNmb->nmbPlanId.val = ftdm->rdnis.plan;
|
||||
}
|
||||
|
||||
redirNmb->typeNmb.pres = PRSNT_NODEF;
|
||||
redirNmb->typeNmb.val = ftdm->rdnis.type;
|
||||
if (ftdm->rdnis.type == FTDM_TON_INVALID) {
|
||||
redirNmb->typeNmb.val = FTDM_TON_UNKNOWN;
|
||||
} else {
|
||||
redirNmb->typeNmb.val = ftdm->rdnis.type;
|
||||
}
|
||||
|
||||
redirNmb->nmbDigits.pres = PRSNT_NODEF;
|
||||
redirNmb->nmbDigits.len = len;
|
||||
|
@ -255,7 +318,7 @@ ftdm_status_t cpy_redir_num_to_sngisdn(RedirNmb *redirNmb, ftdm_caller_data_t *f
|
|||
}
|
||||
|
||||
|
||||
ftdm_status_t cpy_calling_name_to_sngisdn(ConEvnt *conEvnt, ftdm_channel_t *ftdmchan)
|
||||
ftdm_status_t cpy_calling_name_from_user(ConEvnt *conEvnt, ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
uint8_t len;
|
||||
ftdm_caller_data_t *ftdm = &ftdmchan->caller_data;
|
||||
|
@ -308,28 +371,93 @@ ftdm_status_t cpy_calling_name_to_sngisdn(ConEvnt *conEvnt, ftdm_channel_t *ftdm
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ftdm_status_t check_for_state_change(ftdm_channel_t *ftdmchan)
|
||||
void sngisdn_delayed_release(void* p_sngisdn_info)
|
||||
{
|
||||
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info;
|
||||
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
#if 0
|
||||
ftdm_log_chan_msg(ftdmchan, "Checking for pending state change\n");
|
||||
#endif
|
||||
/* check to see if there are any pending state changes on the channel and give them a sec to happen*/
|
||||
ftdm_wait_for_flag_cleared(ftdmchan, FTDM_CHANNEL_STATE_CHANGE, 5000);
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
|
||||
if (ftdm_test_flag(sngisdn_info, FLAG_DELAYED_REL)) {
|
||||
ftdm_clear_flag(sngisdn_info, FLAG_DELAYED_REL);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending delayed RELEASE (suId:%d suInstId:%u spInstId:%u)\n",
|
||||
signal_data->cc_id, sngisdn_info->glare.spInstId, sngisdn_info->glare.suInstId);
|
||||
|
||||
/* check the flag to confirm it is clear now */
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
|
||||
/* the flag is still up...so we have a problem */
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "FTDM_CHANNEL_STATE_CHANGE set for over 500ms\n");
|
||||
sngisdn_snd_release(ftdmchan, 1);
|
||||
clear_call_glare_data(sngisdn_info);
|
||||
} else {
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Call was already released (suId:%d suInstId:%u spInstId:%u)\n",
|
||||
signal_data->cc_id, sngisdn_info->glare.spInstId, sngisdn_info->glare.suInstId);
|
||||
}
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
/* move the state of the channel to RESTART to force a reset */
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
|
||||
void sngisdn_delayed_connect(void* p_sngisdn_info)
|
||||
{
|
||||
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info;
|
||||
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Sending delayed CONNECT (suId:%d suInstId:%u spInstId:%u)\n",
|
||||
signal_data->cc_id, sngisdn_info->glare.spInstId, sngisdn_info->glare.suInstId);
|
||||
|
||||
sngisdn_snd_connect(ftdmchan);
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
void sngisdn_delayed_disconnect(void* p_sngisdn_info)
|
||||
{
|
||||
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info;
|
||||
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
ftdm_status_t sngisdn_check_free_ids(void)
|
||||
{
|
||||
unsigned i;
|
||||
unsigned j;
|
||||
ftdm_log(FTDM_LOG_INFO, "Checking suInstId's\n");
|
||||
for(j=1;j<=MAX_VARIANTS;j++) {
|
||||
if (g_sngisdn_data.ccs[j].config_done) {
|
||||
for(i=1;i<MAX_INSTID;i++) {
|
||||
if (g_sngisdn_data.ccs[j].active_suInstIds[i] != NULL) {
|
||||
ftdm_log(FTDM_LOG_INFO, "suId:%u suInstId:%u is not free\n", j, i);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ftdm_log(FTDM_LOG_INFO, "Checking spInstId's\n");
|
||||
for(j=1;j<=MAX_VARIANTS;j++) {
|
||||
if (g_sngisdn_data.ccs[j].config_done) {
|
||||
for(i=1;i<MAX_INSTID;i++) {
|
||||
if (g_sngisdn_data.ccs[j].active_spInstIds[i] != NULL) {
|
||||
ftdm_log(FTDM_LOG_INFO, "suId:%u spInstId:%u is not free\n", j, i);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ftdm_log(FTDM_LOG_INFO, "Checking ID's done\n");
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
void get_memory_info(void)
|
||||
|
@ -339,6 +467,73 @@ void get_memory_info(void)
|
|||
return;
|
||||
}
|
||||
|
||||
uint8_t sngisdn_get_infoTranCap_from_stack(ftdm_bearer_cap_t bearer_capability)
|
||||
{
|
||||
switch(bearer_capability) {
|
||||
case FTDM_BEARER_CAP_SPEECH:
|
||||
return IN_ITC_SPEECH;
|
||||
|
||||
case FTDM_BEARER_CAP_64K_UNRESTRICTED:
|
||||
return IN_ITC_UNRDIG;
|
||||
|
||||
case FTDM_BEARER_CAP_3_1KHZ_AUDIO:
|
||||
return IN_ITC_A31KHZ;
|
||||
|
||||
/* Do not put a default case here, so we can see compile warnings if we have unhandled cases */
|
||||
}
|
||||
return FTDM_BEARER_CAP_SPEECH;
|
||||
}
|
||||
|
||||
uint8_t sngisdn_get_usrInfoLyr1Prot_from_stack(ftdm_user_layer1_prot_t layer1_prot)
|
||||
{
|
||||
switch(layer1_prot) {
|
||||
case FTDM_USER_LAYER1_PROT_V110:
|
||||
return IN_UIL1_CCITTV110;
|
||||
|
||||
case FTDM_USER_LAYER1_PROT_ULAW:
|
||||
return IN_UIL1_G711ULAW;
|
||||
|
||||
case FTDM_USER_LAYER1_PROT_ALAW:
|
||||
return IN_UIL1_G711ALAW;
|
||||
|
||||
/* Do not put a default case here, so we can see compile warnings if we have unhandled cases */
|
||||
}
|
||||
return IN_UIL1_G711ULAW;
|
||||
}
|
||||
|
||||
ftdm_bearer_cap_t sngisdn_get_infoTranCap_from_user(uint8_t bearer_capability)
|
||||
{
|
||||
switch(bearer_capability) {
|
||||
case IN_ITC_SPEECH:
|
||||
return FTDM_BEARER_CAP_SPEECH;
|
||||
|
||||
case IN_ITC_UNRDIG:
|
||||
return FTDM_BEARER_CAP_64K_UNRESTRICTED;
|
||||
|
||||
case IN_ITC_A31KHZ:
|
||||
return FTDM_BEARER_CAP_3_1KHZ_AUDIO;
|
||||
|
||||
default:
|
||||
return FTDM_BEARER_CAP_SPEECH;
|
||||
}
|
||||
return FTDM_BEARER_CAP_SPEECH;
|
||||
}
|
||||
|
||||
ftdm_user_layer1_prot_t sngisdn_get_usrInfoLyr1Prot_from_user(uint8_t layer1_prot)
|
||||
{
|
||||
switch(layer1_prot) {
|
||||
case IN_UIL1_CCITTV110:
|
||||
return FTDM_USER_LAYER1_PROT_V110;
|
||||
case IN_UIL1_G711ULAW:
|
||||
return FTDM_USER_LAYER1_PROT_ULAW;
|
||||
case IN_UIL1_G711ALAW:
|
||||
return IN_UIL1_G711ALAW;
|
||||
default:
|
||||
return FTDM_USER_LAYER1_PROT_ULAW;
|
||||
}
|
||||
return FTDM_USER_LAYER1_PROT_ULAW;
|
||||
}
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
|
|
|
@ -205,7 +205,7 @@ void sngisdn_trace_q931(char* str, uint8_t* data, uint32_t data_len)
|
|||
i=i+1;
|
||||
c=c+1;
|
||||
}
|
||||
str_len += sprintf(&str[str_len], " (%s side)\n", callRefFlag?"Destination":"Origination");
|
||||
str_len += sprintf(&str[str_len], " (%s side)\n", callRefFlag?"Destination":"Originating");
|
||||
|
||||
/* Decode message type */
|
||||
str_len+= sprintf(&str[str_len], " Type:%s (0x%x)\n", get_code_2_str((int)(data[2+lenCallRef] & 0xFF), dcodQ931MsgTypeTable), (int)(data[2+lenCallRef] & 0xFF));
|
||||
|
@ -337,7 +337,7 @@ uint32_t sngisdn_decode_ie(char *str, uint32_t *str_len, uint8_t current_codeset
|
|||
}
|
||||
|
||||
if (numberMap) {
|
||||
*str_len+= sprintf(&str[*str_len], " MAP\n");
|
||||
*str_len+= sprintf(&str[*str_len], " MAP:%s ", get_code_2_str(infoChannelSelection, dcodQ931InfoChannelSelTable));
|
||||
} else {
|
||||
*str_len+= sprintf(&str[*str_len], "No:%d ", channelNo);
|
||||
}
|
||||
|
@ -608,6 +608,9 @@ uint32_t sngisdn_decode_ie(char *str, uint32_t *str_len, uint8_t current_codeset
|
|||
break;
|
||||
case PROT_Q931_IE_SENDING_COMPLETE:
|
||||
/* No need to decode sending complete IE, as no additional info is available except that sending is done */
|
||||
/* This is a single octet IE */
|
||||
*str_len+= sprintf(&str[*str_len], "\n");
|
||||
return 0;
|
||||
break;
|
||||
case PROT_Q931_IE_CALLED_PARTY_SUBADDRESS:
|
||||
case PROT_Q931_IE_REDIRECTION_NUMBER:
|
||||
|
|
|
@ -373,6 +373,14 @@ struct code2str dcodQ931ScreeningTable[] = {
|
|||
{-1, "invalid" },
|
||||
};
|
||||
|
||||
struct code2str dcodQ931InfoChannelSelTable[] = {
|
||||
{0, "No Chan"},
|
||||
{1, "B1"},
|
||||
{2, "B2"},
|
||||
{3, "Any Chan"},
|
||||
{-1, "invalid" },
|
||||
};
|
||||
|
||||
struct code2str dcodQ931ReasonTable[] = {
|
||||
{0x0, "Unknown"},
|
||||
{0x1, "Call forwarding busy"},
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -42,681 +42,235 @@
|
|||
/******************************************************************************/
|
||||
|
||||
/* PROTOTYPES *****************************************************************/
|
||||
void handle_sng_log(uint8_t level, char *fmt,...);
|
||||
void handle_sng_alarm(sng_alrm_t t_alarm);
|
||||
|
||||
static void handle_entsi_alarm(sng_alrm_t t_alarm);
|
||||
|
||||
int ft_to_sngss7_cfg(void);
|
||||
int ft_to_sngss7_activate_all(void);
|
||||
|
||||
static int ftmod_ss7_general_configuration(void);
|
||||
|
||||
static int ftmod_ss7_configure_mtp1_link(int id);
|
||||
|
||||
static int ftmod_ss7_configure_mtp2_link(int id);
|
||||
|
||||
static int ftmod_ss7_configure_mtp3_link(int id);
|
||||
static int ftmod_ss7_configure_mtp3_linkset(int id);
|
||||
static int ftmod_ss7_configure_mtp3_route(int id);
|
||||
static int ftmod_ss7_configure_mtp3_isup(int id);
|
||||
|
||||
static int ftmod_ss7_configure_isup_mtp3(int id);
|
||||
static int ftmod_ss7_configure_isup_interface(int id);
|
||||
static int ftmod_ss7_configure_isup_circuit(int id);
|
||||
static int ftmod_ss7_configure_isup_cc(int id);
|
||||
|
||||
static int ftmod_ss7_configure_cc_isup(int id);
|
||||
static int ftmod_ss7_enable_isap(int suId);
|
||||
static int ftmod_ss7_enable_nsap(int suId);
|
||||
static int ftmod_ss7_enable_mtpLinkSet(int lnkSetId);
|
||||
|
||||
int ftmod_ss7_inhibit_mtplink(uint32_t id);
|
||||
int ftmod_ss7_uninhibit_mtplink(uint32_t id);
|
||||
/******************************************************************************/
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
/* LOGGIGING ******************************************************************/
|
||||
void handle_sng_log(uint8_t level, char *fmt,...)
|
||||
{
|
||||
char *data;
|
||||
int ret;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
ret = vasprintf(&data, fmt, ap);
|
||||
if (ret == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (level) {
|
||||
/**************************************************************************/
|
||||
case SNG_LOGLEVEL_DEBUG:
|
||||
ftdm_log(FTDM_LOG_DEBUG, "sng_ss7->%s", data);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case SNG_LOGLEVEL_WARN:
|
||||
ftdm_log(FTDM_LOG_INFO, "sng_ss7->%s", data);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case SNG_LOGLEVEL_INFO:
|
||||
ftdm_log(FTDM_LOG_INFO, "sng_ss7->%s", data);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case SNG_LOGLEVEL_STATS:
|
||||
ftdm_log(FTDM_LOG_INFO, "sng_ss7->%s", data);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case SNG_LOGLEVEL_ERROR:
|
||||
ftdm_log(FTDM_LOG_ERROR, "sng_ss7->%s", data);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case SNG_LOGLEVEL_CRIT:
|
||||
printf("%s",data);
|
||||
/*ftdm_log(FTDM_LOG_CRIT, "sng_ss7->%s", data);*/
|
||||
break;
|
||||
/**************************************************************************/
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_INFO, "sng_ss7->%s", data);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void handle_sng_alarm(sng_alrm_t t_alarm)
|
||||
{
|
||||
|
||||
switch (t_alarm.entity) {
|
||||
/**************************************************************************/
|
||||
case (ENTL1):
|
||||
ftdm_log(FTDM_LOG_WARNING,"[SNG-MTP1] %s : %s : %s \n",
|
||||
DECODE_LL1_EVENT(t_alarm.event),
|
||||
DECODE_LL1_CAUSE(t_alarm.cause),
|
||||
DECODE_LL1_PARM(t_alarm.eventParm[0]));
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (ENTSD):
|
||||
ftdm_log(FTDM_LOG_WARNING,"[SNG-MTP2] %s : %s \n",
|
||||
DECODE_LSD_EVENT(t_alarm.event),
|
||||
DECODE_LSD_CAUSE(t_alarm.cause));
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (ENTSN):
|
||||
ftdm_log(FTDM_LOG_WARNING,"[SNG-MTP3] %s on %d: %s \n",
|
||||
DECODE_LSN_EVENT(t_alarm.event),
|
||||
t_alarm.id,
|
||||
DECODE_LSN_CAUSE(t_alarm.cause));
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (ENTSI):
|
||||
handle_entsi_alarm(t_alarm);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (ENTCC):
|
||||
ftdm_log(FTDM_LOG_DEBUG,"[SNG-CC] %s : %s \n",
|
||||
DECODE_LCC_EVENT(t_alarm.event),
|
||||
DECODE_LCC_CAUSE(t_alarm.cause));
|
||||
break;
|
||||
/**************************************************************************/
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_WARNING,"Received alarm from unknown entity");
|
||||
break;
|
||||
/**************************************************************************/
|
||||
} /* switch (t_alarm.entity) */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static void handle_entsi_alarm(sng_alrm_t alarm)
|
||||
{
|
||||
|
||||
switch (alarm.event) {
|
||||
/**************************************************************************/
|
||||
case (LCM_EVENT_TIMEOUT):
|
||||
/* this event always has the circuit value embedded */
|
||||
SS7_WARN("[ISUP] Timer %d expired on CIC %d\n",
|
||||
alarm.eventParm[8],
|
||||
g_ftdm_sngss7_data.cfg.isupCircuit[alarm.eventParm[0]].cic);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (LSI_EVENT_REMOTE):
|
||||
SS7_WARN("[ISUP] %s received on CIC %d\n",
|
||||
DECODE_LSI_CAUSE(alarm.cause),
|
||||
g_ftdm_sngss7_data.cfg.isupCircuit[alarm.eventParm[0]].cic);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (LSI_EVENT_LOCAL):
|
||||
SS7_WARN("[ISUP] %s transmitted on CIC %d\n",
|
||||
DECODE_LSI_CAUSE(alarm.cause),
|
||||
g_ftdm_sngss7_data.cfg.isupCircuit[alarm.eventParm[0]].cic);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (LSI_EVENT_MTP):
|
||||
SS7_WARN("[ISUP] Received %s on %d\n",
|
||||
DECODE_LSI_CAUSE(alarm.cause),
|
||||
g_ftdm_sngss7_data.cfg.mtp3_isup[alarm.eventParm[2]].id);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (LCM_EVENT_UI_INV_EVT):
|
||||
switch (alarm.cause) {
|
||||
/**********************************************************************/
|
||||
case (LSI_CAUSE_INV_CIRCUIT):
|
||||
SS7_WARN("[ISUP] Invalid circuit = %d (CIC = %d)\n",
|
||||
alarm.eventParm[0],
|
||||
g_ftdm_sngss7_data.cfg.isupCircuit[alarm.eventParm[0]].cic);
|
||||
break;
|
||||
/**********************************************************************/
|
||||
}
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (LCM_EVENT_LI_INV_EVT):
|
||||
switch (alarm.cause) {
|
||||
/**********************************************************************/
|
||||
case (LCM_CAUSE_INV_SAP):
|
||||
SS7_WARN("[ISUP] Invalid spId = %d\n",
|
||||
alarm.eventParm[3]);
|
||||
break;
|
||||
/**********************************************************************/
|
||||
}
|
||||
break;
|
||||
/**************************************************************************/
|
||||
default:
|
||||
SS7_WARN("[ISUP] %s : %s \n", DECODE_LSI_EVENT(alarm.event), DECODE_LSI_CAUSE(alarm.cause));
|
||||
break;
|
||||
/**************************************************************************/
|
||||
} /* switch (alarm.event) */
|
||||
return;
|
||||
}
|
||||
|
||||
/* ACTIVATION *****************************************************************/
|
||||
int ft_to_sngss7_activate_all(void)
|
||||
{
|
||||
sng_isup_cc_t *cc_isup = NULL;
|
||||
sng_mtp3_isup_t *isup_mtp3 = NULL;
|
||||
sng_mtp3LinkSet_t *mtp3_linkset = NULL;
|
||||
int x;
|
||||
int x;
|
||||
|
||||
/* CC to ISUP *************************************************************/
|
||||
x = 1;
|
||||
cc_isup = &g_ftdm_sngss7_data.cfg.isup_cc[x];
|
||||
while (cc_isup->id != 0) {
|
||||
if (sngss7_test_flag(cc_isup, SNGSS7_FLAG_ACTIVE)) {
|
||||
SS7_DEBUG("CC-ISUP interface already active = %d\n", cc_isup->id);
|
||||
} else {
|
||||
if (sng_activate_cc_isup_inf(cc_isup->ccId)) {
|
||||
SS7_ERROR("Failed to activate CC-ISUP = %d\n",cc_isup->id);
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
SS7_INFO("Started CC-ISUP interface = %d\n", cc_isup->id);
|
||||
sngss7_set_flag(cc_isup, SNGSS7_FLAG_ACTIVE);
|
||||
}
|
||||
} /* if (sngss7_test_flag(cc_isup, SNGSS7_FLAG_ACTIVE) */
|
||||
x = 1;
|
||||
while (g_ftdm_sngss7_data.cfg.isap[x].id != 0) {
|
||||
/* check if this link has already been actived */
|
||||
if (!(g_ftdm_sngss7_data.cfg.isap[x].flags & ACTIVE)) {
|
||||
|
||||
x++;
|
||||
cc_isup = &g_ftdm_sngss7_data.cfg.isup_cc[x];
|
||||
} /* while (cc_isup->id != 0) */
|
||||
if (ftmod_ss7_enable_isap(x)) {
|
||||
SS7_CRITICAL("ISAP %d Enable: NOT OK\n", x);
|
||||
SS7_ASSERT;
|
||||
} else {
|
||||
SS7_INFO("ISAP %d Enable: OK\n", x);
|
||||
}
|
||||
|
||||
/* ISUP - MTP3 ************************************************************/
|
||||
x = 1;
|
||||
isup_mtp3 = &g_ftdm_sngss7_data.cfg.mtp3_isup[x];
|
||||
while (isup_mtp3->id != 0) {
|
||||
if (sngss7_test_flag(isup_mtp3, SNGSS7_FLAG_ACTIVE)) {
|
||||
SS7_DEBUG("ISUP-MTP3 interface already active = %d\n", isup_mtp3->id);
|
||||
} else {
|
||||
if (sng_activate_isup_mtp3_inf(isup_mtp3->id)) {
|
||||
SS7_ERROR("Failed to activate ISUP-MTP3 = %d\n",isup_mtp3->id);
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
SS7_INFO("Started ISUP-MTP3interface = %d\n", isup_mtp3->id);
|
||||
sngss7_set_flag(isup_mtp3, SNGSS7_FLAG_ACTIVE);
|
||||
}
|
||||
} /* if (sngss7_test_flag(isup_mtp3, SNGSS7_FLAG_ACTIVE) */
|
||||
/* set the ACTIVE flag */
|
||||
g_ftdm_sngss7_data.cfg.isap[x].flags |= ACTIVE;
|
||||
} /* if !ACTIVE */
|
||||
|
||||
x++;
|
||||
} /* while (g_ftdm_sngss7_data.cfg.isap[x].id != 0) */
|
||||
|
||||
x++;
|
||||
isup_mtp3 = &g_ftdm_sngss7_data.cfg.mtp3_isup[x];
|
||||
} /* while (isup_mtp3->id != 0) */
|
||||
x = 1;
|
||||
while (g_ftdm_sngss7_data.cfg.nsap[x].id != 0) {
|
||||
/* check if this link has already been actived */
|
||||
if (!(g_ftdm_sngss7_data.cfg.nsap[x].flags & ACTIVE)) {
|
||||
|
||||
/* MTP3 Linkset (MTP3 - MTP2 - MTP1) **************************************/
|
||||
x = 1;
|
||||
mtp3_linkset = &g_ftdm_sngss7_data.cfg.mtp3LinkSet[x];
|
||||
while (mtp3_linkset->id != 0) {
|
||||
if (sngss7_test_flag(mtp3_linkset, SNGSS7_FLAG_ACTIVE)) {
|
||||
SS7_DEBUG("MTP3 Linkset already active = %s\n", mtp3_linkset->name);
|
||||
} else {
|
||||
if (sng_activate_mtp3_linkset(mtp3_linkset->id)) {
|
||||
SS7_ERROR("Failed to activate MTP3 Linkset = %s\n",mtp3_linkset->name);
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
SS7_INFO("Started MTP3 Linkset = %s\n", mtp3_linkset->name);
|
||||
sngss7_set_flag(mtp3_linkset, SNGSS7_FLAG_ACTIVE);
|
||||
}
|
||||
} /* if (sngss7_test_flag(mtp3_linkset, SNGSS7_FLAG_ACTIVE) */
|
||||
if (ftmod_ss7_enable_nsap(x)) {
|
||||
SS7_CRITICAL("NSAP %d Enable: NOT OK\n", x);
|
||||
SS7_ASSERT;
|
||||
} else {
|
||||
SS7_INFO("NSAP %d Enable: OK\n", x);
|
||||
}
|
||||
|
||||
x++;
|
||||
mtp3_linkset = &g_ftdm_sngss7_data.cfg.mtp3LinkSet[x];
|
||||
} /* while (mtp3_linkset->id != 0) */
|
||||
/* set the ACTIVE flag */
|
||||
g_ftdm_sngss7_data.cfg.nsap[x].flags |= ACTIVE;
|
||||
} /* if !ACTIVE */
|
||||
|
||||
x++;
|
||||
} /* while (g_ftdm_sngss7_data.cfg.nsap[x].id != 0) */
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
x = 1;
|
||||
while (g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) {
|
||||
/* check if this link has already been actived */
|
||||
if (!(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags & ACTIVE)) {
|
||||
|
||||
/* CONFIGURATION **************************************************************/
|
||||
int ft_to_sngss7_cfg(void)
|
||||
{
|
||||
sng_mtp1Link_t *mtp1_link = NULL;
|
||||
sng_mtp2Link_t *mtp2_link = NULL;
|
||||
sng_mtp3Link_t *mtp3_link = NULL;
|
||||
sng_mtp3LinkSet_t *mtp3_linkset = NULL;
|
||||
sng_mtp3Route_t *mtp3_route = NULL;
|
||||
sng_mtp3_isup_t *mtp3_isup = NULL;
|
||||
sng_mtp3_isup_t *isup_mtp3 = NULL;
|
||||
sng_isupInterface_t *isup_interface = NULL;
|
||||
sng_isupCircuit_t *isup_circuit = NULL;
|
||||
sng_isup_cc_t *isup_cc = NULL;
|
||||
sng_isup_cc_t *cc_isup = NULL;
|
||||
int x;
|
||||
if (ftmod_ss7_enable_mtpLinkSet(x)) {
|
||||
SS7_CRITICAL("LinkSet \"%s\" Enable: NOT OK\n", g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name);
|
||||
SS7_ASSERT;
|
||||
} else {
|
||||
SS7_INFO("LinkSet \"%s\" Enable: OK\n", g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name);
|
||||
}
|
||||
|
||||
SS7_DEBUG("Starting LibSngSS7 configuration...\n");
|
||||
/* set the ACTIVE flag */
|
||||
g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags |= ACTIVE;
|
||||
} /* if !ACTIVE */
|
||||
|
||||
x++;
|
||||
} /* while (g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) */
|
||||
|
||||
if (g_ftdm_sngss7_data.gen_config_done == 0) {
|
||||
/* perform general configuration */
|
||||
if(ftmod_ss7_general_configuration()) {
|
||||
SS7_ERROR("Failed to run general configuration!\n");
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
SS7_INFO("General Configuration was successful\n");
|
||||
g_ftdm_sngss7_data.gen_config_done = 1;
|
||||
}
|
||||
} else {
|
||||
SS7_DEBUG("General configuration already done.\n");
|
||||
}
|
||||
|
||||
/* MTP1 *******************************************************************/
|
||||
x=1;
|
||||
mtp1_link = &g_ftdm_sngss7_data.cfg.mtp1Link[x];
|
||||
while (mtp1_link->id != 0) {
|
||||
|
||||
if (sngss7_test_flag(mtp1_link, SNGSS7_FLAG_CONFIGURED)) {
|
||||
SS7_DEBUG("MTP1 Link already configured = %s\n",mtp1_link->name);
|
||||
} else {
|
||||
if (ftmod_ss7_configure_mtp1_link(x)) {
|
||||
SS7_ERROR("Failed to configure MTP1 link = %s\n!", mtp1_link->name);
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
SS7_INFO("Successfully configured MTP1 link = %s\n", mtp1_link->name);
|
||||
sngss7_set_flag(mtp1_link, SNGSS7_FLAG_CONFIGURED);
|
||||
}
|
||||
}
|
||||
|
||||
/* next link */
|
||||
x++;
|
||||
mtp1_link = &g_ftdm_sngss7_data.cfg.mtp1Link[x];
|
||||
} /* while (g_ftdm_sngss7_data.cfg.mtp1Link[x]->id != 0) */
|
||||
|
||||
/* MTP2 *******************************************************************/
|
||||
x=1;
|
||||
mtp2_link = &g_ftdm_sngss7_data.cfg.mtp2Link[x];
|
||||
while (mtp2_link->id != 0) {
|
||||
if (sngss7_test_flag(mtp2_link, SNGSS7_FLAG_CONFIGURED)) {
|
||||
SS7_DEBUG("MTP2 Link already configured = %s\n",mtp2_link->name);
|
||||
} else {
|
||||
if (ftmod_ss7_configure_mtp2_link(x)) {
|
||||
SS7_ERROR("Failed to configure MTP2 link = %s\n!", mtp2_link->name);
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
SS7_INFO("Successfully configured MTP2 link = %s\n", mtp2_link->name);
|
||||
sngss7_set_flag(mtp2_link, SNGSS7_FLAG_CONFIGURED);
|
||||
}
|
||||
}
|
||||
/* next link */
|
||||
x++;
|
||||
mtp2_link = &g_ftdm_sngss7_data.cfg.mtp2Link[x];
|
||||
} /* while (g_ftdm_sngss7_data.cfg.mtp2Link[x]->id != 0) */
|
||||
|
||||
/* MTP3 *******************************************************************/
|
||||
x=1;
|
||||
mtp3_link = &g_ftdm_sngss7_data.cfg.mtp3Link[x];
|
||||
while (mtp3_link->id != 0) {
|
||||
if (sngss7_test_flag(mtp3_link, SNGSS7_FLAG_CONFIGURED)) {
|
||||
SS7_DEBUG("MTP3 Link already configured = %s\n", mtp3_link->name);
|
||||
} else {
|
||||
if (ftmod_ss7_configure_mtp3_link(x)) {
|
||||
SS7_ERROR("Failed to configure MTP3 link = %s\n!", mtp3_link->name);
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
SS7_INFO("Successfully configured MTP3 link = %s\n", mtp3_link->name);
|
||||
sngss7_set_flag(mtp3_link, SNGSS7_FLAG_CONFIGURED);
|
||||
}
|
||||
}
|
||||
/* next link */
|
||||
x++;
|
||||
mtp3_link = &g_ftdm_sngss7_data.cfg.mtp3Link[x];
|
||||
} /* while (g_ftdm_sngss7_data.cfg.mtp3Link[x]->id != 0) */
|
||||
|
||||
x=1;
|
||||
mtp3_linkset = &g_ftdm_sngss7_data.cfg.mtp3LinkSet[x];
|
||||
while (mtp3_linkset->id != 0) {
|
||||
if (sngss7_test_flag(mtp3_linkset, SNGSS7_FLAG_CONFIGURED)) {
|
||||
SS7_DEBUG("MTP3 LinkSet already configured = %s\n", mtp3_linkset->name);
|
||||
} else {
|
||||
if (ftmod_ss7_configure_mtp3_linkset(x)) {
|
||||
SS7_ERROR("Failed to configure MTP3 link = %s\n!", mtp3_linkset->name);
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
SS7_INFO("Successfully configured MTP3 link = %s\n", mtp3_linkset->name);
|
||||
sngss7_set_flag(mtp3_linkset, SNGSS7_FLAG_CONFIGURED);
|
||||
}
|
||||
}
|
||||
/* next link */
|
||||
x++;
|
||||
mtp3_linkset = &g_ftdm_sngss7_data.cfg.mtp3LinkSet[x];
|
||||
} /* while (g_ftdm_sngss7_data.cfg.mtp1Link[x]->id != 0) */
|
||||
|
||||
x=1;
|
||||
mtp3_route = &g_ftdm_sngss7_data.cfg.mtp3Route[x];
|
||||
while (mtp3_route->id != 0) {
|
||||
if (sngss7_test_flag(mtp3_route, SNGSS7_FLAG_CONFIGURED)) {
|
||||
SS7_DEBUG("MTP3 Route already configured = %s\n", mtp3_route->name);
|
||||
} else {
|
||||
if (ftmod_ss7_configure_mtp3_route(x)) {
|
||||
SS7_ERROR("Failed to configure MTP3 route = %s\n!", mtp3_route->name);
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
SS7_INFO("Successfully configured MTP3 route = %s\n", mtp3_route->name);
|
||||
sngss7_set_flag(mtp3_route, SNGSS7_FLAG_CONFIGURED);
|
||||
}
|
||||
}
|
||||
/* next link */
|
||||
x++;
|
||||
mtp3_route = &g_ftdm_sngss7_data.cfg.mtp3Route[x];
|
||||
} /* while (g_ftdm_sngss7_data.cfg.mtp3Route[x]->id != 0) */
|
||||
|
||||
mtp3_route = &g_ftdm_sngss7_data.cfg.mtp3Route[0];
|
||||
if (sngss7_test_flag(mtp3_route, SNGSS7_FLAG_CONFIGURED)) {
|
||||
SS7_DEBUG("MTP3 Self Route already configured\n");
|
||||
} else {
|
||||
if (ftmod_ss7_configure_mtp3_route(0)) {
|
||||
SS7_ERROR("Failed to configure MTP3 Route = SelfRoute\n!");
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
SS7_INFO("Successfully configured MTP3 Route = SelfRoute\n");
|
||||
sngss7_set_flag(mtp3_route, SNGSS7_FLAG_CONFIGURED);
|
||||
}
|
||||
}
|
||||
|
||||
x=1;
|
||||
mtp3_isup = &g_ftdm_sngss7_data.cfg.mtp3_isup[x];
|
||||
while (mtp3_isup->id != 0) {
|
||||
if (sngss7_test_flag(mtp3_isup, SNGSS7_FLAG_CONFIGURED)) {
|
||||
SS7_DEBUG("MTP3-ISUP interface already configured = %d\n", mtp3_isup->id);
|
||||
} else {
|
||||
if (ftmod_ss7_configure_mtp3_isup(x)) {
|
||||
SS7_ERROR("Failed to configure MTP3-ISUP interface = %d\n!", mtp3_isup->id);
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
SS7_INFO("Successfully configured MTP3-ISUP interface = %d\n", mtp3_isup->id);
|
||||
}
|
||||
}
|
||||
/* next link */
|
||||
x++;
|
||||
mtp3_isup = &g_ftdm_sngss7_data.cfg.mtp3_isup[x];
|
||||
} /* while (g_ftdm_sngss7_data.cfg.mtp3_isup[x]->id != 0) */
|
||||
|
||||
/* ISUP *******************************************************************/
|
||||
x=1;
|
||||
isup_mtp3 = &g_ftdm_sngss7_data.cfg.mtp3_isup[x];
|
||||
while (isup_mtp3->id != 0) {
|
||||
if (sngss7_test_flag(isup_mtp3, SNGSS7_FLAG_CONFIGURED)) {
|
||||
SS7_DEBUG("ISUP-MTP3 interface already configured = %d\n", isup_mtp3->id);
|
||||
} else {
|
||||
if (ftmod_ss7_configure_isup_mtp3(x)) {
|
||||
SS7_ERROR("Failed to configure ISUP-MTP3 interface = %d\n!", isup_mtp3->id);
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
SS7_INFO("Successfully configured ISUP-MTP3 interface = %d\n", isup_mtp3->id);
|
||||
sngss7_set_flag(isup_mtp3, SNGSS7_FLAG_CONFIGURED);
|
||||
}
|
||||
}
|
||||
/* next link */
|
||||
x++;
|
||||
isup_mtp3 = &g_ftdm_sngss7_data.cfg.mtp3_isup[x];
|
||||
} /* while (g_ftdm_sngss7_data.cfg.isup_mtp3[x]->id != 0) */
|
||||
|
||||
x=1;
|
||||
isup_cc = &g_ftdm_sngss7_data.cfg.isup_cc[x];
|
||||
while (isup_cc->id != 0) {
|
||||
if (sngss7_test_flag(isup_cc, SNGSS7_FLAG_CONFIGURED)) {
|
||||
SS7_DEBUG("ISUP-CC interface already configured = %d\n", isup_cc->id);
|
||||
} else {
|
||||
if (ftmod_ss7_configure_isup_cc(x)) {
|
||||
SS7_ERROR("Failed to configure ISUP-CC interface = %d\n!", isup_cc->id);
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
SS7_INFO("Successfully configured ISUP-CC interface = %d\n", isup_cc->id);
|
||||
}
|
||||
}
|
||||
/* next link */
|
||||
x++;
|
||||
isup_cc = &g_ftdm_sngss7_data.cfg.isup_cc[x];
|
||||
} /* while (g_ftdm_sngss7_data.cfg.isup_cc[x]->id != 0) */
|
||||
|
||||
x=1;
|
||||
isup_interface = &g_ftdm_sngss7_data.cfg.isupInterface[x];
|
||||
while (isup_interface->id != 0) {
|
||||
if (sngss7_test_flag(isup_interface, SNGSS7_FLAG_CONFIGURED)) {
|
||||
SS7_DEBUG("ISUP interface already configured = %s\n", isup_interface->name);
|
||||
} else {
|
||||
if (ftmod_ss7_configure_isup_interface(x)) {
|
||||
SS7_ERROR("Failed to configure ISUP interface = %s\n", isup_interface->name);
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
SS7_INFO("Successfully configured ISUP interface = %s\n", isup_interface->name);
|
||||
sngss7_set_flag(isup_interface, SNGSS7_FLAG_CONFIGURED);
|
||||
}
|
||||
}
|
||||
/* next link */
|
||||
x++;
|
||||
isup_interface = &g_ftdm_sngss7_data.cfg.isupInterface[x];
|
||||
} /* while (g_ftdm_sngss7_data.cfg.isup_interface[x]->id != 0) */
|
||||
|
||||
x=1;
|
||||
isup_circuit = &g_ftdm_sngss7_data.cfg.isupCircuit[x];
|
||||
while (isup_circuit->id != 0) {
|
||||
if (isup_circuit->cic != 0) {
|
||||
if (sngss7_test_flag(isup_circuit, SNGSS7_FLAG_CONFIGURED)) {
|
||||
SS7_DEBUG("ISUP Circuit already configured = %d\n", isup_circuit->id);
|
||||
} else {
|
||||
if (ftmod_ss7_configure_isup_circuit(x)) {
|
||||
SS7_ERROR("Failed to configure ISUP circuit = %d\n!", isup_circuit->id);
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
SS7_INFO("Successfully configured ISUP circuit = %d\n", isup_circuit->id);
|
||||
sngss7_set_flag(isup_circuit, SNGSS7_FLAG_CONFIGURED);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* next link */
|
||||
x++;
|
||||
isup_circuit = &g_ftdm_sngss7_data.cfg.isupCircuit[x];
|
||||
} /* while (g_ftdm_sngss7_data.cfg.isup_circuit[x]->id != 0) */
|
||||
|
||||
/* CC *********************************************************************/
|
||||
|
||||
x=1;
|
||||
cc_isup = &g_ftdm_sngss7_data.cfg.isup_cc[x];
|
||||
while (cc_isup->id != 0) {
|
||||
if (sngss7_test_flag(cc_isup, SNGSS7_FLAG_CONFIGURED)) {
|
||||
SS7_DEBUG("CC-ISUP interface already configured = %d\n", cc_isup->id);
|
||||
} else {
|
||||
if (ftmod_ss7_configure_cc_isup(x)) {
|
||||
SS7_ERROR("Failed to configure CC-ISUP interface = %d\n!", cc_isup->id);
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
SS7_INFO("Successfully configured CC-ISUP interface = %d\n", cc_isup->id);
|
||||
sngss7_set_flag(cc_isup, SNGSS7_FLAG_CONFIGURED);
|
||||
}
|
||||
}
|
||||
/* next link */
|
||||
x++;
|
||||
cc_isup = &g_ftdm_sngss7_data.cfg.isup_cc[x];
|
||||
} /* while (g_ftdm_sngss7_data.cfg.cc_isup[x]->id != 0) */
|
||||
|
||||
SS7_DEBUG("Finished LibSngSS7 configuration...\n");
|
||||
return FTDM_SUCCESS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static int ftmod_ss7_general_configuration(void)
|
||||
static int ftmod_ss7_enable_isap(int suId)
|
||||
{
|
||||
CcMngmt cntrl;
|
||||
Pst pst;
|
||||
|
||||
if(sng_cfg_mtp1_gen(&g_ftdm_sngss7_data.cfg)) {
|
||||
SS7_ERROR("General configuration for MTP1 failed!\n");
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
SS7_INFO("General configuration for MTP1 was successful\n");
|
||||
}
|
||||
/* initalize the post structure */
|
||||
smPstInit(&pst);
|
||||
|
||||
if(sng_cfg_mtp2_gen(&g_ftdm_sngss7_data.cfg)) {
|
||||
SS7_ERROR("General configuration for MTP2 failed!\n");
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
SS7_INFO("General configuration for MTP2 was successful\n");
|
||||
}
|
||||
/* insert the destination Entity */
|
||||
pst.dstEnt = ENTCC;
|
||||
|
||||
if(sng_cfg_mtp3_gen(&g_ftdm_sngss7_data.cfg)) {
|
||||
SS7_ERROR("General configuration for MTP3 failed!\n");
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
SS7_INFO("General configuration for MTP3 was successful\n");
|
||||
}
|
||||
/* initalize the control structure */
|
||||
memset(&cntrl, 0x0, sizeof(CcMngmt));
|
||||
|
||||
if(sng_cfg_isup_gen(&g_ftdm_sngss7_data.cfg)) {
|
||||
SS7_ERROR("General configuration for ISUP failed!\n");
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
SS7_INFO("General configuration for ISUP was successful\n");
|
||||
}
|
||||
/* initalize the control header */
|
||||
smHdrInit(&cntrl.hdr);
|
||||
|
||||
if(sng_cfg_cc_gen(&g_ftdm_sngss7_data.cfg)) {
|
||||
SS7_ERROR("General configuration for Call-Control failed!\n");
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
SS7_INFO("General configuration for Call-Control was successful\n");
|
||||
}
|
||||
cntrl.hdr.msgType = TCNTRL; /* this is a control request */
|
||||
cntrl.hdr.entId.ent = ENTCC;
|
||||
cntrl.hdr.entId.inst = S_INST;
|
||||
cntrl.hdr.elmId.elmnt = STISAP;
|
||||
|
||||
return FTDM_SUCCESS;
|
||||
cntrl.hdr.elmId.elmntInst1 = suId; /* this is the SAP to bind */
|
||||
|
||||
cntrl.t.cntrl.action = ABND_ENA; /* bind and activate */
|
||||
cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */
|
||||
|
||||
return (sng_cntrl_cc(&pst, &cntrl));
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static int ftmod_ss7_configure_mtp1_link(int id)
|
||||
static int ftmod_ss7_enable_nsap(int suId)
|
||||
{
|
||||
if(sng_cfg_mtp1_link(&g_ftdm_sngss7_data.cfg, id)){
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
SiMngmt cntrl;
|
||||
Pst pst;
|
||||
|
||||
/* initalize the post structure */
|
||||
smPstInit(&pst);
|
||||
|
||||
/* insert the destination Entity */
|
||||
pst.dstEnt = ENTSI;
|
||||
|
||||
/* initalize the control structure */
|
||||
memset(&cntrl, 0x0, sizeof(SiMngmt));
|
||||
|
||||
/* initalize the control header */
|
||||
smHdrInit(&cntrl.hdr);
|
||||
|
||||
cntrl.hdr.msgType = TCNTRL; /* this is a control request */
|
||||
cntrl.hdr.entId.ent = ENTSI;
|
||||
cntrl.hdr.entId.inst = S_INST;
|
||||
cntrl.hdr.elmId.elmnt = STNSAP;
|
||||
|
||||
cntrl.t.cntrl.s.siElmnt.elmntId.sapId = suId;
|
||||
cntrl.t.cntrl.s.siElmnt.elmntParam.nsap.nsapType = SAP_MTP;
|
||||
|
||||
|
||||
cntrl.t.cntrl.action = ABND_ENA; /* bind and activate */
|
||||
cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */
|
||||
|
||||
return (sng_cntrl_isup(&pst, &cntrl));
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static int ftmod_ss7_configure_mtp2_link(int id)
|
||||
static int ftmod_ss7_enable_mtpLinkSet(int lnkSetId)
|
||||
{
|
||||
if(sng_cfg_mtp2_link(&g_ftdm_sngss7_data.cfg, id)){
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
SnMngmt cntrl;
|
||||
Pst pst;
|
||||
|
||||
/* initalize the post structure */
|
||||
smPstInit(&pst);
|
||||
|
||||
/* insert the destination Entity */
|
||||
pst.dstEnt = ENTSN;
|
||||
|
||||
/* initalize the control structure */
|
||||
memset(&cntrl, 0x0, sizeof(SnMngmt));
|
||||
|
||||
/* initalize the control header */
|
||||
smHdrInit(&cntrl.hdr);
|
||||
|
||||
cntrl.hdr.msgType = TCNTRL; /* this is a control request */
|
||||
cntrl.hdr.entId.ent = ENTSN;
|
||||
cntrl.hdr.entId.inst = S_INST;
|
||||
cntrl.hdr.elmId.elmnt = STLNKSET;
|
||||
cntrl.hdr.elmId.elmntInst1 = lnkSetId; /* this is the linkset to bind */
|
||||
|
||||
cntrl.t.cntrl.action = ABND_ENA; /* bind and activate */
|
||||
cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */
|
||||
|
||||
return (sng_cntrl_mtp3(&pst, &cntrl));
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static int ftmod_ss7_configure_mtp3_link(int id)
|
||||
int ftmod_ss7_inhibit_mtplink(uint32_t id)
|
||||
{
|
||||
if(sng_cfg_mtp3_link(&g_ftdm_sngss7_data.cfg, id)){
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
SnMngmt cntrl;
|
||||
Pst pst;
|
||||
|
||||
/* initalize the post structure */
|
||||
smPstInit(&pst);
|
||||
|
||||
/* insert the destination Entity */
|
||||
pst.dstEnt = ENTSN;
|
||||
|
||||
/* initalize the control structure */
|
||||
memset(&cntrl, 0x0, sizeof(SnMngmt));
|
||||
|
||||
/* initalize the control header */
|
||||
smHdrInit(&cntrl.hdr);
|
||||
|
||||
cntrl.hdr.msgType = TCNTRL; /* this is a control request */
|
||||
cntrl.hdr.entId.ent = ENTSN;
|
||||
cntrl.hdr.entId.inst = S_INST;
|
||||
cntrl.hdr.elmId.elmnt = STDLSAP;
|
||||
cntrl.hdr.elmId.elmntInst1 = id; /* the DSLAP to inhibit */
|
||||
|
||||
cntrl.t.cntrl.action = AINH; /* Inhibit */
|
||||
cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */
|
||||
|
||||
return (sng_cntrl_mtp3(&pst, &cntrl));
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
static int ftmod_ss7_configure_mtp3_linkset(int id)
|
||||
int ftmod_ss7_uninhibit_mtplink(uint32_t id)
|
||||
{
|
||||
if(sng_cfg_mtp3_linkset(&g_ftdm_sngss7_data.cfg, id)){
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
}
|
||||
SnMngmt cntrl;
|
||||
Pst pst;
|
||||
|
||||
/******************************************************************************/
|
||||
static int ftmod_ss7_configure_mtp3_route(int id)
|
||||
{
|
||||
if(sng_cfg_mtp3_route(&g_ftdm_sngss7_data.cfg, id)){
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
}
|
||||
/* initalize the post structure */
|
||||
smPstInit(&pst);
|
||||
|
||||
/******************************************************************************/
|
||||
static int ftmod_ss7_configure_mtp3_isup(int id)
|
||||
{
|
||||
if(sng_cfg_mtp3_isup_interface(&g_ftdm_sngss7_data.cfg, id)){
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
}
|
||||
/* insert the destination Entity */
|
||||
pst.dstEnt = ENTSN;
|
||||
|
||||
/******************************************************************************/
|
||||
static int ftmod_ss7_configure_isup_mtp3(int id)
|
||||
{
|
||||
if(sng_cfg_isup_mtp3_interface(&g_ftdm_sngss7_data.cfg, id)){
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
}
|
||||
/* initalize the control structure */
|
||||
memset(&cntrl, 0x0, sizeof(SnMngmt));
|
||||
|
||||
/******************************************************************************/
|
||||
static int ftmod_ss7_configure_isup_interface(int id)
|
||||
{
|
||||
if(sng_cfg_isup_interface(&g_ftdm_sngss7_data.cfg, id)){
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
}
|
||||
/* initalize the control header */
|
||||
smHdrInit(&cntrl.hdr);
|
||||
|
||||
/******************************************************************************/
|
||||
static int ftmod_ss7_configure_isup_circuit(int id)
|
||||
{
|
||||
if(sng_cfg_isup_circuit(&g_ftdm_sngss7_data.cfg, id)){
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
}
|
||||
cntrl.hdr.msgType = TCNTRL; /* this is a control request */
|
||||
cntrl.hdr.entId.ent = ENTSN;
|
||||
cntrl.hdr.entId.inst = S_INST;
|
||||
cntrl.hdr.elmId.elmnt = STDLSAP;
|
||||
cntrl.hdr.elmId.elmntInst1 = id; /* the DSLAP to inhibit */
|
||||
|
||||
/******************************************************************************/
|
||||
static int ftmod_ss7_configure_isup_cc(int id)
|
||||
{
|
||||
if(sng_cfg_isup_cc_interface(&g_ftdm_sngss7_data.cfg, id)){
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
}
|
||||
cntrl.t.cntrl.action = AUNINH; /* Inhibit */
|
||||
cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */
|
||||
|
||||
/******************************************************************************/
|
||||
static int ftmod_ss7_configure_cc_isup(int id)
|
||||
{
|
||||
if(sng_cfg_cc_isup_interface(&g_ftdm_sngss7_data.cfg, id)){
|
||||
return FTDM_FAIL;
|
||||
} else {
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
return (sng_cntrl_mtp3(&pst, &cntrl));
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,592 @@
|
|||
/*
|
||||
* Copyright (c) 2009|Konrad Hammel <konrad@sangoma.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms|with or without
|
||||
* modification|are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice|this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice|this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES|INCLUDING|BUT NOT
|
||||
* LIMITED TO|THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT|INDIRECT|INCIDENTAL|SPECIAL,
|
||||
* EXEMPLARY|OR CONSEQUENTIAL DAMAGES (INCLUDING|BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE|DATA|OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY|WHETHER IN CONTRACT|STRICT LIABILITY|OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE|EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* INCLUDE ********************************************************************/
|
||||
#include "ftmod_sangoma_ss7_main.h"
|
||||
/******************************************************************************/
|
||||
|
||||
/* DEFINES ********************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/* PROTOTYPES *****************************************************************/
|
||||
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);
|
||||
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);
|
||||
/******************************************************************************/
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
void handle_sng_log(uint8_t level, char *fmt,...)
|
||||
{
|
||||
char *data;
|
||||
int ret;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
ret = vasprintf(&data, fmt, ap);
|
||||
if (ret == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (level) {
|
||||
/**************************************************************************/
|
||||
case SNG_LOGLEVEL_DEBUG:
|
||||
ftdm_log(FTDM_LOG_DEBUG, "sng_ss7->%s", data);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case SNG_LOGLEVEL_WARN:
|
||||
ftdm_log(FTDM_LOG_WARNING, "sng_ss7->%s", data);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case SNG_LOGLEVEL_INFO:
|
||||
ftdm_log(FTDM_LOG_INFO, "sng_ss7->%s", data);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case SNG_LOGLEVEL_STATS:
|
||||
ftdm_log(FTDM_LOG_INFO, "sng_ss7->%s", data);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case SNG_LOGLEVEL_ERROR:
|
||||
ftdm_log(FTDM_LOG_ERROR, "sng_ss7->%s", data);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case SNG_LOGLEVEL_CRIT:
|
||||
/*printf("%s",data);*/
|
||||
ftdm_log(FTDM_LOG_CRIT, "sng_ss7->%s", data);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_INFO, "sng_ss7->%s", data);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void handle_sng_mtp1_alarm(Pst *pst, L1Mngmt *sta)
|
||||
{
|
||||
|
||||
|
||||
} /* handle_mtp1_alarm */
|
||||
|
||||
/******************************************************************************/
|
||||
void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta)
|
||||
{
|
||||
|
||||
switch (sta->t.usta.alarm.category) {
|
||||
/**************************************************************************/
|
||||
case (LCM_CATEGORY_PROTOCOL):
|
||||
case (LCM_CATEGORY_INTERFACE):
|
||||
|
||||
switch (sta->t.usta.alarm.event) {
|
||||
/**********************************************************************/
|
||||
case (LSD_EVENT_ENTR_CONG):
|
||||
case (LSD_EVENT_EXIT_CONG):
|
||||
case (LSD_EVENT_PROT_ST_UP):
|
||||
case (LSD_EVENT_PROT_ST_DN):
|
||||
case (LSD_EVENT_LINK_ALIGNED):
|
||||
case (LSD_EVENT_REMOTE_CONG_START):
|
||||
case (LSD_EVENT_REMOTE_CONG_END):
|
||||
case (LSD_EVENT_RX_REMOTE_SIPO):
|
||||
|
||||
switch (sta->t.usta.alarm.cause) {
|
||||
/******************************************************************/
|
||||
case (LCM_CAUSE_UNKNOWN):
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP2][SAPID:%d] %s\n",
|
||||
sta->t.usta.evntParm[0],
|
||||
DECODE_LSD_EVENT(sta->t.usta.alarm.event));
|
||||
break;
|
||||
/******************************************************************/
|
||||
case (LCM_CAUSE_MGMT_INITIATED):
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP2][SAPID:%d][MGMT] %s\n",
|
||||
sta->t.usta.evntParm[0],
|
||||
DECODE_LSD_EVENT(sta->t.usta.alarm.event));
|
||||
break;
|
||||
/******************************************************************/
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP2][SAPID:%d] %s (***unknown cause***)\n",
|
||||
sta->t.usta.evntParm[0],
|
||||
DECODE_LSD_EVENT(sta->t.usta.alarm.event));
|
||||
break;
|
||||
/******************************************************************/
|
||||
} /* switch (sta->t.usta.alarm.cause) */
|
||||
break;
|
||||
/**********************************************************************/
|
||||
case (LSD_EVENT_PROT_ERR):
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP2][SAPID:%d] %s : %s\n",
|
||||
sta->t.usta.evntParm[0],
|
||||
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
|
||||
DECODE_LSD_CAUSE(sta->t.usta.alarm.cause));
|
||||
break;
|
||||
/**********************************************************************/
|
||||
case (LSD_EVENT_ALIGN_LOST):
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP2][SAPID:%d] %s : %s\n",
|
||||
sta->t.usta.evntParm[0],
|
||||
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
|
||||
DECODE_DISC_REASON(sta->t.usta.evntParm[1]));
|
||||
break;
|
||||
/**********************************************************************/
|
||||
case (LSD_EVENT_RTB_FULL):
|
||||
case (LSD_EVENT_RTB_FULL_OVER):
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP2][SAPID:%d] %s : RTB Queue Len(%d)|Oldest BSN(%d)|Tx Queue Len(%d)|Outstanding Frames(%d)\n",
|
||||
sta->t.usta.evntParm[0],
|
||||
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
|
||||
sta->t.usta.evntParm[1],
|
||||
sta->t.usta.evntParm[2],
|
||||
sta->t.usta.evntParm[3],
|
||||
sta->t.usta.evntParm[4]);
|
||||
break;
|
||||
/**********************************************************************/
|
||||
case (LSD_EVENT_NEG_ACK):
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP2][SAPID:%d] %s : RTB Queue Len(%d)\n",
|
||||
sta->t.usta.evntParm[0],
|
||||
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
|
||||
sta->t.usta.evntParm[1]);
|
||||
break;
|
||||
/**********************************************************************/
|
||||
case (LSD_EVENT_DAT_CFM_SDT):
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP2][SAPID:%d] %s : %d\n",
|
||||
sta->t.usta.evntParm[0],
|
||||
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
|
||||
DECODE_DISC_REASON(sta->t.usta.evntParm[1]));
|
||||
break;
|
||||
/**********************************************************************/
|
||||
case (LCM_EVENT_UI_INV_EVT):
|
||||
case (LCM_EVENT_LI_INV_EVT):
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP2] %s : %s : Primitive (%d)\n",
|
||||
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
|
||||
DECODE_LCM_CAUSE(sta->t.usta.alarm.cause),
|
||||
sta->t.usta.evntParm[0]);
|
||||
break;
|
||||
/**********************************************************************/
|
||||
case (LCM_EVENT_INV_EVT):
|
||||
|
||||
switch (sta->t.usta.alarm.cause) {
|
||||
/******************************************************************/
|
||||
case (LCM_CAUSE_UNKNOWN):
|
||||
case (LCM_CAUSE_SWVER_NAVAIL):
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP2] %s : %s : Event (%d)\n",
|
||||
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
|
||||
DECODE_LCM_CAUSE(sta->t.usta.alarm.cause),
|
||||
sta->t.usta.evntParm[0]);
|
||||
break;
|
||||
/******************************************************************/
|
||||
case (LCM_CAUSE_DECODE_ERR):
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP2] %s : %s : Primitive (%d)|Version (%d)\n",
|
||||
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
|
||||
DECODE_LCM_CAUSE(sta->t.usta.alarm.cause),
|
||||
sta->t.usta.evntParm[0],
|
||||
sta->t.usta.evntParm[1]);
|
||||
break;
|
||||
/******************************************************************/
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP2] %s(%d) : %s(%d)\n",
|
||||
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
|
||||
sta->t.usta.alarm.event,
|
||||
DECODE_LSD_CAUSE(sta->t.usta.alarm.cause),
|
||||
sta->t.usta.alarm.cause);
|
||||
break;
|
||||
/******************************************************************/
|
||||
} /* switch (sta->t.usta.alarm.cause) */
|
||||
break;
|
||||
/**********************************************************************/
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP2] %s(%d) : %s(%d)\n",
|
||||
DECODE_LSD_EVENT(sta->t.usta.alarm.event),
|
||||
sta->t.usta.alarm.event,
|
||||
DECODE_LSD_CAUSE(sta->t.usta.alarm.cause),
|
||||
sta->t.usta.alarm.cause);
|
||||
break;
|
||||
/**********************************************************************/
|
||||
} /* switch (sta->t.usta.alarm.event) */
|
||||
break;
|
||||
/**************************************************************************/
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP2] Unknown alarm category %d\n",
|
||||
sta->t.usta.alarm.category);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
} /* switch(sta->t.usta.alarm.category) */
|
||||
|
||||
return;
|
||||
} /* handle_mtp2_alarm */
|
||||
|
||||
/******************************************************************************/
|
||||
void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta)
|
||||
{
|
||||
|
||||
switch (sta->hdr.elmId.elmnt) {
|
||||
/**************************************************************************/
|
||||
case (STDLSAP):
|
||||
switch (sta->t.usta.alarm.event) {
|
||||
/**********************************************************************/
|
||||
case (LSN_EVENT_INV_OPC_OTHER_END):
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP3][SAPID:%d] %s : %s : OPC(0x%X%X%X%X)\n",
|
||||
sta->hdr.elmId.elmntInst1,
|
||||
DECODE_LSN_EVENT(sta->t.usta.alarm.event),
|
||||
DECODE_LSN_CAUSE(sta->t.usta.alarm.cause),
|
||||
sta->t.usta.evntParm[3],
|
||||
sta->t.usta.evntParm[2],
|
||||
sta->t.usta.evntParm[1],
|
||||
sta->t.usta.evntParm[0]);
|
||||
break;
|
||||
/**********************************************************************/
|
||||
case (LSN_EVENT_INV_SLC_OTHER_END):
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP3][SAPID:%d] %s : %s : SLC(%d)\n",
|
||||
sta->hdr.elmId.elmntInst1,
|
||||
DECODE_LSN_EVENT(sta->t.usta.alarm.event),
|
||||
DECODE_LSN_CAUSE(sta->t.usta.alarm.cause),
|
||||
sta->t.usta.evntParm[0]);
|
||||
break;
|
||||
/**********************************************************************/
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP3][SAPID:%d] %s(%d) : %s(%d)\n",
|
||||
sta->hdr.elmId.elmntInst1,
|
||||
DECODE_LSN_EVENT(sta->t.usta.alarm.event),
|
||||
sta->t.usta.alarm.event,
|
||||
DECODE_LSN_CAUSE(sta->t.usta.alarm.cause),
|
||||
sta->t.usta.alarm.cause);
|
||||
break;
|
||||
/**********************************************************************/
|
||||
} /* sta->t.usta.alarm.event */
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (STNSAP):
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP3][SAPID:%d] %s : %s\n",
|
||||
sta->hdr.elmId.elmntInst1,
|
||||
DECODE_LSN_EVENT(sta->t.usta.alarm.event),
|
||||
DECODE_LSN_CAUSE(sta->t.usta.alarm.cause));
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (STLNKSET):
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP3][LNKSET:%d] %s : %s\n",
|
||||
sta->hdr.elmId.elmntInst1,
|
||||
DECODE_LSN_EVENT(sta->t.usta.alarm.event),
|
||||
DECODE_LSN_CAUSE(sta->t.usta.alarm.cause));
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case (STROUT):
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP3][DPC:0x%d%d%d%d] %s : %s\n",
|
||||
sta->t.usta.evntParm[0],
|
||||
sta->t.usta.evntParm[1],
|
||||
sta->t.usta.evntParm[2],
|
||||
sta->t.usta.evntParm[3],
|
||||
DECODE_LSN_EVENT(sta->t.usta.alarm.event),
|
||||
DECODE_LSN_CAUSE(sta->t.usta.alarm.cause));
|
||||
break;
|
||||
/**************************************************************************/
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_ERROR,"[MTP3] %s(%d) : %s(%d)\n",
|
||||
DECODE_LSN_EVENT(sta->t.usta.alarm.event),
|
||||
sta->t.usta.alarm.event,
|
||||
DECODE_LSN_CAUSE(sta->t.usta.alarm.cause),
|
||||
sta->t.usta.alarm.cause);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
} /* switch (sta->hdr.elmId.elmnt) */
|
||||
|
||||
return;
|
||||
} /* handle_mtp3_alarm */
|
||||
|
||||
/******************************************************************************/
|
||||
void handle_sng_isup_alarm(Pst *pst, SiMngmt *sta)
|
||||
{
|
||||
char msg[250];
|
||||
char tmp[25];
|
||||
char *p = NULL;
|
||||
int x = 0;
|
||||
|
||||
/* initalize the msg variable to NULLs */
|
||||
memset(&msg[0], '\0', sizeof(&msg));
|
||||
|
||||
|
||||
/* point p to the first spot in msg */
|
||||
p = &msg[0];
|
||||
|
||||
p = strcat(p, "[ISUP]");
|
||||
|
||||
/* go through the dgnVals */
|
||||
for (x = 0; x < 5; x++) {
|
||||
switch (sta->t.usta.dgn.dgnVal[x].type) {
|
||||
/**********************************************************************/
|
||||
case (LSI_USTA_DGNVAL_NONE):
|
||||
break;
|
||||
/**********************************************************************/
|
||||
case (LSI_USTA_DGNVAL_EVENT):
|
||||
/* init tmp with NULLs */
|
||||
memset(&tmp[0], '\0', sizeof(&tmp));
|
||||
|
||||
/* fill in the dgn val to tmp */
|
||||
sprintf(&tmp[0], "[EVENT:%d]",sta->t.usta.dgn.dgnVal[x].t.event);
|
||||
|
||||
/* concat tmp to msg */
|
||||
p = strcat(p, &tmp[0]);
|
||||
break;
|
||||
/**********************************************************************/
|
||||
case (LSI_USTA_DGNVAL_SPID):
|
||||
/* init tmp with NULLs */
|
||||
memset(&tmp[0], '\0', sizeof(&tmp));
|
||||
|
||||
/* fill in the dgn val to tmp */
|
||||
sprintf(&tmp[0], "[SPID:%d]",sta->t.usta.dgn.dgnVal[x].t.spId);
|
||||
|
||||
/* concat tmp to msg */
|
||||
p = strcat(p, &tmp[0]);
|
||||
break;
|
||||
/**********************************************************************/
|
||||
case (LSI_USTA_DGNVAL_SUID):
|
||||
/* init tmp with NULLs */
|
||||
memset(&tmp[0], '\0', sizeof(&tmp));
|
||||
|
||||
/* fill in the dgn val to tmp */
|
||||
sprintf(&tmp[0], "[SUID:%d]",sta->t.usta.dgn.dgnVal[x].t.suId);
|
||||
|
||||
/* concat tmp to msg */
|
||||
p = strcat(p, &tmp[0]);
|
||||
break;
|
||||
/**********************************************************************/
|
||||
case (LSI_USTA_DGNVAL_SPINSTID):
|
||||
/* init tmp with NULLs */
|
||||
memset(&tmp[0], '\0', sizeof(&tmp));
|
||||
|
||||
/* fill in the dgn val to tmp */
|
||||
sprintf(&tmp[0], "[SPINSTID:%d]", (int)sta->t.usta.dgn.dgnVal[x].t.spInstId);
|
||||
|
||||
/* concat tmp to msg */
|
||||
p = strcat(p, &tmp[0]);
|
||||
break;
|
||||
/**********************************************************************/
|
||||
case (LSI_USTA_DGNVAL_SUINSTID):
|
||||
/* init tmp with NULLs */
|
||||
memset(&tmp[0], '\0', sizeof(&tmp));
|
||||
|
||||
/* fill in the dgn val to tmp */
|
||||
sprintf(&tmp[0], "[SUINSTID:%d]", (int)sta->t.usta.dgn.dgnVal[x].t.suInstId);
|
||||
|
||||
/* concat tmp to msg */
|
||||
p = strcat(p, &tmp[0]);
|
||||
break;
|
||||
/**********************************************************************/
|
||||
case (LSI_USTA_DGNVAL_CIRCUIT):
|
||||
/* init tmp with NULLs */
|
||||
memset(&tmp[0], '\0', sizeof(&tmp));
|
||||
|
||||
/* fill in the dgn val to tmp */
|
||||
sprintf(&tmp[0], "[CKT:%d]", (int)sta->t.usta.dgn.dgnVal[x].t.cirId);
|
||||
|
||||
/* concat tmp to msg */
|
||||
p = strcat(p, &tmp[0]);
|
||||
break;
|
||||
/**********************************************************************/
|
||||
case (LSI_USTA_DGNVAL_CIC):
|
||||
/* init tmp with NULLs */
|
||||
memset(&tmp[0], '\0', sizeof(&tmp));
|
||||
|
||||
/* fill in the dgn val to tmp */
|
||||
sprintf(&tmp[0], "[CIC:%d]", (int)sta->t.usta.dgn.dgnVal[x].t.cic);
|
||||
|
||||
/* concat tmp to msg */
|
||||
p = strcat(p, &tmp[0]);
|
||||
break;
|
||||
/**********************************************************************/
|
||||
case (LSI_USTA_DGNVAL_INTF):
|
||||
/* init tmp with NULLs */
|
||||
memset(&tmp[0], '\0', sizeof(&tmp));
|
||||
|
||||
/* fill in the dgn val to tmp */
|
||||
sprintf(&tmp[0], "[INTF:%d]", (int)sta->t.usta.dgn.dgnVal[x].t.intfId);
|
||||
|
||||
/* concat tmp to msg */
|
||||
p = strcat(p, &tmp[0]);
|
||||
break;
|
||||
/**********************************************************************/
|
||||
case (LSI_USTA_DGNVAL_DPC):
|
||||
/* init tmp with NULLs */
|
||||
memset(&tmp[0], '\0', sizeof(&tmp));
|
||||
|
||||
/* fill in the dgn val to tmp */
|
||||
sprintf(&tmp[0], "[DPC:%d]", (int)sta->t.usta.dgn.dgnVal[x].t.dpc);
|
||||
|
||||
/* concat tmp to msg */
|
||||
p = strcat(p, &tmp[0]);
|
||||
break;
|
||||
/**********************************************************************/
|
||||
case (LSI_USTA_DGNVAL_ADDRS):
|
||||
#if 0
|
||||
/*
|
||||
*typedef struct addrs
|
||||
*{
|
||||
*U8 length;
|
||||
*U8 strg[ADRLEN];
|
||||
*} Addrs;
|
||||
*/
|
||||
/* init tmp with NULLs */
|
||||
memset(&tmp[0], '\0', sizeof(&tmp));
|
||||
|
||||
/* fill in the dgn val to tmp */
|
||||
sprintf(&tmp[0], "[ADDRS:%d]",sta->t.usta.dgn.dgnVal[x].t.);
|
||||
|
||||
/* concat tmp to msg */
|
||||
p = strcat(p, &tmp[0]);
|
||||
#endif
|
||||
break;
|
||||
/**********************************************************************/
|
||||
case (LSI_USTA_DGNVAL_SWTCH):
|
||||
/* init tmp with NULLs */
|
||||
memset(&tmp[0], '\0', sizeof(&tmp));
|
||||
|
||||
/* fill in the dgn val to tmp */
|
||||
sprintf(&tmp[0], "[SWTCH:%d]",sta->t.usta.dgn.dgnVal[x].t.swtch);
|
||||
|
||||
/* concat tmp to msg */
|
||||
p = strcat(p, &tmp[0]);
|
||||
break;
|
||||
/**********************************************************************/
|
||||
case (LSI_USTA_DGNVAL_RANGE):
|
||||
/* init tmp with NULLs */
|
||||
memset(&tmp[0], '\0', sizeof(&tmp));
|
||||
|
||||
/* fill in the dgn val to tmp */
|
||||
sprintf(&tmp[0], "[RANGE:0x%X]",sta->t.usta.dgn.dgnVal[x].t.range);
|
||||
|
||||
/* concat tmp to msg */
|
||||
p = strcat(p, &tmp[0]);
|
||||
break;
|
||||
/**********************************************************************/
|
||||
case (LSI_USTA_DGNVAL_STATUS_OCTS):
|
||||
#if 0
|
||||
/*
|
||||
*typedef struct addrs
|
||||
*{
|
||||
*U8 length;
|
||||
*U8 strg[ADRLEN];
|
||||
*} Addrs;
|
||||
*/
|
||||
/* init tmp with NULLs */
|
||||
/* init tmp with NULLs */
|
||||
memset(&tmp[0], '\0', sizeof(&tmp));
|
||||
|
||||
/* fill in the dgn val to tmp */
|
||||
sprintf(&tmp[0], "[STATUS_OCT:0x%X]",sta->t.usta.dgn.dgnVal[x].t.);
|
||||
|
||||
/* concat tmp to msg */
|
||||
p = strcat(p, &tmp[0]);
|
||||
#endif
|
||||
break;
|
||||
/**********************************************************************/
|
||||
case (LSI_USTA_DGNVAL_VER):
|
||||
#ifdef SI_RUG
|
||||
/* init tmp with NULLs */
|
||||
memset(&tmp[0], '\0', sizeof(&tmp));
|
||||
|
||||
/* fill in the dgn val to tmp */
|
||||
sprintf(&tmp[0], "[VER:%d]",sta->t.usta.dgn.dgnVal[x].t.intfVer);
|
||||
|
||||
/* concat tmp to msg */
|
||||
p = strcat(p, &tmp[0]);
|
||||
#endif
|
||||
break;
|
||||
/**********************************************************************/
|
||||
case (LSI_USTA_DGNVAL_TIMER):
|
||||
/* init tmp with NULLs */
|
||||
memset(&tmp[0], '\0', sizeof(&tmp));
|
||||
|
||||
/* fill in the dgn val to tmp */
|
||||
sprintf(&tmp[0], "[TIMER:0x%X]",sta->t.usta.dgn.dgnVal[x].t.tmrInfo);
|
||||
|
||||
/* concat tmp to msg */
|
||||
p = strcat(p, &tmp[0]);
|
||||
break;
|
||||
/**********************************************************************/
|
||||
case (LSI_USTA_DGNVAL_MSGTYPE):
|
||||
/* init tmp with NULLs */
|
||||
memset(&tmp[0], '\0', sizeof(&tmp));
|
||||
|
||||
/* fill in the dgn val to tmp */
|
||||
sprintf(&tmp[0], "[MSGTYPE:%d]",sta->t.usta.dgn.dgnVal[x].t.msgType);
|
||||
|
||||
/* concat tmp to msg */
|
||||
p = strcat(p, &tmp[0]);
|
||||
break;
|
||||
/**********************************************************************/
|
||||
case (LSI_USTA_DGNVAL_STATE):
|
||||
/* init tmp with NULLs */
|
||||
memset(&tmp[0], '\0', sizeof(&tmp));
|
||||
|
||||
/* fill in the dgn val to tmp */
|
||||
sprintf(&tmp[0], "[STATE:%d]",sta->t.usta.dgn.dgnVal[x].t.state);
|
||||
|
||||
/* concat tmp to msg */
|
||||
p = strcat(p, &tmp[0]);
|
||||
break;
|
||||
/**********************************************************************/
|
||||
default:
|
||||
break;
|
||||
/**********************************************************************/
|
||||
} /* switch (sta->t.usta.dgn.dgnVal[x].t.type) */
|
||||
} /* for (x = 0; x < 5; x++) */
|
||||
|
||||
ftdm_log(FTDM_LOG_ERROR,"%s %s : %s\n",
|
||||
msg,
|
||||
DECODE_LSI_EVENT(sta->t.usta.alarm.event),
|
||||
DECODE_LSI_CAUSE(sta->t.usta.alarm.cause));
|
||||
|
||||
} /* handle_isup_alarm */
|
||||
|
||||
/******************************************************************************/
|
||||
void handle_sng_cc_alarm(Pst *pst, CcMngmt *sta)
|
||||
{
|
||||
|
||||
return;
|
||||
} /* handle_cc_alarm */
|
||||
/******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
* indent-tabs-mode:t
|
||||
* tab-width:4
|
||||
* c-basic-offset:4
|
||||
* End:
|
||||
* For VIM:
|
||||
* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
|
||||
*/
|
||||
/******************************************************************************/
|
File diff suppressed because it is too large
Load Diff
|
@ -44,58 +44,286 @@
|
|||
#include <ctype.h>
|
||||
|
||||
#include "private/ftdm_core.h"
|
||||
/*
|
||||
#include "sng_sit.h"
|
||||
#include "sng_ss7_error.h"
|
||||
*/
|
||||
|
||||
#include "sng_ss7.h"
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
/* DEFINES ********************************************************************/
|
||||
#define MAX_CIC_LENGTH 5
|
||||
#define MAX_CIC_MAP_LENGTH 256
|
||||
#define MAX_MTP_LINKS MAX_SN_LINKSETS
|
||||
#define MAX_NAME_LEN 10
|
||||
#define MAX_PATH 255
|
||||
|
||||
#if 0
|
||||
#define SS7_HARDCODED
|
||||
#endif
|
||||
#define SNG_BASE 1
|
||||
#define MAX_CIC_LENGTH 5
|
||||
#define MAX_CIC_MAP_LENGTH 1000
|
||||
|
||||
#define SNGSS7_EVENT_QUEUE_SIZE 100
|
||||
|
||||
typedef enum {
|
||||
SNG_IAM = 1,
|
||||
SNG_ACM,
|
||||
SNG_CPG,
|
||||
SNG_ANM,
|
||||
SNG_REL,
|
||||
SNG_RLC
|
||||
}sng_msg_type_t;
|
||||
SNGSS7_CON_IND_EVENT = 0,
|
||||
SNGSS7_CON_CFM_EVENT,
|
||||
SNGSS7_CON_STA_EVENT,
|
||||
SNGSS7_REL_IND_EVENT,
|
||||
SNGSS7_REL_CFM_EVENT,
|
||||
SNGSS7_DAT_IND_EVENT,
|
||||
SNGSS7_FAC_IND_EVENT,
|
||||
SNGSS7_FAC_CFM_EVENT,
|
||||
SNGSS7_UMSG_IND_EVENT,
|
||||
SNGSS7_STA_IND_EVENT
|
||||
} sng_event_type_t;
|
||||
|
||||
typedef enum {
|
||||
VOICE = 0,
|
||||
SIG,
|
||||
HOLE
|
||||
} sng_ckt_type_t;
|
||||
|
||||
typedef enum {
|
||||
CONFIGURED = (1 << 0),
|
||||
ACTIVE = (1 << 1)
|
||||
} sng_flag_t;
|
||||
|
||||
typedef struct sng_mtp_link {
|
||||
char name[MAX_NAME_LEN];
|
||||
uint32_t id;
|
||||
uint32_t flags;
|
||||
struct {
|
||||
uint32_t span;
|
||||
uint32_t chan;
|
||||
} mtp1;
|
||||
struct {
|
||||
uint32_t lssuLength;
|
||||
uint32_t errorType;
|
||||
uint32_t linkType;
|
||||
uint32_t mtp1Id;
|
||||
uint32_t t1;
|
||||
uint32_t t2;
|
||||
uint32_t t3;
|
||||
uint32_t t4n;
|
||||
uint32_t t4e;
|
||||
uint32_t t5;
|
||||
uint32_t t6;
|
||||
uint32_t t7;
|
||||
} mtp2;
|
||||
struct {
|
||||
uint32_t priority;
|
||||
uint32_t linkType;
|
||||
uint32_t switchType;
|
||||
uint32_t apc;
|
||||
uint32_t spc;
|
||||
uint32_t ssf;
|
||||
uint32_t slc;
|
||||
uint32_t linkSetId;
|
||||
uint32_t mtp2Id;
|
||||
uint32_t t1;
|
||||
uint32_t t2;
|
||||
uint32_t t3;
|
||||
uint32_t t4;
|
||||
uint32_t t5;
|
||||
uint32_t t6;
|
||||
uint32_t t7;
|
||||
uint32_t t8;
|
||||
uint32_t t9;
|
||||
uint32_t t10;
|
||||
uint32_t t11;
|
||||
uint32_t t12;
|
||||
uint32_t t13;
|
||||
uint32_t t14;
|
||||
uint32_t t15;
|
||||
uint32_t t16;
|
||||
uint32_t t17;
|
||||
uint32_t t18;
|
||||
uint32_t t19;
|
||||
uint32_t t20;
|
||||
uint32_t t21;
|
||||
uint32_t t22;
|
||||
uint32_t t23;
|
||||
uint32_t t24;
|
||||
uint32_t t25;
|
||||
uint32_t t26;
|
||||
uint32_t t27;
|
||||
uint32_t t28;
|
||||
uint32_t t29;
|
||||
uint32_t t30;
|
||||
uint32_t t31;
|
||||
uint32_t t32;
|
||||
uint32_t t33;
|
||||
uint32_t t34;
|
||||
uint32_t t35;
|
||||
uint32_t t36;
|
||||
uint32_t t37;
|
||||
uint32_t tcraft;
|
||||
uint32_t tflc;
|
||||
uint32_t tbnd;
|
||||
} mtp3;
|
||||
} sng_mtp_link_t;
|
||||
|
||||
typedef struct sng_link_set {
|
||||
uint32_t id;
|
||||
char name[MAX_NAME_LEN];
|
||||
uint32_t flags;
|
||||
uint32_t apc;
|
||||
uint32_t linkType;
|
||||
uint32_t minActive;
|
||||
uint32_t numLinks;
|
||||
uint32_t links[16];
|
||||
} sng_link_set_t;
|
||||
|
||||
typedef struct sng_route {
|
||||
uint32_t id;
|
||||
char name[MAX_NAME_LEN];
|
||||
uint32_t flags;
|
||||
uint32_t dpc;
|
||||
uint32_t cmbLinkSetId;
|
||||
uint32_t linkType;
|
||||
uint32_t switchType;
|
||||
uint32_t ssf;
|
||||
uint32_t isSTP;
|
||||
uint32_t t6;
|
||||
uint32_t t8;
|
||||
uint32_t t10;
|
||||
uint32_t t11;
|
||||
uint32_t t15;
|
||||
uint32_t t16;
|
||||
uint32_t t18;
|
||||
uint32_t t19;
|
||||
uint32_t t21;
|
||||
uint32_t t25;
|
||||
} sng_route_t;
|
||||
|
||||
typedef struct sng_isup_intf {
|
||||
uint32_t id;
|
||||
char name[MAX_NAME_LEN];
|
||||
uint32_t flags;
|
||||
uint32_t spc;
|
||||
uint32_t dpc;
|
||||
uint32_t switchType;
|
||||
uint32_t nwId;
|
||||
uint32_t mtpRouteId;
|
||||
uint32_t ssf;
|
||||
uint32_t isap;
|
||||
uint16_t t4;
|
||||
uint32_t t10;
|
||||
uint32_t t11;
|
||||
uint32_t t18;
|
||||
uint32_t t19;
|
||||
uint32_t t20;
|
||||
uint32_t t21;
|
||||
uint32_t t22;
|
||||
uint32_t t23;
|
||||
uint32_t t24;
|
||||
uint32_t t25;
|
||||
uint32_t t26;
|
||||
uint32_t t28;
|
||||
uint32_t t29;
|
||||
uint32_t t30;
|
||||
uint32_t t32;
|
||||
uint32_t t35;
|
||||
uint32_t t37;
|
||||
uint32_t t38;
|
||||
uint32_t t39;
|
||||
uint32_t tfgr;
|
||||
uint32_t tpause;
|
||||
uint32_t tstaenq;
|
||||
} sng_isup_inf_t;
|
||||
|
||||
typedef struct sng_isup_ckt {
|
||||
uint32_t id;
|
||||
uint32_t flags;
|
||||
uint32_t span;
|
||||
uint32_t chan;
|
||||
uint32_t type; /* VOICE/SIG/HOLE */
|
||||
uint32_t cic;
|
||||
uint32_t infId;
|
||||
uint32_t ssf;
|
||||
uint32_t typeCntrl;
|
||||
void *obj;
|
||||
uint16_t t3;
|
||||
uint16_t t12;
|
||||
uint16_t t13;
|
||||
uint16_t t14;
|
||||
uint16_t t15;
|
||||
uint16_t t16;
|
||||
uint16_t t17;
|
||||
uint16_t tval;
|
||||
} sng_isup_ckt_t;
|
||||
|
||||
typedef struct sng_nsap {
|
||||
uint32_t id;
|
||||
uint32_t flags;
|
||||
uint32_t suId;
|
||||
uint32_t spId;
|
||||
uint32_t nwId;
|
||||
uint32_t linkType;
|
||||
uint32_t switchType;
|
||||
uint32_t ssf;
|
||||
} sng_nsap_t;
|
||||
|
||||
typedef struct sng_isap {
|
||||
uint32_t id;
|
||||
uint32_t suId;
|
||||
uint32_t spId;
|
||||
uint32_t switchType;
|
||||
uint32_t ssf;
|
||||
uint32_t flags;
|
||||
uint32_t t1;
|
||||
uint32_t t2;
|
||||
uint32_t t5;
|
||||
uint32_t t6;
|
||||
uint32_t t7;
|
||||
uint32_t t8;
|
||||
uint32_t t9;
|
||||
uint32_t t27;
|
||||
uint32_t t31;
|
||||
uint32_t t33;
|
||||
uint32_t t34;
|
||||
uint32_t t36;
|
||||
uint32_t tccr;
|
||||
uint32_t tccrt;
|
||||
uint32_t tex;
|
||||
uint32_t tcrm;
|
||||
uint32_t tcra;
|
||||
uint32_t tect;
|
||||
uint32_t trelrsp;
|
||||
uint32_t tfnlrelrsp;
|
||||
} sng_isap_t;
|
||||
|
||||
typedef struct sng_ss7_cfg {
|
||||
uint32_t spc;
|
||||
char license[MAX_PATH];
|
||||
char signature[MAX_PATH];
|
||||
sng_mtp_link_t mtpLink[MAX_MTP_LINKS+1];
|
||||
sng_link_set_t mtpLinkSet[MAX_MTP_LINKSETS+1];
|
||||
sng_route_t mtpRoute[MAX_MTP_ROUTES+1];
|
||||
sng_isup_inf_t isupIntf[MAX_ISUP_INFS+1];
|
||||
sng_isup_ckt_t isupCkt[MAX_ISUP_CKTS+1];
|
||||
sng_nsap_t nsap[MAX_NSAPS+1];
|
||||
sng_isap_t isap[MAX_ISAPS+1];
|
||||
}sng_ss7_cfg_t;
|
||||
|
||||
typedef struct ftdm_sngss7_data {
|
||||
sng_config_t cfg;
|
||||
int gen_config_done;
|
||||
int min_digits;
|
||||
int function_trace;
|
||||
int function_trace_level;
|
||||
int message_trace;
|
||||
int message_trace_level;
|
||||
fio_signal_cb_t sig_cb;
|
||||
sng_ss7_cfg_t cfg;
|
||||
int gen_config;
|
||||
int min_digits;
|
||||
int function_trace;
|
||||
int function_trace_level;
|
||||
int message_trace;
|
||||
int message_trace_level;
|
||||
fio_signal_cb_t sig_cb;
|
||||
}ftdm_sngss7_data_t;
|
||||
|
||||
typedef struct sngss7_timer_data {
|
||||
ftdm_timer_t *heartbeat_timer;
|
||||
int beat;
|
||||
int counter;
|
||||
ftdm_sched_callback_t callback;
|
||||
ftdm_sched_t *sched;
|
||||
void *sngss7_info;
|
||||
ftdm_timer_t *heartbeat_timer;
|
||||
int beat;
|
||||
int counter;
|
||||
ftdm_sched_callback_t callback;
|
||||
ftdm_sched_t *sched;
|
||||
void *sngss7_info;
|
||||
}sngss7_timer_data_t;
|
||||
|
||||
typedef struct sngss7_glare_data {
|
||||
uint32_t suInstId;
|
||||
uint32_t spInstId;
|
||||
uint32_t circuit;
|
||||
SiConEvnt iam;
|
||||
uint32_t spInstId;
|
||||
uint32_t circuit;
|
||||
SiConEvnt iam;
|
||||
}sngss7_glare_data_t;
|
||||
|
||||
typedef struct sngss7_group_data {
|
||||
|
@ -104,56 +332,123 @@ typedef struct sngss7_group_data {
|
|||
}sngss7_group_data_t;
|
||||
|
||||
typedef struct sngss7_chan_data {
|
||||
ftdm_channel_t *ftdmchan;
|
||||
sng_isupCircuit_t *circuit;
|
||||
uint32_t suInstId;
|
||||
uint32_t spInstId;
|
||||
uint32_t spId;
|
||||
uint8_t globalFlg;
|
||||
uint32_t flags;
|
||||
sngss7_glare_data_t glare;
|
||||
sngss7_timer_data_t t35;
|
||||
sngss7_group_data_t grs;
|
||||
ftdm_channel_t *ftdmchan;
|
||||
sng_isup_ckt_t *circuit;
|
||||
uint32_t base_chan;
|
||||
uint32_t suInstId;
|
||||
uint32_t spInstId;
|
||||
uint32_t spId;
|
||||
uint8_t globalFlg;
|
||||
uint32_t flags;
|
||||
sngss7_glare_data_t glare;
|
||||
sngss7_timer_data_t t35;
|
||||
}sngss7_chan_data_t;
|
||||
|
||||
typedef struct sngss7_span_data {
|
||||
ftdm_sched_t *sched;
|
||||
sngss7_group_data_t rx_grs;
|
||||
sngss7_group_data_t tx_grs;
|
||||
ftdm_queue_t *event_queue;
|
||||
}sngss7_span_data_t;
|
||||
|
||||
typedef struct sngss7_event_data
|
||||
{
|
||||
uint32_t event_id;
|
||||
uint32_t spId;
|
||||
uint32_t suId;
|
||||
uint32_t spInstId;
|
||||
uint32_t suInstId;
|
||||
uint32_t circuit;
|
||||
uint8_t globalFlg;
|
||||
uint8_t evntType;
|
||||
union
|
||||
{
|
||||
SiConEvnt siConEvnt;
|
||||
SiCnStEvnt siCnStEvnt;
|
||||
SiRelEvnt siRelEvnt;
|
||||
SiInfoEvnt siInfoEvnt;
|
||||
SiFacEvnt siFacEvnt;
|
||||
SiStaEvnt siStaEvnt;
|
||||
} event;
|
||||
} sngss7_event_data_t;
|
||||
|
||||
|
||||
|
||||
|
||||
typedef enum {
|
||||
FLAG_RESET_RX = (1 << 0),
|
||||
FLAG_RESET_TX = (1 << 1),
|
||||
FLAG_GRP_RESET_RX = (1 << 2),
|
||||
FLAG_GRP_RESET_TX = (1 << 3),
|
||||
FLAG_REMOTE_REL = (1 << 4),
|
||||
FLAG_LOCAL_REL = (1 << 5),
|
||||
FLAG_GLARE = (1 << 6),
|
||||
FLAG_INFID_RESUME = (1 << 17),
|
||||
FLAG_INFID_PAUSED = (1 << 18),
|
||||
FLAG_CKT_MN_BLOCK_RX = (1 << 19),
|
||||
FLAG_CKT_MN_BLOCK_TX = (1 << 20),
|
||||
FLAG_CKT_MN_UNBLK_RX = (1 << 21),
|
||||
FLAG_CKT_MN_UNBLK_TX = (1 << 22),
|
||||
FLAG_GRP_HW_BLOCK_RX = (1 << 23),
|
||||
FLAG_GRP_HW_BLOCK_TX = (1 << 24),
|
||||
FLAG_GRP_MN_BLOCK_RX = (1 << 25),
|
||||
FLAG_GRP_MN_BLOCK_TX = (1 << 28),
|
||||
FLAG_GRP_HW_UNBLK_RX = (1 << 27),
|
||||
FLAG_GRP_HW_UNBLK_TX = (1 << 28),
|
||||
FLAG_GRP_MN_UNBLK_RX = (1 << 29),
|
||||
FLAG_GRP_MN_UNBLK_TX = (1 << 30)
|
||||
FLAG_RESET_RX = (1 << 0),
|
||||
FLAG_RESET_TX = (1 << 1),
|
||||
FLAG_RESET_SENT = (1 << 2),
|
||||
FLAG_RESET_TX_RSP = (1 << 3),
|
||||
FLAG_GRP_RESET_RX = (1 << 4),
|
||||
FLAG_GRP_RESET_RX_DN = (1 << 5),
|
||||
FLAG_GRP_RESET_RX_CMPLT = (1 << 6),
|
||||
FLAG_GRP_RESET_BASE = (1 << 7),
|
||||
FLAG_GRP_RESET_TX = (1 << 8),
|
||||
FLAG_GRP_RESET_SENT = (1 << 9),
|
||||
FLAG_GRP_RESET_TX_RSP = (1 << 10),
|
||||
FLAG_REMOTE_REL = (1 << 11),
|
||||
FLAG_LOCAL_REL = (1 << 12),
|
||||
FLAG_GLARE = (1 << 13),
|
||||
FLAG_INFID_RESUME = (1 << 14),
|
||||
FLAG_INFID_PAUSED = (1 << 15),
|
||||
FLAG_CKT_UCIC_BLOCK = (1 << 16),
|
||||
FLAG_CKT_UCIC_UNBLK = (1 << 17),
|
||||
FLAG_CKT_LC_BLOCK_RX = (1 << 18),
|
||||
FLAG_CKT_LC_UNBLK_RX = (1 << 19),
|
||||
FLAG_CKT_MN_BLOCK_RX = (1 << 20),
|
||||
FLAG_CKT_MN_BLOCK_TX = (1 << 21),
|
||||
FLAG_CKT_MN_UNBLK_RX = (1 << 22),
|
||||
FLAG_CKT_MN_UNBLK_TX = (1 << 23),
|
||||
FLAG_GRP_HW_BLOCK_RX = (1 << 24),
|
||||
FLAG_GRP_HW_BLOCK_TX = (1 << 25),
|
||||
FLAG_GRP_MN_BLOCK_RX = (1 << 26),
|
||||
FLAG_GRP_MN_BLOCK_TX = (1 << 27),
|
||||
FLAG_GRP_HW_UNBLK_RX = (1 << 28),
|
||||
FLAG_GRP_HW_UNBLK_TX = (1 << 29),
|
||||
FLAG_GRP_MN_UNBLK_RX = (1 << 30),
|
||||
FLAG_GRP_MN_UNBLK_TX = (1 << 31)
|
||||
} flag_t;
|
||||
/******************************************************************************/
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
extern ftdm_sngss7_data_t g_ftdm_sngss7_data;
|
||||
extern uint32_t sngss7_id;
|
||||
extern ftdm_sched_t *sngss7_sched;
|
||||
extern uint32_t sngss7_id;
|
||||
extern ftdm_sched_t *sngss7_sched;
|
||||
/******************************************************************************/
|
||||
|
||||
/* PROTOTYPES *****************************************************************/
|
||||
void handle_sng_log(uint8_t level, char *fmt,...);
|
||||
void handle_sng_alarm(sng_alrm_t t_alarm);
|
||||
void handle_sng_mtp1_alarm(Pst *pst, L1Mngmt *sta);
|
||||
void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta);
|
||||
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);
|
||||
|
||||
int ft_to_sngss7_cfg_all(void);
|
||||
int ftmod_ss7_mtp1_gen_config(void);
|
||||
int ftmod_ss7_mtp2_gen_config(void);
|
||||
int ftmod_ss7_mtp3_gen_config(void);
|
||||
int ftmod_ss7_isup_gen_config(void);
|
||||
int ftmod_ss7_cc_gen_config(void);
|
||||
int ftmod_ss7_mtp1_psap_config(int id);
|
||||
int ftmod_ss7_mtp2_dlsap_config(int id);
|
||||
int ftmod_ss7_mtp3_dlsap_config(int id);
|
||||
int ftmod_ss7_mtp3_nsap_config(int id);
|
||||
int ftmod_ss7_mtp3_linkset_config(int id);
|
||||
int ftmod_ss7_mtp3_route_config(int id);
|
||||
int ftmod_ss7_isup_nsap_config(int id);
|
||||
int ftmod_ss7_isup_intf_config(int id);
|
||||
int ftmod_ss7_isup_ckt_config(int id);
|
||||
int ftmod_ss7_isup_isap_config(int id);
|
||||
int ftmod_ss7_cc_isap_config(int id);
|
||||
|
||||
int ftmod_ss7_inhibit_mtplink(uint32_t id);
|
||||
int ftmod_ss7_uninhibit_mtplink(uint32_t id);
|
||||
|
||||
int ftmod_ss7_mtplink_sta(uint32_t id, SnMngmt *cfm);
|
||||
int ftmod_ss7_mtplinkSet_sta(uint32_t id, SnMngmt *cfm);
|
||||
|
||||
int ft_to_sngss7_cfg(void);
|
||||
int ft_to_sngss7_activate_all(void);
|
||||
|
||||
void ft_to_sngss7_iam(ftdm_channel_t *ftdmchan);
|
||||
|
@ -169,6 +464,7 @@ void ft_to_sngss7_ubl(ftdm_channel_t *ftdmchan);
|
|||
void ft_to_sngss7_uba(ftdm_channel_t *ftdmchan);
|
||||
void ft_to_sngss7_lpa(ftdm_channel_t *ftdmchan);
|
||||
void ft_to_sngss7_gra(ftdm_channel_t *ftdmchan);
|
||||
void ft_to_sngss7_grs(ftdm_channel_t *ftdmchan);
|
||||
|
||||
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);
|
||||
|
@ -182,12 +478,44 @@ void sngss7_fac_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint
|
|||
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);
|
||||
|
||||
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);
|
||||
ftdm_status_t handle_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt);
|
||||
ftdm_status_t handle_rel_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiRelEvnt *siRelEvnt);
|
||||
ftdm_status_t handle_dat_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiInfoEvnt *siInfoEvnt);
|
||||
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_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);
|
||||
ftdm_status_t handle_pause(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
|
||||
ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
|
||||
ftdm_status_t handle_cot_start(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
|
||||
ftdm_status_t handle_cot_stop(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
|
||||
ftdm_status_t handle_cot(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
|
||||
ftdm_status_t handle_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
|
||||
ftdm_status_t handle_local_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
|
||||
ftdm_status_t handle_rsc_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
|
||||
ftdm_status_t handle_grs_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
|
||||
ftdm_status_t handle_grs_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
|
||||
ftdm_status_t handle_blo_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
|
||||
ftdm_status_t handle_blo_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
|
||||
ftdm_status_t handle_ubl_req(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
|
||||
ftdm_status_t handle_ubl_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
|
||||
ftdm_status_t handle_local_blk(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
|
||||
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);
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
|
@ -199,11 +527,17 @@ ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const cha
|
|||
/******************************************************************************/
|
||||
|
||||
/* MACROS *********************************************************************/
|
||||
#define SS7_DEBUG(a,...) ftdm_log(FTDM_LOG_DEBUG,a,##__VA_ARGS__ );
|
||||
#define SS7_INFO(a,...) ftdm_log(FTDM_LOG_INFO,a,##__VA_ARGS__ );
|
||||
#define SS7_WARN(a,...) ftdm_log(FTDM_LOG_WARNING,a,##__VA_ARGS__ );
|
||||
#define SS7_ERROR(a,...) ftdm_log(FTDM_LOG_ERROR,a,##__VA_ARGS__ );
|
||||
#define SS7_CRITICAL(a,...) ftdm_log(FTDM_LOG_CRIT,a,##__VA_ARGS__ );
|
||||
#define SS7_DEBUG(a,...) ftdm_log(FTDM_LOG_DEBUG,a , ##__VA_ARGS__ );
|
||||
#define SS7_INFO(a,...) ftdm_log(FTDM_LOG_INFO,a , ##__VA_ARGS__ );
|
||||
#define SS7_WARN(a,...) ftdm_log(FTDM_LOG_WARNING,a , ##__VA_ARGS__ );
|
||||
#define SS7_ERROR(a,...) ftdm_log(FTDM_LOG_ERROR,a , ##__VA_ARGS__ );
|
||||
#define SS7_CRITICAL(a,...) ftdm_log(FTDM_LOG_CRIT,a , ##__VA_ARGS__ );
|
||||
|
||||
#define SS7_DEBUG_CHAN(fchan, msg, args...) ftdm_log_chan(fchan, FTDM_LOG_DEBUG, msg , ##args)
|
||||
#define SS7_INFO_CHAN(fchan, msg, args...) ftdm_log_chan(fchan, FTDM_LOG_INFO, msg , ##args)
|
||||
#define SS7_WARN_CHAN(fchan, msg, args...) ftdm_log_chan(fchan, FTDM_LOG_WARNING, msg , ##args)
|
||||
#define SS7_ERROR_CHAN(fchan, msg, args...) ftdm_log_chan(fchan, FTDM_LOG_ERROR, msg , ##args)
|
||||
#define SS7_CTRIT_CHAN(fchan, msg, args...) ftdm_log_chan(fchan, FTDM_LOG_CRIT, msg , ##args)
|
||||
|
||||
#ifdef KONRAD_DEVEL
|
||||
#define SS7_DEVEL_DEBUG(a,...) ftdm_log(FTDM_LOG_DEBUG,a,##__VA_ARGS__ );
|
||||
|
@ -212,107 +546,130 @@ ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const cha
|
|||
#endif
|
||||
|
||||
#define SS7_FUNC_TRACE_ENTER(a) if (g_ftdm_sngss7_data.function_trace) { \
|
||||
switch (g_ftdm_sngss7_data.function_trace_level) { \
|
||||
case 0: \
|
||||
ftdm_log(FTDM_LOG_EMERG,"Entering %s\n", a); \
|
||||
break; \
|
||||
case 1: \
|
||||
ftdm_log(FTDM_LOG_ALERT,"Entering %s\n", a); \
|
||||
break; \
|
||||
case 2: \
|
||||
ftdm_log(FTDM_LOG_CRIT,"Entering %s\n", a); \
|
||||
break; \
|
||||
case 3: \
|
||||
ftdm_log(FTDM_LOG_ERROR,"Entering %s\n", a); \
|
||||
break; \
|
||||
case 4: \
|
||||
ftdm_log(FTDM_LOG_WARNING,"Entering %s\n", a); \
|
||||
break; \
|
||||
case 5: \
|
||||
ftdm_log(FTDM_LOG_NOTICE,"Entering %s\n", a); \
|
||||
break; \
|
||||
case 6: \
|
||||
ftdm_log(FTDM_LOG_INFO,"Entering %s\n", a); \
|
||||
break; \
|
||||
case 7: \
|
||||
ftdm_log(FTDM_LOG_DEBUG,"Entering %s\n", a); \
|
||||
break; \
|
||||
default: \
|
||||
ftdm_log(FTDM_LOG_INFO,"Entering %s\n", a); \
|
||||
break; \
|
||||
} /* switch (g_ftdm_sngss7_data.function_trace_level) */ \
|
||||
} /* if(g_ftdm_sngss7_data.function_trace) */
|
||||
switch (g_ftdm_sngss7_data.function_trace_level) { \
|
||||
case 0: \
|
||||
ftdm_log(FTDM_LOG_EMERG,"Entering %s\n", a); \
|
||||
break; \
|
||||
case 1: \
|
||||
ftdm_log(FTDM_LOG_ALERT,"Entering %s\n", a); \
|
||||
break; \
|
||||
case 2: \
|
||||
ftdm_log(FTDM_LOG_CRIT,"Entering %s\n", a); \
|
||||
break; \
|
||||
case 3: \
|
||||
ftdm_log(FTDM_LOG_ERROR,"Entering %s\n", a); \
|
||||
break; \
|
||||
case 4: \
|
||||
ftdm_log(FTDM_LOG_WARNING,"Entering %s\n", a); \
|
||||
break; \
|
||||
case 5: \
|
||||
ftdm_log(FTDM_LOG_NOTICE,"Entering %s\n", a); \
|
||||
break; \
|
||||
case 6: \
|
||||
ftdm_log(FTDM_LOG_INFO,"Entering %s\n", a); \
|
||||
break; \
|
||||
case 7: \
|
||||
ftdm_log(FTDM_LOG_DEBUG,"Entering %s\n", a); \
|
||||
break; \
|
||||
default: \
|
||||
ftdm_log(FTDM_LOG_INFO,"Entering %s\n", a); \
|
||||
break; \
|
||||
} /* switch (g_ftdm_sngss7_data.function_trace_level) */ \
|
||||
} /* if(g_ftdm_sngss7_data.function_trace) */
|
||||
|
||||
#define SS7_FUNC_TRACE_EXIT(a) if (g_ftdm_sngss7_data.function_trace) { \
|
||||
switch (g_ftdm_sngss7_data.function_trace_level) { \
|
||||
case 0: \
|
||||
ftdm_log(FTDM_LOG_EMERG,"Exitting %s\n", a); \
|
||||
break; \
|
||||
case 1: \
|
||||
ftdm_log(FTDM_LOG_ALERT,"Exitting %s\n", a); \
|
||||
break; \
|
||||
case 2: \
|
||||
ftdm_log(FTDM_LOG_CRIT,"Exitting %s\n", a); \
|
||||
break; \
|
||||
case 3: \
|
||||
ftdm_log(FTDM_LOG_ERROR,"Exitting %s\n", a); \
|
||||
break; \
|
||||
case 4: \
|
||||
ftdm_log(FTDM_LOG_WARNING,"Exitting %s\n", a); \
|
||||
break; \
|
||||
case 5: \
|
||||
ftdm_log(FTDM_LOG_NOTICE,"Exitting %s\n", a); \
|
||||
break; \
|
||||
case 6: \
|
||||
ftdm_log(FTDM_LOG_INFO,"Exitting %s\n", a); \
|
||||
break; \
|
||||
case 7: \
|
||||
ftdm_log(FTDM_LOG_DEBUG,"Exitting %s\n", a); \
|
||||
break; \
|
||||
default: \
|
||||
ftdm_log(FTDM_LOG_INFO,"Exitting %s\n", a); \
|
||||
break; \
|
||||
} /* switch (g_ftdm_sngss7_data.function_trace_level) */ \
|
||||
} /* if(g_ftdm_sngss7_data.function_trace) */
|
||||
switch (g_ftdm_sngss7_data.function_trace_level) { \
|
||||
case 0: \
|
||||
ftdm_log(FTDM_LOG_EMERG,"Exitting %s\n", a); \
|
||||
break; \
|
||||
case 1: \
|
||||
ftdm_log(FTDM_LOG_ALERT,"Exitting %s\n", a); \
|
||||
break; \
|
||||
case 2: \
|
||||
ftdm_log(FTDM_LOG_CRIT,"Exitting %s\n", a); \
|
||||
break; \
|
||||
case 3: \
|
||||
ftdm_log(FTDM_LOG_ERROR,"Exitting %s\n", a); \
|
||||
break; \
|
||||
case 4: \
|
||||
ftdm_log(FTDM_LOG_WARNING,"Exitting %s\n", a); \
|
||||
break; \
|
||||
case 5: \
|
||||
ftdm_log(FTDM_LOG_NOTICE,"Exitting %s\n", a); \
|
||||
break; \
|
||||
case 6: \
|
||||
ftdm_log(FTDM_LOG_INFO,"Exitting %s\n", a); \
|
||||
break; \
|
||||
case 7: \
|
||||
ftdm_log(FTDM_LOG_DEBUG,"Exitting %s\n", a); \
|
||||
break; \
|
||||
default: \
|
||||
ftdm_log(FTDM_LOG_INFO,"Exitting %s\n", a); \
|
||||
break; \
|
||||
} /* switch (g_ftdm_sngss7_data.function_trace_level) */ \
|
||||
} /* if(g_ftdm_sngss7_data.function_trace) */
|
||||
|
||||
#define SS7_MSG_TRACE(a,...) if (g_ftdm_sngss7_data.message_trace) { \
|
||||
switch (g_ftdm_sngss7_data.message_trace_level) { \
|
||||
case 0: \
|
||||
ftdm_log(FTDM_LOG_EMERG,a,##__VA_ARGS__ ); \
|
||||
break; \
|
||||
case 1: \
|
||||
ftdm_log(FTDM_LOG_ALERT,a,##__VA_ARGS__ ); \
|
||||
break; \
|
||||
case 2: \
|
||||
ftdm_log(FTDM_LOG_CRIT,a,##__VA_ARGS__ ); \
|
||||
break; \
|
||||
case 3: \
|
||||
ftdm_log(FTDM_LOG_ERROR,a,##__VA_ARGS__ ); \
|
||||
break; \
|
||||
case 4: \
|
||||
ftdm_log(FTDM_LOG_WARNING,a,##__VA_ARGS__ ); \
|
||||
break; \
|
||||
case 5: \
|
||||
ftdm_log(FTDM_LOG_NOTICE,a,##__VA_ARGS__ ); \
|
||||
break; \
|
||||
case 6: \
|
||||
ftdm_log(FTDM_LOG_INFO,a,##__VA_ARGS__ ); \
|
||||
break; \
|
||||
case 7: \
|
||||
ftdm_log(FTDM_LOG_DEBUG,a,##__VA_ARGS__ ); \
|
||||
break; \
|
||||
default: \
|
||||
ftdm_log(FTDM_LOG_INFO,a,##__VA_ARGS__ ); \
|
||||
break; \
|
||||
} /* switch (g_ftdm_sngss7_data.message_trace_level) */ \
|
||||
} /* if(g_ftdm_sngss7_data.message_trace) */
|
||||
#define SS7_MSG_TRACE(fchan, sngss7info ,msg) if (g_ftdm_sngss7_data.message_trace) { \
|
||||
switch (g_ftdm_sngss7_data.message_trace_level) { \
|
||||
case 0: \
|
||||
ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "[CIC:%d][SPINSTID:%d][SUINSTID:%d]%s", \
|
||||
sngss7info->circuit->cic,sngss7info->spInstId,sngss7info->suInstId, msg); \
|
||||
break; \
|
||||
case 1: \
|
||||
ftdm_log_chan(fchan, FTDM_LOG_ALERT, "[CIC:%d][SPINSTID:%d][SUINSTID:%d]%s", \
|
||||
sngss7info->circuit->cic,sngss7info->spInstId,sngss7info->suInstId, msg); \
|
||||
break; \
|
||||
case 2: \
|
||||
ftdm_log_chan(fchan, FTDM_LOG_CRIT, "[CIC:%d][SPINSTID:%d][SUINSTID:%d]%s", \
|
||||
sngss7info->circuit->cic,sngss7info->spInstId,sngss7info->suInstId, msg); \
|
||||
break; \
|
||||
case 3: \
|
||||
ftdm_log_chan(fchan, FTDM_LOG_ERROR, "[CIC:%d][SPINSTID:%d][SUINSTID:%d]%s", \
|
||||
sngss7info->circuit->cic,sngss7info->spInstId,sngss7info->suInstId, msg); \
|
||||
break; \
|
||||
case 4: \
|
||||
ftdm_log_chan(fchan, FTDM_LOG_WARNING, "[CIC:%d][SPINSTID:%d][SUINSTID:%d]%s", \
|
||||
sngss7info->circuit->cic,sngss7info->spInstId,sngss7info->suInstId, msg); \
|
||||
break; \
|
||||
case 5: \
|
||||
ftdm_log_chan(fchan, FTDM_LOG_NOTICE, "[CIC:%d][SPINSTID:%d][SUINSTID:%d]%s", \
|
||||
sngss7info->circuit->cic,sngss7info->spInstId,sngss7info->suInstId, msg); \
|
||||
break; \
|
||||
case 6: \
|
||||
ftdm_log_chan(fchan, FTDM_LOG_INFO, "[CIC:%d][SPINSTID:%d][SUINSTID:%d]%s", \
|
||||
sngss7info->circuit->cic,sngss7info->spInstId,sngss7info->suInstId, msg); \
|
||||
break; \
|
||||
case 7: \
|
||||
ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "[CIC:%d][SPINSTID:%d][SUINSTID:%d]%s", \
|
||||
sngss7info->circuit->cic,sngss7info->spInstId,sngss7info->suInstId, msg); \
|
||||
break; \
|
||||
default: \
|
||||
ftdm_log_chan(fchan, FTDM_LOG_INFO, "[CIC:%d][SPINSTID:%d][SUINSTID:%d]%s", \
|
||||
sngss7info->circuit->cic,sngss7info->spInstId,sngss7info->suInstId, msg); \
|
||||
break; \
|
||||
} /* switch (g_ftdm_sngss7_data.message_trace_level) */ \
|
||||
} /* if(g_ftdm_sngss7_data.message_trace) */
|
||||
|
||||
#define sngss7_test_flag(obj, flag) ((obj)->flags & flag)
|
||||
#define sngss7_clear_flag(obj, flag) ((obj)->flags &= ~(flag))
|
||||
#define sngss7_set_flag(obj, flag) ((obj)->flags |= (flag))
|
||||
|
||||
# define SS7_ASSERT *(int*)0=0;
|
||||
/******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
#endif /* __FTMOD_SNG_SS7_H__ */
|
||||
/******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
* indent-tabs-mode:t
|
||||
* tab-width:4
|
||||
* c-basic-offset:4
|
||||
* End:
|
||||
* For VIM:
|
||||
* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
|
||||
*/
|
||||
/******************************************************************************/
|
||||
|
|
|
@ -42,393 +42,449 @@
|
|||
/******************************************************************************/
|
||||
|
||||
/* PROTOTYPES *****************************************************************/
|
||||
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);
|
||||
void ft_to_sngss7_rel(ftdm_channel_t *ftdmchan);
|
||||
void ft_to_sngss7_rlc(ftdm_channel_t *ftdmchan);
|
||||
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);
|
||||
void ft_to_sngss7_rel (ftdm_channel_t * ftdmchan);
|
||||
void ft_to_sngss7_rlc (ftdm_channel_t * ftdmchan);
|
||||
|
||||
void ft_to_sngss7_rsc(ftdm_channel_t *ftdmchan);
|
||||
void ft_to_sngss7_rsca(ftdm_channel_t *ftdmchan);
|
||||
void ft_to_sngss7_rsc (ftdm_channel_t * ftdmchan);
|
||||
void ft_to_sngss7_rsca (ftdm_channel_t * ftdmchan);
|
||||
|
||||
void ft_to_sngss7_blo(ftdm_channel_t *ftdmchan);
|
||||
void ft_to_sngss7_bla(ftdm_channel_t *ftdmchan);
|
||||
void ft_to_sngss7_ubl(ftdm_channel_t *ftdmchan);
|
||||
void ft_to_sngss7_uba(ftdm_channel_t *ftdmchan);
|
||||
void ft_to_sngss7_blo (ftdm_channel_t * ftdmchan);
|
||||
void ft_to_sngss7_bla (ftdm_channel_t * ftdmchan);
|
||||
void ft_to_sngss7_ubl (ftdm_channel_t * ftdmchan);
|
||||
void ft_to_sngss7_uba (ftdm_channel_t * ftdmchan);
|
||||
|
||||
void ft_to_sngss7_lpa(ftdm_channel_t *ftdmchan);
|
||||
void ft_to_sngss7_lpa (ftdm_channel_t * ftdmchan);
|
||||
|
||||
void ft_to_sngss7_gra (ftdm_channel_t * ftdmchan);
|
||||
void ft_to_sngss7_grs (ftdm_channel_t * ftdmchan);
|
||||
/******************************************************************************/
|
||||
|
||||
void ft_to_sngss7_gra(ftdm_channel_t *ftdmchan);
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
void ft_to_sngss7_iam(ftdm_channel_t *ftdmchan)
|
||||
void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
|
||||
{
|
||||
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;;
|
||||
SiConEvnt iam;
|
||||
|
||||
sngss7_info->suInstId = get_unique_id();
|
||||
sngss7_info->spInstId = 0;
|
||||
sngss7_info->spId = 1;
|
||||
|
||||
memset(&iam, 0x0, sizeof(iam));
|
||||
|
||||
/* copy down the nature of connection indicators */
|
||||
iam.natConInd.eh.pres = PRSNT_NODEF;
|
||||
iam.natConInd.satInd.pres = PRSNT_NODEF;
|
||||
iam.natConInd.satInd.val = 0;
|
||||
iam.natConInd.contChkInd.pres = PRSNT_NODEF;
|
||||
iam.natConInd.contChkInd.val = 0x00;
|
||||
iam.natConInd.echoCntrlDevInd.pres = PRSNT_NODEF;
|
||||
iam.natConInd.echoCntrlDevInd.val = 0x01;
|
||||
|
||||
/* copy down the forward call indicators */
|
||||
iam.fwdCallInd.eh.pres = PRSNT_NODEF;
|
||||
iam.fwdCallInd.natIntCallInd.pres = PRSNT_NODEF;
|
||||
iam.fwdCallInd.natIntCallInd.val = 0x00;
|
||||
iam.fwdCallInd.end2EndMethInd.pres = PRSNT_NODEF;
|
||||
iam.fwdCallInd.end2EndMethInd.val = 0x00;
|
||||
iam.fwdCallInd.intInd.pres = PRSNT_NODEF;
|
||||
iam.fwdCallInd.intInd.val = 0x01;
|
||||
iam.fwdCallInd.end2EndInfoInd.pres = PRSNT_NODEF;
|
||||
iam.fwdCallInd.end2EndInfoInd.val = 0x00;
|
||||
iam.fwdCallInd.isdnUsrPrtInd.pres = PRSNT_NODEF;
|
||||
iam.fwdCallInd.isdnUsrPrtInd.val = 0x01;
|
||||
iam.fwdCallInd.isdnUsrPrtPrfInd.pres = PRSNT_NODEF;
|
||||
iam.fwdCallInd.isdnUsrPrtPrfInd.val = 0x02;
|
||||
iam.fwdCallInd.isdnAccInd.pres = PRSNT_NODEF;
|
||||
iam.fwdCallInd.isdnAccInd.val = 0x01;
|
||||
iam.fwdCallInd.sccpMethInd.pres = PRSNT_NODEF;
|
||||
iam.fwdCallInd.sccpMethInd.val = 0x00;
|
||||
|
||||
/* copy down the calling number information */
|
||||
iam.cgPtyCat.eh.pres = PRSNT_NODEF;
|
||||
iam.cgPtyCat.cgPtyCat.pres = PRSNT_NODEF;
|
||||
iam.cgPtyCat.cgPtyCat.val = 0x0a;
|
||||
|
||||
/* copy down the transmission medium requirements */
|
||||
iam.txMedReq.eh.pres = PRSNT_NODEF;
|
||||
iam.txMedReq.trMedReq.pres = PRSNT_NODEF;
|
||||
iam.txMedReq.trMedReq.val = 0; /* SPEECH = 0, 3.1Khz = 3, 64k unres = 2 */
|
||||
|
||||
/* copy down the called number information */
|
||||
copy_cdPtyNum_to_sngss7(&ftdmchan->caller_data, &iam.cdPtyNum);
|
||||
|
||||
/* copy down the calling number information */
|
||||
copy_cgPtyNum_to_sngss7(&ftdmchan->caller_data, &iam.cgPtyNum);
|
||||
|
||||
sng_cc_con_request(sngss7_info->spId,
|
||||
sngss7_info->suInstId,
|
||||
sngss7_info->spInstId,
|
||||
sngss7_info->circuit->id,
|
||||
&iam,
|
||||
0);
|
||||
|
||||
SS7_MSG_TRACE("Transmitted IAM on CIC # %d\n", sngss7_info->circuit->cic);
|
||||
|
||||
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
/******************************************************************************/
|
||||
|
||||
void ft_to_sngss7_acm(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
SiCnStEvnt acm;
|
||||
|
||||
memset(&acm, 0x0, sizeof(acm));
|
||||
|
||||
/* fill in the needed information for the ACM */
|
||||
acm.bckCallInd.eh.pres = PRSNT_NODEF;
|
||||
acm.bckCallInd.chrgInd.pres = PRSNT_NODEF;
|
||||
acm.bckCallInd.chrgInd.val = 0x00;
|
||||
acm.bckCallInd.cadPtyStatInd.pres = PRSNT_NODEF;
|
||||
acm.bckCallInd.cadPtyStatInd.val = 0x01;
|
||||
acm.bckCallInd.cadPtyCatInd.pres = PRSNT_NODEF;
|
||||
acm.bckCallInd.cadPtyCatInd.val = 0x00;
|
||||
acm.bckCallInd.end2EndMethInd.pres = PRSNT_NODEF;
|
||||
acm.bckCallInd.end2EndMethInd.val = 0x00;
|
||||
acm.bckCallInd.intInd.pres = PRSNT_NODEF;
|
||||
acm.bckCallInd.intInd.val = 0x00;
|
||||
acm.bckCallInd.end2EndInfoInd.pres = PRSNT_NODEF;
|
||||
acm.bckCallInd.end2EndInfoInd.val = 0x00;
|
||||
acm.bckCallInd.isdnUsrPrtInd.pres = PRSNT_NODEF;
|
||||
acm.bckCallInd.isdnUsrPrtInd.val = 0x0;
|
||||
acm.bckCallInd.holdInd.pres = PRSNT_NODEF;
|
||||
acm.bckCallInd.holdInd.val = 0x00;
|
||||
acm.bckCallInd.isdnAccInd.pres = PRSNT_NODEF;
|
||||
acm.bckCallInd.isdnAccInd.val = 0x0;
|
||||
acm.bckCallInd.echoCtrlDevInd.pres = PRSNT_NODEF;
|
||||
acm.bckCallInd.echoCtrlDevInd.val = 0x0;
|
||||
acm.bckCallInd.sccpMethInd.pres = PRSNT_NODEF;
|
||||
acm.bckCallInd.sccpMethInd.val = 0x00;
|
||||
|
||||
/* send the ACM request to LibSngSS7 */
|
||||
sng_cc_con_status(1,
|
||||
sngss7_info->suInstId,
|
||||
sngss7_info->spInstId,
|
||||
sngss7_info->circuit->id,
|
||||
&acm,
|
||||
ADDRCMPLT);
|
||||
|
||||
SS7_MSG_TRACE("Transmitted ACM on CIC # %d\n", sngss7_info->circuit->cic);
|
||||
|
||||
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
/******************************************************************************/
|
||||
|
||||
void ft_to_sngss7_anm(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
SiConEvnt anm;
|
||||
|
||||
memset(&anm, 0x0, sizeof(anm));
|
||||
|
||||
/* send the ANM request to LibSngSS7 */
|
||||
sng_cc_con_response(1,
|
||||
sngss7_info->suInstId,
|
||||
sngss7_info->spInstId,
|
||||
sngss7_info->circuit->id,
|
||||
&anm,
|
||||
5);
|
||||
|
||||
SS7_MSG_TRACE("Transmitted ANM on CIC # %d\n", sngss7_info->circuit->cic);
|
||||
|
||||
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
|
||||
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;;
|
||||
SiConEvnt iam;
|
||||
|
||||
sngss7_info->suInstId = get_unique_id ();
|
||||
sngss7_info->spInstId = 0;
|
||||
sngss7_info->spId = 1;
|
||||
|
||||
memset (&iam, 0x0, sizeof (iam));
|
||||
|
||||
/* copy down the nature of connection indicators */
|
||||
iam.natConInd.eh.pres = PRSNT_NODEF;
|
||||
iam.natConInd.satInd.pres = PRSNT_NODEF;
|
||||
iam.natConInd.satInd.val = 0; /* no satellite circuit */
|
||||
iam.natConInd.contChkInd.pres = PRSNT_NODEF;
|
||||
iam.natConInd.contChkInd.val = CONTCHK_NOTREQ;
|
||||
iam.natConInd.echoCntrlDevInd.pres = PRSNT_NODEF;
|
||||
iam.natConInd.echoCntrlDevInd.val = ECHOCDEV_INCL;
|
||||
|
||||
/* copy down the forward call indicators */
|
||||
iam.fwdCallInd.eh.pres = PRSNT_NODEF;
|
||||
iam.fwdCallInd.natIntCallInd.pres = PRSNT_NODEF;
|
||||
iam.fwdCallInd.natIntCallInd.val = 0x00;
|
||||
iam.fwdCallInd.end2EndMethInd.pres = PRSNT_NODEF;
|
||||
iam.fwdCallInd.end2EndMethInd.val = E2EMTH_NOMETH;
|
||||
iam.fwdCallInd.intInd.pres = PRSNT_NODEF;
|
||||
iam.fwdCallInd.intInd.val = INTIND_NOINTW;
|
||||
iam.fwdCallInd.end2EndInfoInd.pres = PRSNT_NODEF;
|
||||
iam.fwdCallInd.end2EndInfoInd.val = E2EINF_NOINFO;
|
||||
iam.fwdCallInd.isdnUsrPrtInd.pres = PRSNT_NODEF;
|
||||
iam.fwdCallInd.isdnUsrPrtInd.val = ISUP_USED;
|
||||
iam.fwdCallInd.isdnUsrPrtPrfInd.pres = PRSNT_NODEF;
|
||||
iam.fwdCallInd.isdnUsrPrtPrfInd.val = PREF_REQAW;
|
||||
iam.fwdCallInd.isdnAccInd.pres = PRSNT_NODEF;
|
||||
iam.fwdCallInd.isdnAccInd.val = ISDNACC_ISDN;
|
||||
iam.fwdCallInd.sccpMethInd.pres = PRSNT_NODEF;
|
||||
iam.fwdCallInd.sccpMethInd.val = SCCPMTH_NOIND;
|
||||
|
||||
/* copy down the calling number information */
|
||||
iam.cgPtyCat.eh.pres = PRSNT_NODEF;
|
||||
iam.cgPtyCat.cgPtyCat.pres = PRSNT_NODEF;
|
||||
iam.cgPtyCat.cgPtyCat.val = CAT_ORD; /* ordinary suscriber */
|
||||
|
||||
/* copy down the transmission medium requirements */
|
||||
iam.txMedReq.eh.pres = PRSNT_NODEF;
|
||||
iam.txMedReq.trMedReq.pres = PRSNT_NODEF;
|
||||
iam.txMedReq.trMedReq.val = ftdmchan->caller_data.bearer_capability;
|
||||
|
||||
/* copy down the called number information */
|
||||
copy_cdPtyNum_to_sngss7 (&ftdmchan->caller_data, &iam.cdPtyNum);
|
||||
|
||||
/* copy down the calling number information */
|
||||
copy_cgPtyNum_to_sngss7 (&ftdmchan->caller_data, &iam.cgPtyNum);
|
||||
|
||||
sng_cc_con_request (sngss7_info->spId,
|
||||
sngss7_info->suInstId,
|
||||
sngss7_info->spInstId,
|
||||
sngss7_info->circuit->id,
|
||||
&iam,
|
||||
0);
|
||||
|
||||
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx IAM\n");
|
||||
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void ft_to_sngss7_rel(ftdm_channel_t *ftdmchan)
|
||||
void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan)
|
||||
{
|
||||
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
SiRelEvnt rel;
|
||||
|
||||
memset(&rel, 0x0, sizeof(rel));
|
||||
|
||||
rel.causeDgn.eh.pres = PRSNT_NODEF;
|
||||
rel.causeDgn.location.pres = PRSNT_NODEF;
|
||||
rel.causeDgn.location.val = 0x01;
|
||||
rel.causeDgn.cdeStand.pres = PRSNT_NODEF;
|
||||
rel.causeDgn.cdeStand.val = 0x00;
|
||||
rel.causeDgn.recommend.pres = NOTPRSNT;
|
||||
rel.causeDgn.causeVal.pres = PRSNT_NODEF;
|
||||
rel.causeDgn.causeVal.val = (uint8_t)ftdmchan->caller_data.hangup_cause;
|
||||
rel.causeDgn.dgnVal.pres = NOTPRSNT;
|
||||
|
||||
/* send the REL request to LibSngSS7 */
|
||||
sng_cc_rel_request(1,
|
||||
sngss7_info->suInstId,
|
||||
sngss7_info->spInstId,
|
||||
sngss7_info->circuit->id,
|
||||
&rel);
|
||||
|
||||
SS7_MSG_TRACE("Transmitted REL on CIC # %d\n", sngss7_info->circuit->cic);
|
||||
|
||||
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
|
||||
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
SiCnStEvnt acm;
|
||||
|
||||
memset (&acm, 0x0, sizeof (acm));
|
||||
|
||||
/* fill in the needed information for the ACM */
|
||||
acm.bckCallInd.eh.pres = PRSNT_NODEF;
|
||||
acm.bckCallInd.chrgInd.pres = PRSNT_NODEF;
|
||||
acm.bckCallInd.chrgInd.val = 0x00;
|
||||
acm.bckCallInd.cadPtyStatInd.pres = PRSNT_NODEF;
|
||||
acm.bckCallInd.cadPtyStatInd.val = 0x01;
|
||||
acm.bckCallInd.cadPtyCatInd.pres = PRSNT_NODEF;
|
||||
acm.bckCallInd.cadPtyCatInd.val = 0x00;
|
||||
acm.bckCallInd.end2EndMethInd.pres = PRSNT_NODEF;
|
||||
acm.bckCallInd.end2EndMethInd.val = 0x00;
|
||||
acm.bckCallInd.intInd.pres = PRSNT_NODEF;
|
||||
acm.bckCallInd.intInd.val = 0x00;
|
||||
acm.bckCallInd.end2EndInfoInd.pres = PRSNT_NODEF;
|
||||
acm.bckCallInd.end2EndInfoInd.val = 0x00;
|
||||
acm.bckCallInd.isdnUsrPrtInd.pres = PRSNT_NODEF;
|
||||
acm.bckCallInd.isdnUsrPrtInd.val = 0x0;
|
||||
acm.bckCallInd.holdInd.pres = PRSNT_NODEF;
|
||||
acm.bckCallInd.holdInd.val = 0x00;
|
||||
acm.bckCallInd.isdnAccInd.pres = PRSNT_NODEF;
|
||||
acm.bckCallInd.isdnAccInd.val = 0x0;
|
||||
acm.bckCallInd.echoCtrlDevInd.pres = PRSNT_NODEF;
|
||||
acm.bckCallInd.echoCtrlDevInd.val = 0x0;
|
||||
acm.bckCallInd.sccpMethInd.pres = PRSNT_NODEF;
|
||||
acm.bckCallInd.sccpMethInd.val = 0x00;
|
||||
|
||||
/* send the ACM request to LibSngSS7 */
|
||||
sng_cc_con_status (1,
|
||||
sngss7_info->suInstId,
|
||||
sngss7_info->spInstId,
|
||||
sngss7_info->circuit->id,
|
||||
&acm,
|
||||
ADDRCMPLT);
|
||||
|
||||
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx ACM\n");
|
||||
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void ft_to_sngss7_rlc(ftdm_channel_t *ftdmchan)
|
||||
void ft_to_sngss7_anm (ftdm_channel_t * ftdmchan)
|
||||
{
|
||||
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
|
||||
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
SiConEvnt anm;
|
||||
|
||||
memset (&anm, 0x0, sizeof (anm));
|
||||
|
||||
/* send the ANM request to LibSngSS7 */
|
||||
sng_cc_con_response(1,
|
||||
sngss7_info->suInstId,
|
||||
sngss7_info->spInstId,
|
||||
sngss7_info->circuit->id,
|
||||
&anm,
|
||||
5);
|
||||
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
SiRelEvnt rlc;
|
||||
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx ANM\n");
|
||||
|
||||
memset(&rlc, 0x0, sizeof(rlc));
|
||||
|
||||
/* send the RLC request to LibSngSS7 */
|
||||
sng_cc_rel_response(1,
|
||||
sngss7_info->suInstId,
|
||||
sngss7_info->spInstId,
|
||||
sngss7_info->circuit->id,
|
||||
&rlc);
|
||||
|
||||
SS7_MSG_TRACE("Transmitted RLC on CIC # %d\n", sngss7_info->circuit->cic);
|
||||
|
||||
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void ft_to_sngss7_rsc(ftdm_channel_t *ftdmchan)
|
||||
void ft_to_sngss7_rel (ftdm_channel_t * ftdmchan)
|
||||
{
|
||||
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
|
||||
sng_cc_sta_request(1,
|
||||
sngss7_info->suInstId,
|
||||
sngss7_info->spInstId,
|
||||
sngss7_info->circuit->id,
|
||||
sngss7_info->globalFlg,
|
||||
SIT_STA_CIRRESREQ,
|
||||
NULL);
|
||||
|
||||
SS7_MSG_TRACE("Transmitted RSC on CIC # %d\n", sngss7_info->circuit->cic);
|
||||
|
||||
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
|
||||
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
SiRelEvnt rel;
|
||||
|
||||
memset (&rel, 0x0, sizeof (rel));
|
||||
|
||||
rel.causeDgn.eh.pres = PRSNT_NODEF;
|
||||
rel.causeDgn.location.pres = PRSNT_NODEF;
|
||||
rel.causeDgn.location.val = 0x01;
|
||||
rel.causeDgn.cdeStand.pres = PRSNT_NODEF;
|
||||
rel.causeDgn.cdeStand.val = 0x00;
|
||||
rel.causeDgn.recommend.pres = NOTPRSNT;
|
||||
rel.causeDgn.causeVal.pres = PRSNT_NODEF;
|
||||
rel.causeDgn.causeVal.val = (uint8_t) ftdmchan->caller_data.hangup_cause;
|
||||
rel.causeDgn.dgnVal.pres = NOTPRSNT;
|
||||
|
||||
/* send the REL request to LibSngSS7 */
|
||||
sng_cc_rel_request (1,
|
||||
sngss7_info->suInstId,
|
||||
sngss7_info->spInstId,
|
||||
sngss7_info->circuit->id,
|
||||
&rel);
|
||||
|
||||
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx REL\n");
|
||||
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void ft_to_sngss7_rsca(ftdm_channel_t *ftdmchan)
|
||||
void ft_to_sngss7_rlc (ftdm_channel_t * ftdmchan)
|
||||
{
|
||||
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
|
||||
sng_cc_sta_request(1,
|
||||
sngss7_info->suInstId,
|
||||
sngss7_info->spInstId,
|
||||
sngss7_info->circuit->id,
|
||||
sngss7_info->globalFlg,
|
||||
SIT_STA_CIRRESRSP,
|
||||
NULL);
|
||||
|
||||
SS7_MSG_TRACE("Transmitted RSC-RLC on CIC # %d\n", sngss7_info->circuit->cic);
|
||||
|
||||
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
|
||||
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
SiRelEvnt rlc;
|
||||
|
||||
memset (&rlc, 0x0, sizeof (rlc));
|
||||
|
||||
/* send the RLC request to LibSngSS7 */
|
||||
sng_cc_rel_response (1,
|
||||
sngss7_info->suInstId,
|
||||
sngss7_info->spInstId,
|
||||
sngss7_info->circuit->id,
|
||||
&rlc);
|
||||
|
||||
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx RLC\n");
|
||||
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void ft_to_sngss7_blo(ftdm_channel_t *ftdmchan)
|
||||
void ft_to_sngss7_rsc (ftdm_channel_t * ftdmchan)
|
||||
{
|
||||
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
|
||||
sng_cc_sta_request(1,
|
||||
0,
|
||||
0,
|
||||
sngss7_info->circuit->id,
|
||||
sngss7_info->globalFlg,
|
||||
SIT_STA_CIRBLOREQ,
|
||||
NULL);
|
||||
|
||||
SS7_MSG_TRACE("Transmitted BLO on CIC # %d\n", sngss7_info->circuit->cic);
|
||||
|
||||
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
|
||||
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
|
||||
sng_cc_sta_request (1,
|
||||
sngss7_info->suInstId,
|
||||
sngss7_info->spInstId,
|
||||
sngss7_info->circuit->id,
|
||||
sngss7_info->globalFlg,
|
||||
SIT_STA_CIRRESREQ,
|
||||
NULL);
|
||||
|
||||
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx RSC\n");
|
||||
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void ft_to_sngss7_bla(ftdm_channel_t *ftdmchan)
|
||||
void ft_to_sngss7_rsca (ftdm_channel_t * ftdmchan)
|
||||
{
|
||||
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
|
||||
sng_cc_sta_request(1,
|
||||
0,
|
||||
0,
|
||||
sngss7_info->circuit->id,
|
||||
sngss7_info->globalFlg,
|
||||
SIT_STA_CIRBLORSP,
|
||||
NULL);
|
||||
|
||||
SS7_MSG_TRACE("Transmitted BLA on CIC # %d\n", sngss7_info->circuit->cic);
|
||||
|
||||
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
|
||||
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
|
||||
sng_cc_sta_request (1,
|
||||
sngss7_info->suInstId,
|
||||
sngss7_info->spInstId,
|
||||
sngss7_info->circuit->id,
|
||||
sngss7_info->globalFlg,
|
||||
SIT_STA_CIRRESRSP,
|
||||
NULL);
|
||||
|
||||
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx RSC-RLC\n");
|
||||
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void ft_to_sngss7_ubl(ftdm_channel_t *ftdmchan)
|
||||
void ft_to_sngss7_blo (ftdm_channel_t * ftdmchan)
|
||||
{
|
||||
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
|
||||
sng_cc_sta_request(1,
|
||||
0,
|
||||
0,
|
||||
sngss7_info->circuit->id,
|
||||
sngss7_info->globalFlg,
|
||||
SIT_STA_CIRUBLREQ,
|
||||
NULL);
|
||||
|
||||
SS7_MSG_TRACE("Transmitted UBL on CIC # %d\n", sngss7_info->circuit->cic);
|
||||
|
||||
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
|
||||
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
|
||||
sng_cc_sta_request (1,
|
||||
0,
|
||||
0,
|
||||
sngss7_info->circuit->id,
|
||||
sngss7_info->globalFlg,
|
||||
SIT_STA_CIRBLOREQ,
|
||||
NULL);
|
||||
|
||||
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx BLO\n");
|
||||
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void ft_to_sngss7_uba(ftdm_channel_t *ftdmchan)
|
||||
void ft_to_sngss7_bla (ftdm_channel_t * ftdmchan)
|
||||
{
|
||||
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
|
||||
sng_cc_sta_request(1,
|
||||
0,
|
||||
0,
|
||||
sngss7_info->circuit->id,
|
||||
sngss7_info->globalFlg,
|
||||
SIT_STA_CIRUBLRSP,
|
||||
NULL);
|
||||
|
||||
SS7_MSG_TRACE("Transmitted UBA on CIC # %d\n", sngss7_info->circuit->cic);
|
||||
|
||||
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
|
||||
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
|
||||
sng_cc_sta_request (1,
|
||||
0,
|
||||
0,
|
||||
sngss7_info->circuit->id,
|
||||
sngss7_info->globalFlg,
|
||||
SIT_STA_CIRBLORSP,
|
||||
NULL);
|
||||
|
||||
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx BLA\n");
|
||||
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void ft_to_sngss7_lpa(ftdm_channel_t *ftdmchan)
|
||||
void
|
||||
ft_to_sngss7_ubl (ftdm_channel_t * ftdmchan)
|
||||
{
|
||||
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
|
||||
sng_cc_sta_request(1,
|
||||
sngss7_info->suInstId,
|
||||
sngss7_info->spInstId,
|
||||
sngss7_info->circuit->id,
|
||||
sngss7_info->globalFlg,
|
||||
SIT_STA_LOOPBACKACK,
|
||||
NULL);
|
||||
|
||||
SS7_MSG_TRACE("Transmitted LPA on CIC # %d\n", sngss7_info->circuit->cic);
|
||||
|
||||
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
|
||||
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
|
||||
sng_cc_sta_request (1,
|
||||
0,
|
||||
0,
|
||||
sngss7_info->circuit->id,
|
||||
sngss7_info->globalFlg,
|
||||
SIT_STA_CIRUBLREQ,
|
||||
NULL);
|
||||
|
||||
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx UBL\n");
|
||||
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void ft_to_sngss7_gra(ftdm_channel_t *ftdmchan)
|
||||
void ft_to_sngss7_uba (ftdm_channel_t * ftdmchan)
|
||||
{
|
||||
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
|
||||
/* get the original channel the message came in on */
|
||||
sngss7_info = g_ftdm_sngss7_data.cfg.isupCircuit[sngss7_info->grs.circuit].obj;
|
||||
|
||||
sng_cc_sta_request(1,
|
||||
0,
|
||||
0,
|
||||
sngss7_info->circuit->id,
|
||||
sngss7_info->globalFlg,
|
||||
SIT_STA_GRSRSP,
|
||||
NULL);
|
||||
|
||||
SS7_MSG_TRACE("Transmitted GRA on CIC # %d\n", sngss7_info->circuit->cic);
|
||||
|
||||
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
|
||||
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
|
||||
sng_cc_sta_request (1,
|
||||
0,
|
||||
0,
|
||||
sngss7_info->circuit->id,
|
||||
sngss7_info->globalFlg,
|
||||
SIT_STA_CIRUBLRSP,
|
||||
NULL);
|
||||
|
||||
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx UBA\n");
|
||||
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void ft_to_sngss7_lpa (ftdm_channel_t * ftdmchan)
|
||||
{
|
||||
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
|
||||
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
|
||||
sng_cc_sta_request (1,
|
||||
sngss7_info->suInstId,
|
||||
sngss7_info->spInstId,
|
||||
sngss7_info->circuit->id,
|
||||
sngss7_info->globalFlg,
|
||||
SIT_STA_LOOPBACKACK,
|
||||
NULL);
|
||||
|
||||
SS7_MSG_TRACE(ftdmchan, sngss7_info, "Tx LPA\n");
|
||||
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void ft_to_sngss7_gra (ftdm_channel_t * ftdmchan)
|
||||
{
|
||||
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
|
||||
|
||||
sngss7_span_data_t *sngss7_span = ftdmchan->span->mod_data;
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
SiStaEvnt gra;
|
||||
|
||||
/* clean out the gra struct */
|
||||
memset (&gra, 0x0, sizeof (gra));
|
||||
|
||||
gra.rangStat.eh.pres = PRSNT_NODEF;
|
||||
|
||||
/* fill in the range */
|
||||
gra.rangStat.range.pres = PRSNT_NODEF;
|
||||
gra.rangStat.range.val = sngss7_span->rx_grs.range;
|
||||
|
||||
/* fill in the status */
|
||||
gra.rangStat.status.pres = PRSNT_NODEF;
|
||||
gra.rangStat.status.len = ((sngss7_span->rx_grs.range + 1) >> 3) + (((sngss7_span->rx_grs.range + 1) & 0x07) ? 1 : 0);
|
||||
|
||||
/* the status field should be 1 if blocked for maintenace reasons
|
||||
* and 0 is not blocked....since we memset the struct nothing to do
|
||||
*/
|
||||
|
||||
/* send the GRA to LibSng-SS7 */
|
||||
sng_cc_sta_request (1,
|
||||
0,
|
||||
0,
|
||||
sngss7_span->rx_grs.circuit,
|
||||
0,
|
||||
SIT_STA_GRSRSP,
|
||||
&gra);
|
||||
|
||||
SS7_INFO_CHAN(ftdmchan, "Tx GRA (%d:%d)\n",
|
||||
sngss7_info->circuit->cic,
|
||||
(sngss7_info->circuit->cic + sngss7_span->rx_grs.range));
|
||||
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void ft_to_sngss7_grs (ftdm_channel_t * ftdmchan)
|
||||
{
|
||||
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
|
||||
|
||||
sngss7_span_data_t *sngss7_span = ftdmchan->span->mod_data;
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
|
||||
SiStaEvnt grs;
|
||||
|
||||
memset (&grs, 0x0, sizeof (grs));
|
||||
|
||||
grs.rangStat.eh.pres = PRSNT_NODEF;
|
||||
grs.rangStat.range.pres = PRSNT_NODEF;
|
||||
grs.rangStat.range.val = sngss7_span->tx_grs.range;
|
||||
|
||||
sng_cc_sta_request (1,
|
||||
0,
|
||||
0,
|
||||
sngss7_span->tx_grs.circuit,
|
||||
0,
|
||||
SIT_STA_GRSREQ,
|
||||
&grs);
|
||||
|
||||
SS7_INFO_CHAN(ftdmchan, "Tx GRS (%d:%d)\n",
|
||||
sngss7_info->circuit->cic,
|
||||
(sngss7_info->circuit->cic + sngss7_span->tx_grs.range));
|
||||
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
|
@ -441,4 +497,3 @@ void ft_to_sngss7_gra(ftdm_channel_t *ftdmchan)
|
|||
* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
|
||||
*/
|
||||
/******************************************************************************/
|
||||
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright (c) 2009 Konrad Hammel <konrad@sangoma.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms|with or without
|
||||
* modification|are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice|this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice|this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES|INCLUDING|BUT NOT
|
||||
* LIMITED TO|THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT|INDIRECT|INCIDENTAL|SPECIAL,
|
||||
* EXEMPLARY|OR CONSEQUENTIAL DAMAGES (INCLUDING|BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE|DATA|OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY|WHETHER IN CONTRACT|STRICT LIABILITY|OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE|EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* INCLUDE ********************************************************************/
|
||||
#include "ftmod_sangoma_ss7_main.h"
|
||||
/******************************************************************************/
|
||||
|
||||
/* DEFINES ********************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/* PROTOTYPES *****************************************************************/
|
||||
int ftmod_ss7_mtplink_sta(uint32_t id, SnMngmt *cfm);
|
||||
int ftmod_ss7_mtplinkSet_sta(uint32_t id, SnMngmt *cfm);
|
||||
/******************************************************************************/
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
int ftmod_ss7_mtplink_sta(uint32_t id, SnMngmt *cfm)
|
||||
{
|
||||
SnMngmt sta;
|
||||
|
||||
memset(&sta, 0x0, sizeof(sta));
|
||||
|
||||
sta.hdr.elmId.elmnt = STDLSAP;
|
||||
sta.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLink[id].id;
|
||||
|
||||
return(sng_sta_mtp3(&sta, cfm));
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
int ftmod_ss7_mtplinkSet_sta(uint32_t id, SnMngmt *cfm)
|
||||
{
|
||||
SnMngmt sta;
|
||||
|
||||
memset(&sta, 0x0, sizeof(sta));
|
||||
|
||||
sta.hdr.elmId.elmnt = STLNKSET;
|
||||
sta.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLinkSet[id].id;
|
||||
sta.hdr.elmId.elmntInst2 = 1;
|
||||
|
||||
return(sng_sta_mtp3(&sta, cfm));
|
||||
}
|
||||
/******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
* indent-tabs-mode:t
|
||||
* tab-width:4
|
||||
* c-basic-offset:4
|
||||
* End:
|
||||
* For VIM:
|
||||
* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
|
||||
*/
|
||||
/******************************************************************************/
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (c) 2009 Konrad Hammel <konrad@sangoma.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms|with or without
|
||||
* modification|are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice|this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice|this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES|INCLUDING|BUT NOT
|
||||
* LIMITED TO|THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT|INDIRECT|INCIDENTAL|SPECIAL,
|
||||
* EXEMPLARY|OR CONSEQUENTIAL DAMAGES (INCLUDING|BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE|DATA|OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY|WHETHER IN CONTRACT|STRICT LIABILITY|OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE|EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* INCLUDE ********************************************************************/
|
||||
#include "ftmod_sangoma_ss7_main.h"
|
||||
/******************************************************************************/
|
||||
|
||||
/* DEFINES ********************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/* PROTOTYPES *****************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
* indent-tabs-mode:t
|
||||
* tab-width:4
|
||||
* c-basic-offset:4
|
||||
* End:
|
||||
* For VIM:
|
||||
* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
|
||||
*/
|
||||
/******************************************************************************/
|
|
@ -50,6 +50,9 @@ 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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
@ -60,309 +63,391 @@ ftdm_status_t extract_chan_data(uint32_t circuit, sngss7_chan_data_t **sngss7_in
|
|||
uint8_t copy_cgPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum)
|
||||
{
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
uint8_t copy_cgPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum)
|
||||
{
|
||||
int k;
|
||||
int j;
|
||||
int flag;
|
||||
char tmp;
|
||||
unsigned char lower;
|
||||
unsigned char upper;
|
||||
int k;
|
||||
int j;
|
||||
int flag;
|
||||
char tmp[2];
|
||||
unsigned char lower;
|
||||
unsigned char upper;
|
||||
|
||||
/**************************************************************************/
|
||||
cgPtyNum->eh.pres = PRSNT_NODEF;
|
||||
/**************************************************************************/
|
||||
cgPtyNum->natAddrInd.pres = PRSNT_NODEF;
|
||||
cgPtyNum->natAddrInd.val = 0x03;
|
||||
/**************************************************************************/
|
||||
cgPtyNum->scrnInd.pres = PRSNT_NODEF;
|
||||
cgPtyNum->scrnInd.val = ftdm->screen;
|
||||
/**************************************************************************/
|
||||
cgPtyNum->presRest.pres = PRSNT_NODEF;
|
||||
cgPtyNum->presRest.val = ftdm->pres;
|
||||
/**************************************************************************/
|
||||
cgPtyNum->numPlan.pres = PRSNT_NODEF;
|
||||
cgPtyNum->numPlan.val = 0x01;
|
||||
/**************************************************************************/
|
||||
cgPtyNum->niInd.pres = PRSNT_NODEF;
|
||||
cgPtyNum->niInd.val = 0x00;
|
||||
/**************************************************************************/
|
||||
cgPtyNum->addrSig.pres = PRSNT_NODEF;
|
||||
/**************************************************************************/
|
||||
cgPtyNum->eh.pres = PRSNT_NODEF;
|
||||
/**************************************************************************/
|
||||
cgPtyNum->natAddrInd.pres = PRSNT_NODEF;
|
||||
cgPtyNum->natAddrInd.val = 0x03;
|
||||
/**************************************************************************/
|
||||
cgPtyNum->scrnInd.pres = PRSNT_NODEF;
|
||||
cgPtyNum->scrnInd.val = ftdm->screen;
|
||||
/**************************************************************************/
|
||||
cgPtyNum->presRest.pres = PRSNT_NODEF;
|
||||
cgPtyNum->presRest.val = ftdm->pres;
|
||||
/**************************************************************************/
|
||||
cgPtyNum->numPlan.pres = PRSNT_NODEF;
|
||||
cgPtyNum->numPlan.val = 0x01;
|
||||
/**************************************************************************/
|
||||
cgPtyNum->niInd.pres = PRSNT_NODEF;
|
||||
cgPtyNum->niInd.val = 0x00;
|
||||
/**************************************************************************/
|
||||
cgPtyNum->addrSig.pres = PRSNT_NODEF;
|
||||
|
||||
k = 0;
|
||||
j = 0;
|
||||
flag = 0;
|
||||
while (1) {
|
||||
tmp = ftdm->cid_num.digits[k];
|
||||
if (tmp != '\0') {
|
||||
if (isdigit(tmp)) {
|
||||
lower = atoi(&tmp);
|
||||
k++;
|
||||
tmp = ftdm->cid_num.digits[k];
|
||||
} else {
|
||||
while (!(isdigit(tmp)) && (tmp != '\0')) {
|
||||
k++;
|
||||
tmp = ftdm->cid_num.digits[k];
|
||||
} /* while(!(isdigit(tmp))) */
|
||||
/* atoi will search through memory starting from the pointer it is given until
|
||||
* it finds the \0...since tmp is on the stack it will start going through the
|
||||
* possibly causing corruption. Hard code a \0 to prevent this
|
||||
*/
|
||||
tmp[1] = '\0';
|
||||
k = 0;
|
||||
j = 0;
|
||||
flag = 0;
|
||||
|
||||
if (tmp != '\0') {
|
||||
lower = atoi(&tmp);
|
||||
k++;
|
||||
tmp = ftdm->cid_num.digits[k];
|
||||
} else {
|
||||
flag = 1;
|
||||
lower = 0xf;
|
||||
} /* if (tmp != '\0') */
|
||||
} /* (isdigit(tmp)) */
|
||||
} else {
|
||||
flag = 1;
|
||||
lower = 0xf;
|
||||
} /* if (tmp != '\0') */
|
||||
while (1) {
|
||||
tmp[0] = ftdm->cid_num.digits[k];
|
||||
|
||||
tmp = ftdm->cid_num.digits[k];
|
||||
if (tmp != '\0') {
|
||||
if (isdigit(tmp)) {
|
||||
upper = (atoi(&tmp)) << 4;
|
||||
} else {
|
||||
while (!(isdigit(tmp)) && (tmp != '\0')) {
|
||||
k++;
|
||||
tmp = ftdm->cid_num.digits[k];
|
||||
} /* while(!(isdigit(tmp))) */
|
||||
if (tmp[0] != '\0') {
|
||||
if (isdigit(tmp[0])) {
|
||||
lower = atoi(&tmp[0]);
|
||||
k++;
|
||||
tmp[0] = ftdm->cid_num.digits[k];
|
||||
} else {
|
||||
while (!(isdigit(tmp[0])) && (tmp[0] != '\0')) {
|
||||
k++;
|
||||
tmp[0] = ftdm->cid_num.digits[k];
|
||||
} /* while(!(isdigit(tmp))) */
|
||||
|
||||
if (tmp != '\0') {
|
||||
upper = (atoi(&tmp)) << 4;
|
||||
k++;
|
||||
} else {
|
||||
flag = 1;
|
||||
upper = 0xf;
|
||||
} /* if (tmp != '\0') */
|
||||
} /* if (isdigit(tmp)) */
|
||||
} else {
|
||||
if (flag == 1){
|
||||
upper = 0x0;
|
||||
} else {
|
||||
flag = 1;
|
||||
upper = 0xf;
|
||||
} /* if (flag == 1) */
|
||||
} /* if (tmp != '\0') */
|
||||
if (tmp[0] != '\0') {
|
||||
lower = atoi(&tmp[0]);
|
||||
k++;
|
||||
tmp[0] = ftdm->cid_num.digits[k];
|
||||
} else {
|
||||
flag = 1;
|
||||
lower = 0xf;
|
||||
} /* if (tmp != '\0') */
|
||||
} /* (isdigit(tmp)) */
|
||||
} else {
|
||||
flag = 1;
|
||||
lower = 0xf;
|
||||
} /* if (tmp != '\0') */
|
||||
|
||||
cgPtyNum->addrSig.val[j] = upper | lower;
|
||||
j++;
|
||||
tmp[0] = ftdm->cid_num.digits[k];
|
||||
|
||||
if (flag) {
|
||||
break;
|
||||
} else {
|
||||
k++;
|
||||
}
|
||||
} /* while(1) */
|
||||
if (tmp[0] != '\0') {
|
||||
if (isdigit(tmp[0])) {
|
||||
upper = (atoi(&tmp[0])) << 4;
|
||||
} else {
|
||||
while (!(isdigit(tmp[0])) && (tmp[0] != '\0')) {
|
||||
k++;
|
||||
tmp[0] = ftdm->cid_num.digits[k];
|
||||
} /* while(!(isdigit(tmp))) */
|
||||
|
||||
cgPtyNum->addrSig.len = j;
|
||||
/**************************************************************************/
|
||||
cgPtyNum->oddEven.pres = PRSNT_NODEF;
|
||||
cgPtyNum->oddEven.val = ((cgPtyNum->addrSig.val[j] >>4) == 0x0 ) ? 0x01 : 0x00;
|
||||
/**************************************************************************/
|
||||
return 0;
|
||||
if (tmp[0] != '\0') {
|
||||
upper = (atoi(&tmp[0])) << 4;
|
||||
k++;
|
||||
} else {
|
||||
flag = 1;
|
||||
upper = 0xf;
|
||||
} /* if (tmp != '\0') */
|
||||
} /* if (isdigit(tmp)) */
|
||||
} else {
|
||||
if (flag == 1) {
|
||||
upper = 0x0;
|
||||
} else {
|
||||
flag = 1;
|
||||
upper = 0xf;
|
||||
} /* if (flag == 1) */
|
||||
} /* if (tmp != '\0') */
|
||||
|
||||
cgPtyNum->addrSig.val[j] = upper | lower;
|
||||
|
||||
j++;
|
||||
|
||||
if (flag) {
|
||||
break;
|
||||
} else {
|
||||
k++;
|
||||
}
|
||||
} /* while(1) */
|
||||
|
||||
cgPtyNum->addrSig.len = j;
|
||||
|
||||
/**************************************************************************/
|
||||
cgPtyNum->oddEven.pres = PRSNT_NODEF;
|
||||
|
||||
cgPtyNum->oddEven.val = ((cgPtyNum->addrSig.val[j] >> 4) == 0x0 ) ? 0x01 : 0x00;
|
||||
|
||||
/**************************************************************************/
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
uint8_t copy_cdPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum)
|
||||
{
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
uint8_t copy_cdPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum)
|
||||
{
|
||||
int k;
|
||||
int j;
|
||||
int flag;
|
||||
char tmp;
|
||||
unsigned char lower;
|
||||
unsigned char upper;
|
||||
int k;
|
||||
int j;
|
||||
int flag;
|
||||
char tmp[2];
|
||||
unsigned char lower;
|
||||
unsigned char upper;
|
||||
|
||||
/**************************************************************************/
|
||||
cdPtyNum->eh.pres = PRSNT_NODEF;
|
||||
/**************************************************************************/
|
||||
cdPtyNum->natAddrInd.pres = PRSNT_NODEF;
|
||||
cdPtyNum->natAddrInd.val = 0x03;
|
||||
/**************************************************************************/
|
||||
cdPtyNum->numPlan.pres = PRSNT_NODEF;
|
||||
cdPtyNum->numPlan.val = 0x01;
|
||||
/**************************************************************************/
|
||||
cdPtyNum->innInd.pres = PRSNT_NODEF;
|
||||
cdPtyNum->innInd.val = 0x01;
|
||||
/**************************************************************************/
|
||||
cdPtyNum->addrSig.pres = PRSNT_NODEF;
|
||||
/**************************************************************************/
|
||||
cdPtyNum->eh.pres = PRSNT_NODEF;
|
||||
/**************************************************************************/
|
||||
cdPtyNum->natAddrInd.pres = PRSNT_NODEF;
|
||||
cdPtyNum->natAddrInd.val = 0x03;
|
||||
/**************************************************************************/
|
||||
cdPtyNum->numPlan.pres = PRSNT_NODEF;
|
||||
cdPtyNum->numPlan.val = 0x01;
|
||||
/**************************************************************************/
|
||||
cdPtyNum->innInd.pres = PRSNT_NODEF;
|
||||
cdPtyNum->innInd.val = 0x01;
|
||||
/**************************************************************************/
|
||||
cdPtyNum->addrSig.pres = PRSNT_NODEF;
|
||||
|
||||
k = 0;
|
||||
j = 0;
|
||||
flag = 0;
|
||||
while (1) {
|
||||
tmp = ftdm->dnis.digits[k];
|
||||
if (tmp != '\0') {
|
||||
if (isdigit(tmp)) {
|
||||
lower = atoi(&tmp);
|
||||
k++;
|
||||
tmp = ftdm->dnis.digits[k];
|
||||
} else {
|
||||
while (!(isdigit(tmp)) && (tmp != '\0')) {
|
||||
k++;
|
||||
tmp = ftdm->dnis.digits[k];
|
||||
} /* while(!(isdigit(tmp))) */
|
||||
/* atoi will search through memory starting from the pointer it is given until
|
||||
* it finds the \0...since tmp is on the stack it will start going through the
|
||||
* possibly causing corruption. Hard code a \0 to prevent this
|
||||
*/
|
||||
tmp[1] = '\0';
|
||||
k = 0;
|
||||
j = 0;
|
||||
flag = 0;
|
||||
|
||||
if (tmp != '\0') {
|
||||
lower = atoi(&tmp);
|
||||
k++;
|
||||
tmp = ftdm->dnis.digits[k];
|
||||
} else {
|
||||
flag = 1;
|
||||
lower = 0xf;
|
||||
} /* if (tmp != '\0') */
|
||||
} /* (isdigit(tmp)) */
|
||||
} else {
|
||||
flag = 1;
|
||||
lower = 0xf;
|
||||
} /* if (tmp != '\0') */
|
||||
while (1) {
|
||||
tmp[0] = ftdm->dnis.digits[k];
|
||||
|
||||
tmp = ftdm->dnis.digits[k];
|
||||
if (tmp != '\0') {
|
||||
if (isdigit(tmp)) {
|
||||
upper = (atoi(&tmp)) << 4;
|
||||
} else {
|
||||
while (!(isdigit(tmp)) && (tmp != '\0')) {
|
||||
k++;
|
||||
tmp = ftdm->dnis.digits[k];
|
||||
} /* while(!(isdigit(tmp))) */
|
||||
if (tmp[0] != '\0') {
|
||||
if (isdigit(tmp[0])) {
|
||||
lower = atoi(&tmp[0]);
|
||||
k++;
|
||||
tmp[0] = ftdm->dnis.digits[k];
|
||||
} else {
|
||||
while (!(isdigit(tmp[0])) && (tmp[0] != '\0')) {
|
||||
k++;
|
||||
tmp[0] = ftdm->dnis.digits[k];
|
||||
} /* while(!(isdigit(tmp))) */
|
||||
|
||||
if (tmp != '\0') {
|
||||
upper = (atoi(&tmp)) << 4;
|
||||
k++;
|
||||
} else {
|
||||
flag = 1;
|
||||
upper = 0xf;
|
||||
} /* if (tmp != '\0') */
|
||||
} /* if (isdigit(tmp)) */
|
||||
} else {
|
||||
if (flag == 1){
|
||||
upper = 0x0;
|
||||
} else {
|
||||
flag = 1;
|
||||
upper = 0xf;
|
||||
} /* if (flag == 1) */
|
||||
} /* if (tmp != '\0') */
|
||||
if (tmp[0] != '\0') {
|
||||
lower = atoi(&tmp[0]);
|
||||
k++;
|
||||
tmp[0] = ftdm->dnis.digits[k];
|
||||
} else {
|
||||
flag = 1;
|
||||
lower = 0xf;
|
||||
} /* if (tmp != '\0') */
|
||||
} /* (isdigit(tmp)) */
|
||||
} else {
|
||||
flag = 1;
|
||||
lower = 0xf;
|
||||
} /* if (tmp != '\0') */
|
||||
|
||||
cdPtyNum->addrSig.val[j] = upper | lower;
|
||||
j++;
|
||||
tmp[0] = ftdm->dnis.digits[k];
|
||||
|
||||
if (flag) {
|
||||
break;
|
||||
} else {
|
||||
k++;
|
||||
}
|
||||
} /* while(1) */
|
||||
if (tmp[0] != '\0') {
|
||||
if (isdigit(tmp[0])) {
|
||||
upper = (atoi(&tmp[0])) << 4;
|
||||
} else {
|
||||
while (!(isdigit(tmp[0])) && (tmp[0] != '\0')) {
|
||||
k++;
|
||||
tmp[0] = ftdm->dnis.digits[k];
|
||||
} /* while(!(isdigit(tmp))) */
|
||||
|
||||
cdPtyNum->addrSig.len = j;
|
||||
/**************************************************************************/
|
||||
cdPtyNum->oddEven.pres = PRSNT_NODEF;
|
||||
cdPtyNum->oddEven.val = ((cdPtyNum->addrSig.val[j] >>4) == 0x0 ) ? 0x01 : 0x00;
|
||||
/**************************************************************************/
|
||||
return 0;
|
||||
if (tmp[0] != '\0') {
|
||||
upper = (atoi(&tmp[0])) << 4;
|
||||
k++;
|
||||
} else {
|
||||
flag = 1;
|
||||
upper = 0xf;
|
||||
} /* if (tmp != '\0') */
|
||||
} /* if (isdigit(tmp)) */
|
||||
} else {
|
||||
if (flag == 1) {
|
||||
upper = 0x0;
|
||||
} else {
|
||||
flag = 1;
|
||||
upper = 0xf;
|
||||
} /* if (flag == 1) */
|
||||
} /* if (tmp != '\0') */
|
||||
|
||||
cdPtyNum->addrSig.val[j] = upper | lower;
|
||||
|
||||
j++;
|
||||
|
||||
if (flag) {
|
||||
break;
|
||||
} else {
|
||||
k++;
|
||||
}
|
||||
} /* while(1) */
|
||||
|
||||
cdPtyNum->addrSig.len = j;
|
||||
|
||||
/**************************************************************************/
|
||||
cdPtyNum->oddEven.pres = PRSNT_NODEF;
|
||||
|
||||
cdPtyNum->oddEven.val = ((cdPtyNum->addrSig.val[j] >> 4) == 0x0 ) ? 0x01 : 0x00;
|
||||
|
||||
/**************************************************************************/
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
uint8_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t j;
|
||||
uint8_t i;
|
||||
uint8_t j;
|
||||
|
||||
/* check if the token string is present */
|
||||
if (str.pres == 1) {
|
||||
j=0;
|
||||
/* check if the token string is present */
|
||||
|
||||
for (i=0; i < str.len; i++) {
|
||||
sprintf(&ftdm[j], "%d", (str.val[i] & 0x0F));
|
||||
j++;
|
||||
sprintf(&ftdm[j], "%d", ((str.val[i] & 0xF0) >> 4));
|
||||
j++;
|
||||
}
|
||||
if (str.pres == 1) {
|
||||
j = 0;
|
||||
|
||||
/* 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';
|
||||
}
|
||||
} else {
|
||||
SS7_ERROR("Asked to copy tknStr that is not present!\n");
|
||||
return 1;
|
||||
}
|
||||
for (i = 0; i < str.len; i++) {
|
||||
sprintf(&ftdm[j], "%d", (str.val[i] & 0x0F));
|
||||
j++;
|
||||
sprintf(&ftdm[j], "%d", ((str.val[i] & 0xF0) >> 4));
|
||||
j++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
/* 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';
|
||||
}
|
||||
} else {
|
||||
SS7_ERROR("Asked to copy tknStr that is not present!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
int check_for_state_change(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
|
||||
/* check to see if there are any pending state changes on the channel and give them a sec to happen*/
|
||||
ftdm_wait_for_flag_cleared(ftdmchan, FTDM_CHANNEL_STATE_CHANGE, 500);
|
||||
|
||||
/* check the flag to confirm it is clear now */
|
||||
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
|
||||
/* the flag is still up...so we have a problem */
|
||||
SS7_DEBUG_CHAN(ftdmchan, "FTDM_CHANNEL_STATE_CHANGE flag set for over 500ms, channel state = %s\n",
|
||||
ftdm_channel_state2str (ftdmchan->state));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
int check_cics_in_range(sngss7_chan_data_t *sngss7_info)
|
||||
{
|
||||
|
||||
|
||||
#if 0
|
||||
SS7_DEBUG("Checking for pending state change on span: %d, chan: %d\n!",
|
||||
ftdmchan->physical_span_id,
|
||||
ftdmchan->physical_chan_id);
|
||||
ftdm_channel_t *tmp_ftdmchan;
|
||||
sngss7_chan_data_t *tmp_sngss7_info;
|
||||
int i = 0;
|
||||
|
||||
/* check all the circuits in the range to see if we are the last ckt to reset */
|
||||
for ( i = sngss7_info->grs.circuit; i < ( sngss7_info->grs.range + 1 ); i++ ) {
|
||||
if ( g_ftdm_sngss7_data.cfg.isupCircuit[i].siglink == 0 ) {
|
||||
|
||||
/* get the ftdmchan and ss7_chan_data from the circuit */
|
||||
if (extract_chan_data(g_ftdm_sngss7_data.cfg.isupCircuit[i].id, &tmp_sngss7_info, &tmp_ftdmchan)) {
|
||||
SS7_ERROR("Failed to extract channel data for circuit = %d!\n", g_ftdm_sngss7_data.cfg.isupCircuit[i].id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check if the channel still has the reset flag done is up */
|
||||
if (!sngss7_test_flag(tmp_sngss7_info, FLAG_GRP_RESET_RX_DN)) {
|
||||
SS7_DEBUG_CHAN(tmp_ftdmchan, "[CIC:%d] Still processing reset...\n", tmp_sngss7_info->circuit->cic);
|
||||
return 0;
|
||||
}
|
||||
} /* if not siglink */
|
||||
} /* for */
|
||||
|
||||
SS7_DEBUG("All circuits out of reset: circuit=%d, range=%d\n",
|
||||
sngss7_info->grs.circuit,
|
||||
sngss7_info->grs.range);
|
||||
return 1;
|
||||
|
||||
#endif
|
||||
/* check to see if there are any pending state changes on the channel and give them a sec to happen*/
|
||||
ftdm_wait_for_flag_cleared(ftdmchan, FTDM_CHANNEL_STATE_CHANGE, 500);
|
||||
|
||||
/* check the flag to confirm it is clear now */
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) {
|
||||
/* the flag is still up...so we have a problem */
|
||||
SS7_ERROR("FTDM_CHANNEL_STATE_CHANGE set for over 500ms on span: %d, chan: %d\n",
|
||||
ftdmchan->physical_span_id,
|
||||
ftdmchan->physical_chan_id);
|
||||
return 0;
|
||||
|
||||
/* move the state of the channel to RESTART to force a reset */
|
||||
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART);
|
||||
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
ftdm_status_t extract_chan_data(uint32_t circuit, sngss7_chan_data_t **sngss7_info, ftdm_channel_t **ftdmchan)
|
||||
{
|
||||
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
/*SS7_FUNC_TRACE_ENTER(__FUNCTION__);*/
|
||||
|
||||
if (g_ftdm_sngss7_data.cfg.isupCircuit[circuit].obj == NULL) {
|
||||
SS7_ERROR("sngss7_info is Null for circuit #%d\n", circuit);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].obj == NULL) {
|
||||
SS7_ERROR("sngss7_info is Null for circuit #%d\n", circuit);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
ftdm_assert_return(g_ftdm_sngss7_data.cfg.isupCircuit[circuit].obj,FTDM_FAIL,"received message on signalling link or non-configured cic\n");
|
||||
*sngss7_info = g_ftdm_sngss7_data.cfg.isupCircuit[circuit].obj;
|
||||
ftdm_assert_return(g_ftdm_sngss7_data.cfg.isupCkt[circuit].obj, FTDM_FAIL, "received message on signalling link or non-configured cic\n");
|
||||
|
||||
ftdm_assert_return((*sngss7_info)->ftdmchan,FTDM_FAIL,"received message on signalling link or non-configured cic\n");
|
||||
*ftdmchan = (*sngss7_info)->ftdmchan;
|
||||
*sngss7_info = g_ftdm_sngss7_data.cfg.isupCkt[circuit].obj;
|
||||
|
||||
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return FTDM_SUCCESS;
|
||||
ftdm_assert_return((*sngss7_info)->ftdmchan, FTDM_FAIL, "received message on signalling link or non-configured cic\n");
|
||||
*ftdmchan = (*sngss7_info)->ftdmchan;
|
||||
|
||||
/*SS7_FUNC_TRACE_EXIT(__FUNCTION__);*/
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
int check_for_reset(sngss7_chan_data_t *sngss7_info)
|
||||
{
|
||||
|
||||
if (sngss7_test_flag(sngss7_info,FLAG_RESET_RX)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (sngss7_test_flag(sngss7_info,FLAG_RESET_TX)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (sngss7_test_flag(sngss7_info,FLAG_GRP_RESET_RX)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (sngss7_test_flag(sngss7_info,FLAG_GRP_RESET_TX)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
unsigned long get_unique_id(void)
|
||||
{
|
||||
|
||||
if (sngss7_id < 420000000) {
|
||||
sngss7_id++;
|
||||
} else {
|
||||
sngss7_id = 1;
|
||||
}
|
||||
if (sngss7_id < 420000000) {
|
||||
sngss7_id++;
|
||||
} else {
|
||||
sngss7_id = 1;
|
||||
}
|
||||
|
||||
return(sngss7_id);
|
||||
return(sngss7_id);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -60,6 +60,8 @@
|
|||
/*! \brief Max number of groups */
|
||||
#define FTDM_MAX_GROUPS_INTERFACE FTDM_MAX_SPANS_INTERFACE
|
||||
|
||||
#define FTDM_INVALID_INT_PARM 0xFF
|
||||
|
||||
/*! \brief FreeTDM APIs possible return codes */
|
||||
typedef enum {
|
||||
FTDM_SUCCESS, /*!< Success */
|
||||
|
@ -208,6 +210,7 @@ typedef struct ftdm_queue_handler {
|
|||
ftdm_queue_destroy_func_t destroy;
|
||||
} ftdm_queue_handler_t;
|
||||
|
||||
|
||||
/*! \brief Type Of Number (TON) */
|
||||
typedef enum {
|
||||
FTDM_TON_UNKNOWN = 0,
|
||||
|
@ -239,6 +242,20 @@ typedef struct {
|
|||
uint8_t plan;
|
||||
} ftdm_number_t;
|
||||
|
||||
/*! \brief bearer capability */
|
||||
typedef enum {
|
||||
FTDM_BEARER_CAP_SPEECH = 0x00,
|
||||
FTDM_BEARER_CAP_64K_UNRESTRICTED = 0x02,
|
||||
FTDM_BEARER_CAP_3_1KHZ_AUDIO = 0x03
|
||||
} ftdm_bearer_cap_t;
|
||||
|
||||
/*! \brief user information layer 1 protocol */
|
||||
typedef enum {
|
||||
FTDM_USER_LAYER1_PROT_V110 = 0x01,
|
||||
FTDM_USER_LAYER1_PROT_ULAW = 0x02,
|
||||
FTDM_USER_LAYER1_PROT_ALAW = 0x03,
|
||||
} ftdm_user_layer1_prot_t;
|
||||
|
||||
/*! \brief Caller information */
|
||||
typedef struct ftdm_caller_data {
|
||||
char cid_date[8]; /*!< Caller ID date */
|
||||
|
@ -256,9 +273,9 @@ typedef struct ftdm_caller_data {
|
|||
uint32_t raw_data_len; /* !< Raw data length */
|
||||
/* these 2 are undocumented right now, only used by boost: */
|
||||
/* bearer capability */
|
||||
uint8_t bearer_capability;
|
||||
ftdm_bearer_cap_t bearer_capability;
|
||||
/* user information layer 1 protocol */
|
||||
uint8_t bearer_layer1;
|
||||
ftdm_user_layer1_prot_t bearer_layer1;
|
||||
} ftdm_caller_data_t;
|
||||
|
||||
/*! \brief Tone type */
|
||||
|
@ -317,23 +334,6 @@ typedef struct ftdm_channel_config {
|
|||
float txgain;
|
||||
} ftdm_channel_config_t;
|
||||
|
||||
/*! \brief Generic signaling message */
|
||||
struct ftdm_sigmsg {
|
||||
ftdm_signal_event_t event_id; /*!< The type of message */
|
||||
ftdm_channel_t *channel; /*!< Related channel */
|
||||
uint32_t chan_id; /*!< easy access to chan id */
|
||||
uint32_t span_id; /*!< easy access to span_id */
|
||||
void *raw_data; /*!< Message specific data if any */
|
||||
uint32_t raw_data_len; /*!< Data len in case is needed */
|
||||
};
|
||||
|
||||
/*! \brief Crash policy
|
||||
* Useful for debugging only, default policy is never, if you wish to crash on asserts then use ftdm_global_set_crash_policy */
|
||||
typedef enum {
|
||||
FTDM_CRASH_NEVER = 0,
|
||||
FTDM_CRASH_ON_ASSERT
|
||||
} ftdm_crash_policy_t;
|
||||
|
||||
/*!
|
||||
\brief Signaling status on a given span or specific channel on protocols that support it
|
||||
*/
|
||||
|
@ -352,6 +352,24 @@ typedef enum {
|
|||
/*! \brief Move from string to ftdm_signaling_status_t and viceversa */
|
||||
FTDM_STR2ENUM_P(ftdm_str2ftdm_signaling_status, ftdm_signaling_status2str, ftdm_signaling_status_t)
|
||||
|
||||
/*! \brief Generic signaling message */
|
||||
struct ftdm_sigmsg {
|
||||
ftdm_signal_event_t event_id; /*!< The type of message */
|
||||
ftdm_channel_t *channel; /*!< Related channel */
|
||||
uint32_t chan_id; /*!< easy access to chan id */
|
||||
uint32_t span_id; /*!< easy access to span_id */
|
||||
ftdm_signaling_status_t sigstatus; /*!< Signaling status (valid if event_id is FTDM_SIGEVENT_SIGSTATUS_CHANGED) */
|
||||
void *raw_data; /*!< Message specific data if any */
|
||||
uint32_t raw_data_len; /*!< Data len in case is needed */
|
||||
};
|
||||
|
||||
/*! \brief Crash policy
|
||||
* Useful for debugging only, default policy is never, if you wish to crash on asserts then use ftdm_global_set_crash_policy */
|
||||
typedef enum {
|
||||
FTDM_CRASH_NEVER = 0,
|
||||
FTDM_CRASH_ON_ASSERT
|
||||
} ftdm_crash_policy_t;
|
||||
|
||||
/*! \brief I/O waiting flags */
|
||||
typedef enum {
|
||||
FTDM_NO_FLAGS = 0,
|
||||
|
@ -367,6 +385,9 @@ typedef struct ftdm_conf_parameter {
|
|||
void *ptr;
|
||||
} ftdm_conf_parameter_t;
|
||||
|
||||
/*! \brief Opaque general purpose iterator */
|
||||
typedef void ftdm_iterator_t;
|
||||
|
||||
/*! \brief Channel commands that can be executed through ftdm_channel_command() */
|
||||
typedef enum {
|
||||
FTDM_COMMAND_NOOP,
|
||||
|
@ -1000,14 +1021,25 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_read(ftdm_channel_t *ftdmchan, void *data
|
|||
*/
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_write(ftdm_channel_t *ftdmchan, void *data, ftdm_size_t datasize, ftdm_size_t *datalen);
|
||||
|
||||
/*! \brief Add a custom variable to the channel */
|
||||
/*! \brief Add a custom variable to the channel
|
||||
* \note This variables may be used by signaling modules to override signaling parameters
|
||||
* \todo Document which signaling variables are available
|
||||
* */
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_add_var(ftdm_channel_t *ftdmchan, const char *var_name, const char *value);
|
||||
|
||||
/*! \brief Get a custom variable from the channel */
|
||||
/*! \brief Get a custom variable from the channel.
|
||||
* \note The variable pointer returned is only valid while the channel is open and it'll be destroyed when the channel is closed. */
|
||||
FT_DECLARE(const char *) ftdm_channel_get_var(ftdm_channel_t *ftdmchan, const char *var_name);
|
||||
|
||||
/*! \brief Clear custom channel variables from the channel */
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_clear_vars(ftdm_channel_t *ftdmchan);
|
||||
/*! \brief Get an iterator to iterate over the channel variables
|
||||
* \note The iterator pointer returned is only valid while the channel is open and it'll be destroyed when the channel is closed. */
|
||||
FT_DECLARE(ftdm_iterator_t *) ftdm_channel_get_var_iterator(const ftdm_channel_t *ftdmchan);
|
||||
|
||||
/*! \brief Get variable name and value for the current iterator position */
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_get_current_var(ftdm_iterator_t *iter, const char **var_name, const char **var_val);
|
||||
|
||||
/*! \brief Advance iterator */
|
||||
FT_DECLARE(ftdm_iterator_t *) ftdm_iterator_next(ftdm_iterator_t *iter);
|
||||
|
||||
/*! \brief Get the span pointer associated to the channel */
|
||||
FT_DECLARE(ftdm_span_t *) ftdm_channel_get_span(const ftdm_channel_t *ftdmchan);
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2010, Sangoma Technologies
|
||||
* David Yat Sin <dyatsin@sangoma.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __FTDM_CALL_UTILS_H__
|
||||
#define __FTDM_CALL_UTILS_H__
|
||||
|
||||
#include "freetdm.h"
|
||||
|
||||
FT_DECLARE(ftdm_status_t) ftdm_span_set_npi(const char *npi_string, uint8_t *target);
|
||||
FT_DECLARE(ftdm_status_t) ftdm_span_set_ton(const char *ton_string, uint8_t *target);
|
||||
FT_DECLARE(ftdm_status_t) ftdm_span_set_bearer_capability(const char *bc_string, ftdm_bearer_cap_t *target);
|
||||
FT_DECLARE(ftdm_status_t) ftdm_span_set_bearer_layer1(const char *bc_string, ftdm_user_layer1_prot_t *target);
|
||||
FT_DECLARE(ftdm_status_t) ftdm_is_number(char *number);
|
||||
|
||||
#endif /* __FTDM_CALL_UTILS_H__ */
|
||||
|
|
@ -117,6 +117,7 @@
|
|||
#include "ftdm_buffer.h"
|
||||
#include "ftdm_threadmutex.h"
|
||||
#include "ftdm_sched.h"
|
||||
#include "ftdm_call_utils.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -465,6 +466,7 @@ struct ftdm_span {
|
|||
ftdm_state_map_t *state_map;
|
||||
ftdm_caller_data_t default_caller_data;
|
||||
ftdm_queue_t *pendingchans;
|
||||
ftdm_queue_t *pendingsignals;
|
||||
struct ftdm_span *next;
|
||||
};
|
||||
|
||||
|
@ -578,6 +580,8 @@ FT_DECLARE(ftdm_status_t) ftdm_span_next_event(ftdm_span_t *span, ftdm_event_t *
|
|||
*/
|
||||
FT_DECLARE(ftdm_status_t) ftdm_channel_queue_dtmf(ftdm_channel_t *ftdmchan, const char *dtmf);
|
||||
|
||||
/* dequeue pending signals and notify the user via the span signal callback */
|
||||
FT_DECLARE(ftdm_status_t) ftdm_span_trigger_signals(const ftdm_span_t *span);
|
||||
|
||||
/*!
|
||||
\brief Assert condition
|
||||
|
|
|
@ -176,6 +176,10 @@ typedef enum {
|
|||
FTDM_SPAN_USE_CHAN_QUEUE = (1 << 6),
|
||||
FTDM_SPAN_SUGGEST_CHAN_ID = (1 << 7),
|
||||
FTDM_SPAN_USE_AV_RATE = (1 << 8),
|
||||
/* If you use this flag, you MUST call ftdm_span_trigger_signals to deliver the user signals
|
||||
* after having called ftdm_send_span_signal(), which with this flag it will just enqueue the signal
|
||||
* for later delivery */
|
||||
FTDM_SPAN_USE_SIGNALS_QUEUE = (1 << 9),
|
||||
} ftdm_span_flag_t;
|
||||
|
||||
/*! \brief Channel supported features */
|
||||
|
|
Loading…
Reference in New Issue