mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-10-30 15:14:17 +00:00
Merge branch 'master' of git.sangoma.com:smg_freeswitch
Conflicts: libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c
This commit is contained in:
commit
01eb776469
297 files changed
+12215
-7874
No files matched your search
@@ -426,7 +426,6 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
|
||||
uint32_t state_counter = 0, elapsed = 0, collecting = 0, interval = 0, last_digit = 0, indicate = 0, dial_timeout = analog_data->wait_dialtone_timeout;
|
||||
uint32_t answer_on_polarity_counter = 0;
|
||||
ftdm_sigmsg_t sig;
|
||||
ftdm_status_t status;
|
||||
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "ANALOG CHANNEL thread starting.\n");
|
||||
|
||||
@@ -916,7 +915,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
|
||||
}
|
||||
|
||||
if (codec_func) {
|
||||
status = codec_func(frame, sizeof(frame), &rlen);
|
||||
codec_func(frame, sizeof(frame), &rlen);
|
||||
} else {
|
||||
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "codec error!");
|
||||
goto done;
|
||||
|
||||
@@ -221,7 +221,6 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj)
|
||||
ftdm_channel_t *closed_chan;
|
||||
uint32_t state_counter = 0, elapsed = 0, collecting = 0, interval = 0, last_digit = 0, indicate = 0, dial_timeout = 30000;
|
||||
ftdm_sigmsg_t sig;
|
||||
ftdm_status_t status;
|
||||
|
||||
ftdm_log(FTDM_LOG_DEBUG, "ANALOG EM CHANNEL thread starting.\n");
|
||||
|
||||
@@ -545,7 +544,7 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj)
|
||||
}
|
||||
|
||||
if (codec_func) {
|
||||
status = codec_func(frame, sizeof(frame), &rlen);
|
||||
codec_func(frame, sizeof(frame), &rlen);
|
||||
} else {
|
||||
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "codec error!");
|
||||
goto done;
|
||||
|
||||
@@ -979,7 +979,6 @@ static L3INT ftdm_isdn_931_34(void *pvt, struct Q931_Call *call, Q931mes_Generic
|
||||
{
|
||||
Q931ie_CallingNum *callingnum = Q931GetIEPtr(gen->CallingNum, gen->buf);
|
||||
Q931ie_CalledNum *callednum = Q931GetIEPtr(gen->CalledNum, gen->buf);
|
||||
uint32_t cplen = mlen;
|
||||
int overlap_dial = 0;
|
||||
int fail_cause = 0;
|
||||
int fail = 1;
|
||||
@@ -2128,7 +2127,7 @@ static int ftdm_isdn_q921_log(void *pvt, Q921LogLevel_t level, char *msg, L2INT
|
||||
return 0;
|
||||
}
|
||||
|
||||
static L3INT ftdm_isdn_q931_log(void *pvt, Q931LogLevel_t level, char *msg, L3INT size)
|
||||
static L3INT ftdm_isdn_q931_log(void *pvt, Q931LogLevel_t level, const char *msg, L3INT size)
|
||||
{
|
||||
ftdm_span_t *span = (ftdm_span_t *) pvt;
|
||||
|
||||
|
||||
@@ -562,14 +562,18 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan)
|
||||
sig.chan_id = ftdm_channel_get_id(chan);
|
||||
sig.span_id = ftdm_channel_get_span_id(chan);
|
||||
sig.channel = chan;
|
||||
|
||||
|
||||
ftdm_channel_complete_state(chan);
|
||||
|
||||
switch (ftdm_channel_get_state(chan)) {
|
||||
case FTDM_CHANNEL_STATE_DOWN:
|
||||
{
|
||||
ftdm_channel_t *chtmp = chan;
|
||||
chan->call_data = NULL;
|
||||
|
||||
if (call) {
|
||||
pri_destroycall(isdn_data->spri.pri, call);
|
||||
chan->call_data = NULL;
|
||||
}
|
||||
|
||||
if (ftdm_channel_close(&chtmp) != FTDM_SUCCESS) {
|
||||
ftdm_log(FTDM_LOG_WARNING, "-- Failed to close channel %d:%d\n",
|
||||
@@ -776,8 +780,7 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan)
|
||||
|
||||
pri_hangup(isdn_data->spri.pri, call, caller_data->hangup_cause);
|
||||
// pri_destroycall(isdn_data->spri.pri, call);
|
||||
|
||||
chan->call_data = NULL;
|
||||
// chan->call_data = NULL;
|
||||
}
|
||||
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
|
||||
}
|
||||
@@ -785,10 +788,10 @@ static ftdm_status_t state_advance(ftdm_channel_t *chan)
|
||||
|
||||
case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
|
||||
{
|
||||
if (call) {
|
||||
pri_destroycall(isdn_data->spri.pri, call);
|
||||
chan->call_data = NULL;
|
||||
}
|
||||
// if (call) {
|
||||
// pri_destroycall(isdn_data->spri.pri, call);
|
||||
// chan->call_data = NULL;
|
||||
// }
|
||||
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_DOWN);
|
||||
}
|
||||
break;
|
||||
@@ -854,7 +857,6 @@ static int on_hangup(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_even
|
||||
{
|
||||
ftdm_span_t *span = spri->span;
|
||||
ftdm_channel_t *chan = ftdm_span_get_channel(span, pevent->hangup.channel);
|
||||
q931_call *call = NULL;
|
||||
|
||||
if (!chan) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "-- Hangup on channel %d:%d %s but it's not in use?\n", ftdm_span_get_id(spri->span), pevent->hangup.channel);
|
||||
@@ -863,27 +865,61 @@ static int on_hangup(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_even
|
||||
|
||||
ftdm_channel_lock(chan);
|
||||
|
||||
if (ftdm_channel_get_state(chan) >= FTDM_CHANNEL_STATE_TERMINATING) {
|
||||
ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Ignoring remote hangup in state %s\n", ftdm_channel_get_state_str(chan));
|
||||
goto done;
|
||||
switch (event_type) {
|
||||
case LPWRAP_PRI_EVENT_HANGUP_REQ: /* DISCONNECT */
|
||||
if (ftdm_channel_get_state(chan) >= FTDM_CHANNEL_STATE_TERMINATING) {
|
||||
ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Ignoring remote hangup in state %s\n",
|
||||
ftdm_channel_get_state_str(chan));
|
||||
goto done;
|
||||
}
|
||||
ftdm_log(FTDM_LOG_DEBUG, "-- Hangup REQ on channel %d:%d\n",
|
||||
ftdm_span_get_id(spri->span), pevent->hangup.channel);
|
||||
|
||||
pri_hangup(spri->pri, pevent->hangup.call, pevent->hangup.cause);
|
||||
|
||||
chan->caller_data.hangup_cause = pevent->hangup.cause;
|
||||
ftdm_set_state(chan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
break;
|
||||
|
||||
case LPWRAP_PRI_EVENT_HANGUP_ACK: /* */
|
||||
ftdm_log(FTDM_LOG_DEBUG, "-- Hangup ACK on channel %d:%d\n",
|
||||
ftdm_span_get_id(spri->span), pevent->hangup.channel);
|
||||
|
||||
pri_hangup(spri->pri, pevent->hangup.call, pevent->hangup.cause);
|
||||
|
||||
ftdm_set_state(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
|
||||
break;
|
||||
|
||||
case LPWRAP_PRI_EVENT_HANGUP: /* "RELEASE/RELEASE_COMPLETE/other" */
|
||||
ftdm_log(FTDM_LOG_DEBUG, "-- Hangup on channel %d:%d\n",
|
||||
ftdm_span_get_id(spri->span), pevent->hangup.channel);
|
||||
|
||||
switch (ftdm_channel_get_state(chan)) {
|
||||
case FTDM_CHANNEL_STATE_DIALING:
|
||||
case FTDM_CHANNEL_STATE_RINGING:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
case FTDM_CHANNEL_STATE_PROCEED:
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
chan->caller_data.hangup_cause = pevent->hangup.cause;
|
||||
ftdm_set_state(chan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_HANGUP:
|
||||
chan->caller_data.hangup_cause = pevent->hangup.cause;
|
||||
ftdm_set_state(chan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE);
|
||||
break;
|
||||
// case FTDM_CHANNEL_STATE_TERMINATING:
|
||||
// ftdm_set_state(chan, FTDM_CHANNEL_STATE_HANGUP);
|
||||
// break;
|
||||
// case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
|
||||
// ftdm_set_state(chan, FTDM_CHANNEL_STATE_DOWN);
|
||||
// break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!chan->call_data) {
|
||||
ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Ignoring remote hangup in state %s with no call data\n", ftdm_channel_get_state_str(chan));
|
||||
goto done;
|
||||
}
|
||||
|
||||
call = (q931_call *)chan->call_data;
|
||||
|
||||
ftdm_log(FTDM_LOG_DEBUG, "-- Hangup on channel %d:%d\n", ftdm_span_get_id(spri->span), pevent->hangup.channel);
|
||||
|
||||
pri_release(spri->pri, call, 0);
|
||||
pri_destroycall(spri->pri, call);
|
||||
|
||||
chan->caller_data.hangup_cause = pevent->hangup.cause;
|
||||
chan->call_data = NULL;
|
||||
ftdm_set_state_locked(chan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
|
||||
done:
|
||||
ftdm_channel_unlock(chan);
|
||||
return 0;
|
||||
@@ -1654,6 +1690,7 @@ static void *ftdm_libpri_run(ftdm_thread_t *me, void *obj)
|
||||
LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_DCHAN_UP, on_dchan_up);
|
||||
LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_DCHAN_DOWN, on_dchan_down);
|
||||
LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_HANGUP_REQ, on_hangup);
|
||||
LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_HANGUP_ACK, on_hangup);
|
||||
LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_HANGUP, on_hangup);
|
||||
LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_INFO_RECEIVED, on_info);
|
||||
LPWRAP_MAP_PRI_EVENT(isdn_data->spri, LPWRAP_PRI_EVENT_RESTART, on_restart);
|
||||
@@ -1928,6 +1965,10 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_libpri_configure_span)
|
||||
assert(isdn_data != NULL);
|
||||
memset(isdn_data, 0, sizeof(*isdn_data));
|
||||
|
||||
/* set some default values */
|
||||
isdn_data->mode = PRI_CPE;
|
||||
isdn_data->ton = PRI_UNKNOWN;
|
||||
|
||||
switch (ftdm_span_get_trunk_type(span)) {
|
||||
case FTDM_TRUNK_BRI:
|
||||
case FTDM_TRUNK_BRI_PTMP:
|
||||
@@ -1938,12 +1979,14 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_libpri_configure_span)
|
||||
#endif
|
||||
case FTDM_TRUNK_E1:
|
||||
ftdm_log(FTDM_LOG_NOTICE, "Setting default Layer 1 to ALAW since this is an E1/BRI/BRI PTMP trunk\n");
|
||||
isdn_data->layer1 = PRI_LAYER_1_ALAW;
|
||||
isdn_data->layer1 = PRI_LAYER_1_ALAW;
|
||||
isdn_data->dialect = PRI_SWITCH_EUROISDN_E1;
|
||||
break;
|
||||
case FTDM_TRUNK_T1:
|
||||
case FTDM_TRUNK_J1:
|
||||
ftdm_log(FTDM_LOG_NOTICE, "Setting default Layer 1 to ULAW since this is a T1/J1 trunk\n");
|
||||
isdn_data->layer1 = PRI_LAYER_1_ULAW;
|
||||
isdn_data->layer1 = PRI_LAYER_1_ULAW;
|
||||
isdn_data->dialect = PRI_SWITCH_LUCENT5E;
|
||||
break;
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_ERROR, "Invalid trunk type: '%s'\n", ftdm_span_get_trunk_type_str(span));
|
||||
|
||||
@@ -360,11 +360,15 @@ static void ft_r2_clean_call(ftdm_r2_call_t *call)
|
||||
static void ft_r2_accept_call(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
openr2_chan_t *r2chan = R2CALL(ftdmchan)->r2chan;
|
||||
// FIXME: not always accept as no charge, let the user decide that
|
||||
// also we should check the return code from openr2_chan_accept_call and handle error condition
|
||||
ftdm_r2_data_t *r2data = ftdmchan->span->signal_data;
|
||||
|
||||
// FIXME: we should check the return code from openr2_chan_accept_call and handle error condition
|
||||
// hanging up the call with protocol error as the reason, this openr2 API will fail only when there something
|
||||
// wrong at the I/O layer or the library itself
|
||||
openr2_chan_accept_call(r2chan, OR2_CALL_NO_CHARGE);
|
||||
if (r2data->charge_calls)
|
||||
openr2_chan_accept_call(r2chan, OR2_CALL_WITH_CHARGE);
|
||||
else
|
||||
openr2_chan_accept_call(r2chan, OR2_CALL_NO_CHARGE);
|
||||
}
|
||||
|
||||
static void ft_r2_answer_call(ftdm_channel_t *ftdmchan)
|
||||
@@ -1697,6 +1701,8 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_r2_configure_span_signaling)
|
||||
r2data->category = r2conf.category;
|
||||
r2data->allow_collect_calls = r2conf.allow_collect_calls;
|
||||
r2data->flags = 0;
|
||||
r2data->charge_calls = r2conf.charge_calls;
|
||||
r2data->forced_release = r2conf.forced_release;
|
||||
spanpvt->r2context = r2data->r2context;
|
||||
|
||||
/* just the value must be freed by the hash */
|
||||
@@ -1854,6 +1860,10 @@ static ftdm_status_t ftdm_r2_state_advance(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
if (!r2call->disconnect_rcvd) {
|
||||
openr2_call_disconnect_cause_t disconnect_cause = ftdm_r2_ftdm_cause_to_openr2_cause(ftdmchan);
|
||||
/* overwrite the hangup cause if this is an incoming call and forced_release is set */
|
||||
if (openr2_chan_get_direction(r2chan) == OR2_DIR_BACKWARD && r2data->forced_release) {
|
||||
disconnect_cause = OR2_CAUSE_FORCED_RELEASE;
|
||||
}
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Clearing call, cause = %s\n", openr2_proto_get_disconnect_string(disconnect_cause));
|
||||
/* this will disconnect the call, but need to wait for the call end before moving to DOWN */
|
||||
openr2_chan_disconnect_call(r2chan, disconnect_cause);
|
||||
|
||||
@@ -1198,9 +1198,17 @@ static FIO_SIG_UNLOAD_FUNCTION(ftdm_sangoma_isdn_unload)
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
#define SANGOMA_ISDN_API_USAGE_TRACE "ftdm sangoma_isdn trace <q921|q931> <span name>\n"
|
||||
#define SANGOMA_ISDN_API_USAGE_SHOW_L1_STATS "ftdm sangoma_isdn l1_stats <span name>\n"
|
||||
#define SANGOMA_ISDN_API_USAGE_SHOW_SPANS "ftdm sangoma_isdn show_spans [<span name>]\n"
|
||||
|
||||
#define SANGOMA_ISDN_API_USAGE "\t"SANGOMA_ISDN_API_USAGE_TRACE \
|
||||
"\t"SANGOMA_ISDN_API_USAGE_SHOW_L1_STATS \
|
||||
"\t"SANGOMA_ISDN_API_USAGE_SHOW_SPANS
|
||||
|
||||
static FIO_API_FUNCTION(ftdm_sangoma_isdn_api)
|
||||
{
|
||||
ftdm_status_t status = FTDM_SUCCESS;
|
||||
ftdm_status_t status = FTDM_EINVAL;
|
||||
char *mycmd = NULL, *argv[10] = { 0 };
|
||||
int argc = 0;
|
||||
|
||||
@@ -1222,7 +1230,7 @@ static FIO_API_FUNCTION(ftdm_sangoma_isdn_api)
|
||||
ftdm_span_t *span;
|
||||
|
||||
if (argc < 3) {
|
||||
ftdm_log(FTDM_LOG_ERROR, "Usage: ftdm sangoma_isdn trace <q921|q931> <span name>\n");
|
||||
ftdm_log(FTDM_LOG_ERROR, "Usage: %s\n", SANGOMA_ISDN_API_USAGE_TRACE);
|
||||
status = FTDM_FAIL;
|
||||
goto done;
|
||||
}
|
||||
@@ -1231,34 +1239,40 @@ static FIO_API_FUNCTION(ftdm_sangoma_isdn_api)
|
||||
status = ftdm_span_find_by_name(argv[2], &span);
|
||||
if (FTDM_SUCCESS != status) {
|
||||
stream->write_function(stream, "-ERR failed to find span by name %s\n", argv[2]);
|
||||
|
||||
status = FTDM_FAIL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!strcasecmp(trace_opt, "q921")) {
|
||||
sngisdn_activate_trace(span, SNGISDN_TRACE_Q921);
|
||||
status = sngisdn_activate_trace(span, SNGISDN_TRACE_Q921);
|
||||
} else if (!strcasecmp(trace_opt, "q931")) {
|
||||
sngisdn_activate_trace(span, SNGISDN_TRACE_Q931);
|
||||
status = sngisdn_activate_trace(span, SNGISDN_TRACE_Q931);
|
||||
} else if (!strcasecmp(trace_opt, "disable")) {
|
||||
sngisdn_activate_trace(span, SNGISDN_TRACE_DISABLE);
|
||||
status = sngisdn_activate_trace(span, SNGISDN_TRACE_DISABLE);
|
||||
} else {
|
||||
stream->write_function(stream, "-ERR invalid trace option <q921|q931> <span name>\n");
|
||||
status = FTDM_FAIL;
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!strcasecmp(argv[0], "l1_stats")) {
|
||||
ftdm_span_t *span;
|
||||
if (argc < 2) {
|
||||
stream->write_function(stream, "Usage: ftdm sangoma_isdn l1_stats <span name>\n");
|
||||
stream->write_function(stream, "Usage: %s\n", SANGOMA_ISDN_API_USAGE_SHOW_L1_STATS);
|
||||
status = FTDM_FAIL;
|
||||
goto done;
|
||||
}
|
||||
status = ftdm_span_find_by_name(argv[1], &span);
|
||||
if (FTDM_SUCCESS != status) {
|
||||
stream->write_function(stream, "-ERR failed to find span with name %s\n", argv[1]);
|
||||
/* Return SUCCESS because we do not want to print the general FTDM usage list */
|
||||
status = FTDM_SUCCESS;
|
||||
|
||||
status = FTDM_FAIL;
|
||||
goto done;
|
||||
}
|
||||
sngisdn_print_phy_stats(stream, span);
|
||||
status = sngisdn_show_l1_stats(stream, span);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!strcasecmp(argv[0], "show_spans")) {
|
||||
@@ -1267,20 +1281,42 @@ static FIO_API_FUNCTION(ftdm_sangoma_isdn_api)
|
||||
status = ftdm_span_find_by_name(argv[1], &span);
|
||||
if (FTDM_SUCCESS != status) {
|
||||
stream->write_function(stream, "-ERR failed to find span with name %s\n", argv[1]);
|
||||
/* Return SUCCESS because we do not want to print the general FTDM usage list */
|
||||
status = FTDM_SUCCESS;
|
||||
|
||||
stream->write_function(stream, "Usage: %s\n", SANGOMA_ISDN_API_USAGE_SHOW_SPANS);
|
||||
status = FTDM_FAIL;
|
||||
goto done;
|
||||
}
|
||||
sngisdn_print_span(stream, span);
|
||||
status = FTDM_SUCCESS;
|
||||
status = sngisdn_show_span(stream, span);
|
||||
goto done;
|
||||
}
|
||||
sngisdn_print_spans(stream);
|
||||
status = sngisdn_show_spans(stream);
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!strcasecmp(argv[0], "check_ids")) {
|
||||
sngisdn_check_free_ids();
|
||||
status = sngisdn_check_free_ids();
|
||||
goto done;
|
||||
}
|
||||
if (!strcasecmp(argv[0], "check_mem")) {
|
||||
sngisdn_get_memory_info();
|
||||
}
|
||||
done:
|
||||
switch (status) {
|
||||
case FTDM_SUCCESS:
|
||||
stream->write_function(stream, "Command executed OK\n");
|
||||
break;
|
||||
case FTDM_EINVAL:
|
||||
stream->write_function(stream, "Invalid arguments [%s]\n", mycmd);
|
||||
stream->write_function(stream, "Usage:\n%s\n", SANGOMA_ISDN_API_USAGE);
|
||||
break;
|
||||
default:
|
||||
/* FTDM_FAIL - Do nothing since we already printed the cause of the error */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Return SUCCESS because we do not want to print the general FTDM usage list */
|
||||
status = FTDM_SUCCESS;
|
||||
|
||||
ftdm_safe_free(mycmd);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -292,6 +292,12 @@ typedef struct ftdm_sngisdn_data {
|
||||
sngisdn_span_data_t *spans[MAX_L1_LINKS+1]; /* spans are indexed by link_id */
|
||||
}ftdm_sngisdn_data_t;
|
||||
|
||||
typedef struct ftdm2trillium
|
||||
{
|
||||
uint8_t ftdm_val;
|
||||
uint8_t trillium_val;
|
||||
}ftdm2trillium_t;
|
||||
|
||||
|
||||
/* TODO implement these 2 functions */
|
||||
#define ISDN_FUNC_TRACE_ENTER(a)
|
||||
@@ -388,7 +394,7 @@ void sngisdn_trace_interpreted_q931(sngisdn_span_data_t *signal_data, ftdm_trace
|
||||
void sngisdn_trace_raw_q921(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len);
|
||||
void sngisdn_trace_raw_q931(sngisdn_span_data_t *signal_data, ftdm_trace_dir_t dir, uint8_t *data, uint32_t data_len);
|
||||
|
||||
void get_memory_info(void);
|
||||
void sngisdn_get_memory_info(void);
|
||||
|
||||
ftdm_status_t sng_isdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt);
|
||||
ftdm_status_t sngisdn_check_free_ids(void);
|
||||
@@ -471,9 +477,9 @@ ftdm_status_t sngisdn_stack_start(ftdm_span_t *span);
|
||||
ftdm_status_t sngisdn_stack_stop(ftdm_span_t *span);
|
||||
ftdm_status_t sngisdn_wake_up_phy(ftdm_span_t *span);
|
||||
|
||||
void sngisdn_print_phy_stats(ftdm_stream_handle_t *stream, ftdm_span_t *span);
|
||||
void sngisdn_print_spans(ftdm_stream_handle_t *stream);
|
||||
void sngisdn_print_span(ftdm_stream_handle_t *stream, ftdm_span_t *span);
|
||||
ftdm_status_t sngisdn_show_l1_stats(ftdm_stream_handle_t *stream, ftdm_span_t *span);
|
||||
ftdm_status_t sngisdn_show_spans(ftdm_stream_handle_t *stream);
|
||||
ftdm_status_t sngisdn_show_span(ftdm_stream_handle_t *stream, ftdm_span_t *span);
|
||||
|
||||
#endif /* __FTMOD_SNG_ISDN_H__ */
|
||||
|
||||
|
||||
@@ -745,8 +745,16 @@ ftdm_status_t sngisdn_stack_cfg_q931_dlsap(ftdm_span_t *span)
|
||||
/* TODO: Fill in these timers with proper values - eventually pass them */
|
||||
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;
|
||||
|
||||
/* It looks like ETSI is the only variant that supports Overlap */
|
||||
if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN) {
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t302.enb = TRUE;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t302.val = 15;
|
||||
} else {
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t302.enb = FALSE;
|
||||
cfg.t.cfg.s.inDLSAP.tmr.t302.val = 0;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "ftmod_sangoma_isdn.h"
|
||||
static ftdm_status_t sngisdn_cause_val_requires_disconnect(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn);
|
||||
static void sngisdn_process_restart_confirm(ftdm_channel_t *ftdmchan);
|
||||
static ftdm_status_t sngisdn_force_down(ftdm_channel_t *ftdmchan);
|
||||
|
||||
/* Remote side transmit a SETUP */
|
||||
void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
|
||||
@@ -191,8 +192,7 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
|
||||
strcpy(ftdmchan->caller_data.cid_name, retrieved_str);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
if (signal_data->overlap_dial == SNGISDN_OPT_TRUE && !conEvnt->sndCmplt.eh.pres) {
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_COLLECT);
|
||||
} else {
|
||||
@@ -831,7 +831,7 @@ void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event)
|
||||
if (sng_isdn_retrieve_facility_caller_name(&facEvnt->facElmt.facStr.val[2], facEvnt->facElmt.facStr.len, retrieved_str) == 0) {
|
||||
strcpy(ftdmchan->caller_data.cid_name, retrieved_str);
|
||||
} else {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Failed to retrieve Caller Name from Facility IE\n");
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Failed to retrieve Caller Name from Facility IE\n");
|
||||
}
|
||||
if (signal_data->facility_timeout) {
|
||||
/* Cancel facility timeout */
|
||||
@@ -920,36 +920,8 @@ void sngisdn_process_sta_cfm (sngisdn_event_data_t *sngisdn_event)
|
||||
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;
|
||||
if (sngisdn_force_down(ftdmchan) != FTDM_SUCCESS) {
|
||||
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;
|
||||
case 1:
|
||||
@@ -1159,6 +1131,48 @@ static void sngisdn_process_restart_confirm(ftdm_channel_t *ftdmchan)
|
||||
return;
|
||||
}
|
||||
|
||||
static ftdm_status_t sngisdn_force_down(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)ftdmchan->call_data;
|
||||
ftdm_status_t status = FTDM_SUCCESS;
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Forcing channel to DOWN state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
|
||||
switch (ftdmchan->state) {
|
||||
case FTDM_CHANNEL_STATE_DOWN:
|
||||
/* Do nothing */
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_RESET:
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
|
||||
break;
|
||||
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 already waiting for usr to respond to SIGEVENT stop.
|
||||
FreeTDM already scheduled a timout in case the User does respond to
|
||||
SIGEVENT_STOP, no need to do anything here */
|
||||
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;
|
||||
default:
|
||||
status = FTDM_FAIL;
|
||||
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
void sngisdn_process_rst_cfm (sngisdn_event_data_t *sngisdn_event)
|
||||
{
|
||||
@@ -1171,12 +1185,12 @@ void sngisdn_process_rst_cfm (sngisdn_event_data_t *sngisdn_event)
|
||||
|
||||
sngisdn_span_data_t *signal_data = g_sngisdn_data.dchans[dChan].spans[1];
|
||||
if (!signal_data) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Received RESTART on unconfigured span (suId:%d)\n", suId);
|
||||
ftdm_log(FTDM_LOG_CRIT, "Received RESTART CFM on unconfigured span (suId:%d)\n", suId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!rstEvnt->rstInd.eh.pres || !rstEvnt->rstInd.rstClass.pres) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Receved RESTART, but Restart Indicator IE not present\n");
|
||||
if (rstEvnt->rstInd.eh.pres != PRSNT_NODEF && rstEvnt->rstInd.rstClass.pres != PRSNT_NODEF) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Received RESTART, but Restart Indicator IE not present\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1233,24 +1247,101 @@ void sngisdn_process_rst_cfm (sngisdn_event_data_t *sngisdn_event)
|
||||
}
|
||||
|
||||
|
||||
/* The remote side sent us a RESTART Msg. Trillium automatically acks with RESTART ACK, but
|
||||
we need to clear our call states if there is a call on this channel */
|
||||
void sngisdn_process_rst_ind (sngisdn_event_data_t *sngisdn_event)
|
||||
{
|
||||
uint8_t chan_no = 0;
|
||||
int16_t suId = sngisdn_event->suId;
|
||||
int16_t dChan = sngisdn_event->dChan;
|
||||
uint8_t ces = sngisdn_event->ces;
|
||||
uint8_t evntType = sngisdn_event->evntType;
|
||||
Rst *rstEvnt = NULL;
|
||||
sngisdn_span_data_t *signal_data = NULL;
|
||||
|
||||
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
|
||||
/* 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,
|
||||
rstEvnt = &sngisdn_event->event.rstEvnt;
|
||||
|
||||
/* TODO: readjust this when NFAS is implemented as signal_data will not always be the first
|
||||
* span for that d-channel */
|
||||
|
||||
signal_data = g_sngisdn_data.dchans[dChan].spans[1];
|
||||
|
||||
if (!signal_data) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Received RESTART IND on unconfigured span (suId:%d)\n", suId);
|
||||
return;
|
||||
}
|
||||
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Processing RESTART IND (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");
|
||||
|
||||
if (!rstEvnt->rstInd.eh.pres || !rstEvnt->rstInd.rstClass.pres) {
|
||||
ftdm_log(FTDM_LOG_DEBUG, "Received RESTART IND, but Restart Indicator IE not present\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch(rstEvnt->rstInd.rstClass.val) {
|
||||
case IN_CL_INDCHAN: /* Indicated b-channel */
|
||||
if (rstEvnt->chanId.eh.pres) {
|
||||
if (rstEvnt->chanId.intType.val == IN_IT_BASIC) {
|
||||
if (rstEvnt->chanId.infoChanSel.pres == PRSNT_NODEF) {
|
||||
chan_no = rstEvnt->chanId.infoChanSel.val;
|
||||
}
|
||||
} else if (rstEvnt->chanId.intType.val == IN_IT_OTHER) {
|
||||
if (rstEvnt->chanId.chanNmbSlotMap.pres == PRSNT_NODEF) {
|
||||
chan_no = rstEvnt->chanId.chanNmbSlotMap.val[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!chan_no) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Failed to determine channel from RESTART\n");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case IN_CL_SNGINT: /* Single interface */
|
||||
case IN_CL_ALLINT: /* All interfaces */
|
||||
/* In case restart class indicates all interfaces, we will duplicate
|
||||
this event on each span associated to this d-channel in sngisdn_rcv_rst_cfm,
|
||||
so treat it as a single interface anyway */
|
||||
break;
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_CRIT, "Invalid restart indicator class:%d\n", rstEvnt->rstInd.rstClass.val);
|
||||
return;
|
||||
}
|
||||
|
||||
if (chan_no) { /* For a single channel */
|
||||
if (chan_no > ftdm_span_get_chan_count(signal_data->ftdm_span)) {
|
||||
ftdm_log(FTDM_LOG_CRIT, "Received RESTART IND on invalid channel:%d\n", chan_no);
|
||||
} else {
|
||||
ftdm_iterator_t *chaniter = NULL;
|
||||
ftdm_iterator_t *curr = NULL;
|
||||
|
||||
chaniter = ftdm_span_get_chan_iterator(signal_data->ftdm_span, NULL);
|
||||
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
|
||||
ftdm_channel_t *ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr);
|
||||
if (ftdmchan->physical_chan_id == chan_no) {
|
||||
sngisdn_force_down(ftdmchan);
|
||||
}
|
||||
}
|
||||
ftdm_iterator_free(chaniter);
|
||||
}
|
||||
} else { /* for all channels */
|
||||
ftdm_iterator_t *chaniter = NULL;
|
||||
ftdm_iterator_t *curr = NULL;
|
||||
|
||||
chaniter = ftdm_span_get_chan_iterator(signal_data->ftdm_span, NULL);
|
||||
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
|
||||
sngisdn_force_down((ftdm_channel_t*)ftdm_iterator_current(curr));
|
||||
}
|
||||
ftdm_iterator_free(chaniter);
|
||||
}
|
||||
|
||||
|
||||
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -708,7 +708,7 @@ void sngisdn_rcv_q921_ind(BdMngmt *status)
|
||||
void sngisdn_rcv_q931_ind(InMngmt *status)
|
||||
{
|
||||
if (status->t.usta.alarm.cause == 287) {
|
||||
get_memory_info();
|
||||
sngisdn_get_memory_info();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -779,7 +779,6 @@ void sngisdn_rcv_cc_ind(CcMngmt *status)
|
||||
void sngisdn_rcv_q931_trace(InMngmt *trc, Buffer *mBuf)
|
||||
{
|
||||
MsgLen mlen;
|
||||
MsgLen i;
|
||||
int16_t j;
|
||||
Buffer *tmp;
|
||||
Data *cptr;
|
||||
@@ -802,7 +801,6 @@ void sngisdn_rcv_q931_trace(InMngmt *trc, Buffer *mBuf)
|
||||
tmp = mBuf->b_cont;
|
||||
cptr = tmp->b_rptr;
|
||||
data = *cptr++;
|
||||
i = 0;
|
||||
|
||||
for(j=0;j<mlen;j++) {
|
||||
tdata[j]= data;
|
||||
|
||||
@@ -43,10 +43,53 @@ SNGISDN_STR2ENUM(ftdm_str2ftdm_sngisdn_progind_descr, ftdm_sngisdn_progind_descr
|
||||
SNGISDN_ENUM_NAMES(SNGISDN_PROGIND_LOC_NAMES, SNGISDN_PROGIND_LOC_STRINGS)
|
||||
SNGISDN_STR2ENUM(ftdm_str2ftdm_sngisdn_progind_loc, ftdm_sngisdn_progind_loc2str, ftdm_sngisdn_progind_loc_t, SNGISDN_PROGIND_LOC_NAMES, SNGISDN_PROGIND_LOC_INVALID)
|
||||
|
||||
ftdm_status_t sngisdn_check_free_ids(void);
|
||||
static uint8_t get_trillium_val(ftdm2trillium_t *vals, uint8_t ftdm_val, uint8_t default_val);
|
||||
static uint8_t get_ftdm_val(ftdm2trillium_t *vals, uint8_t trillium_val, uint8_t default_val);
|
||||
|
||||
extern ftdm_sngisdn_data_t g_sngisdn_data;
|
||||
void get_memory_info(void);
|
||||
|
||||
ftdm2trillium_t npi_codes[] = {
|
||||
{FTDM_NPI_UNKNOWN, IN_NP_UNK},
|
||||
{FTDM_NPI_ISDN, IN_NP_ISDN},
|
||||
{FTDM_NPI_DATA, IN_NP_DATA},
|
||||
{FTDM_NPI_TELEX, IN_NP_TELEX},
|
||||
{FTDM_NPI_NATIONAL, IN_NP_NATIONAL},
|
||||
{FTDM_NPI_PRIVATE, IN_NP_PRIVATE},
|
||||
{FTDM_NPI_RESERVED, IN_NP_EXT},
|
||||
};
|
||||
|
||||
ftdm2trillium_t ton_codes[] = {
|
||||
{FTDM_TON_UNKNOWN, IN_TON_UNK},
|
||||
{FTDM_TON_INTERNATIONAL, IN_TON_INT},
|
||||
{FTDM_TON_NATIONAL, IN_TON_NAT},
|
||||
{FTDM_TON_NETWORK_SPECIFIC, IN_TON_NETSPEC},
|
||||
{FTDM_TON_SUBSCRIBER_NUMBER, IN_TON_SUB},
|
||||
{FTDM_TON_ABBREVIATED_NUMBER, IN_TON_ABB},
|
||||
{FTDM_TON_RESERVED, IN_TON_EXT},
|
||||
};
|
||||
|
||||
static uint8_t get_trillium_val(ftdm2trillium_t *vals, uint8_t ftdm_val, uint8_t default_val)
|
||||
{
|
||||
ftdm2trillium_t *val = vals;
|
||||
while(val++) {
|
||||
if (val->ftdm_val == ftdm_val) {
|
||||
return val->trillium_val;
|
||||
}
|
||||
}
|
||||
return default_val;
|
||||
}
|
||||
|
||||
static uint8_t get_ftdm_val(ftdm2trillium_t *vals, uint8_t trillium_val, uint8_t default_val)
|
||||
{
|
||||
ftdm2trillium_t *val = vals;
|
||||
while(val++) {
|
||||
if (val->trillium_val == trillium_val) {
|
||||
return val->ftdm_val;
|
||||
}
|
||||
}
|
||||
return default_val;
|
||||
}
|
||||
|
||||
|
||||
void clear_call_data(sngisdn_chan_data_t *sngisdn_info)
|
||||
{
|
||||
@@ -259,11 +302,11 @@ ftdm_status_t get_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb)
|
||||
}
|
||||
|
||||
if (cdPtyNmb->nmbPlanId.pres == PRSNT_NODEF) {
|
||||
caller_data->dnis.plan = cdPtyNmb->nmbPlanId.val;
|
||||
caller_data->dnis.plan = get_ftdm_val(npi_codes, cdPtyNmb->nmbPlanId.val, IN_NP_UNK);
|
||||
}
|
||||
|
||||
if (cdPtyNmb->typeNmb0.pres == PRSNT_NODEF) {
|
||||
caller_data->dnis.type = cdPtyNmb->typeNmb0.val;
|
||||
caller_data->dnis.type = get_ftdm_val(ton_codes, cdPtyNmb->typeNmb0.val, IN_TON_UNK);
|
||||
}
|
||||
|
||||
if (cdPtyNmb->nmbDigits.pres == PRSNT_NODEF) {
|
||||
@@ -283,11 +326,11 @@ ftdm_status_t get_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb)
|
||||
}
|
||||
|
||||
if (redirNmb->nmbPlanId.pres == PRSNT_NODEF) {
|
||||
caller_data->rdnis.plan = redirNmb->nmbPlanId.val;
|
||||
caller_data->rdnis.plan = get_ftdm_val(npi_codes, redirNmb->nmbPlanId.val, IN_NP_UNK);
|
||||
}
|
||||
|
||||
if (redirNmb->typeNmb.pres == PRSNT_NODEF) {
|
||||
caller_data->rdnis.type = redirNmb->typeNmb.val;
|
||||
caller_data->rdnis.type = get_ftdm_val(ton_codes, redirNmb->typeNmb.val, IN_TON_UNK);
|
||||
}
|
||||
|
||||
if (redirNmb->nmbDigits.pres == PRSNT_NODEF) {
|
||||
@@ -382,11 +425,13 @@ ftdm_status_t get_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, uint8
|
||||
ftdm_status_t get_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd)
|
||||
{
|
||||
uint8_t val;
|
||||
|
||||
if (!progInd->eh.pres) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
|
||||
if (progInd->progDesc.pres) {
|
||||
/* TODO: use get_ftdm_val function and table here */
|
||||
switch (progInd->progDesc.val) {
|
||||
case IN_PD_NOTETEISDN:
|
||||
val = SNGISDN_PROGIND_DESCR_NETE_ISDN;
|
||||
@@ -464,19 +509,11 @@ ftdm_status_t set_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb)
|
||||
cgPtyNmb->presInd0.val = caller_data->pres;
|
||||
|
||||
cgPtyNmb->nmbPlanId.pres = PRSNT_NODEF;
|
||||
if (caller_data->cid_num.plan >= FTDM_NPI_INVALID) {
|
||||
cgPtyNmb->nmbPlanId.val = FTDM_NPI_UNKNOWN;
|
||||
} else {
|
||||
cgPtyNmb->nmbPlanId.val = caller_data->cid_num.plan;
|
||||
}
|
||||
cgPtyNmb->nmbPlanId.val = get_trillium_val(npi_codes, caller_data->cid_num.plan, IN_NP_UNK);
|
||||
|
||||
cgPtyNmb->typeNmb1.pres = PRSNT_NODEF;
|
||||
|
||||
if (caller_data->cid_num.type >= FTDM_TON_INVALID) {
|
||||
cgPtyNmb->typeNmb1.val = FTDM_TON_UNKNOWN;
|
||||
} else {
|
||||
cgPtyNmb->typeNmb1.val = caller_data->cid_num.type;
|
||||
}
|
||||
cgPtyNmb->typeNmb1.val = get_trillium_val(ton_codes, caller_data->cid_num.type, IN_TON_UNK);
|
||||
|
||||
cgPtyNmb->nmbDigits.pres = PRSNT_NODEF;
|
||||
cgPtyNmb->nmbDigits.len = len;
|
||||
@@ -510,7 +547,7 @@ ftdm_status_t set_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb)
|
||||
|
||||
val = FTDM_SCREENING_INVALID;
|
||||
string = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.cg_pty2.screening_ind");
|
||||
if ((string != NULL) && (*string)) {
|
||||
if (!ftdm_strlen_zero(string)) {
|
||||
val = ftdm_str2ftdm_screening(string);
|
||||
}
|
||||
|
||||
@@ -527,7 +564,7 @@ ftdm_status_t set_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb)
|
||||
|
||||
val = FTDM_PRES_INVALID;
|
||||
string = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.cg_pty2.presentation_ind");
|
||||
if ((string != NULL) && (*string)) {
|
||||
if (!ftdm_strlen_zero(string)) {
|
||||
val = ftdm_str2ftdm_presentation(string);
|
||||
}
|
||||
|
||||
@@ -542,14 +579,14 @@ ftdm_status_t set_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb)
|
||||
|
||||
val = FTDM_NPI_INVALID;
|
||||
string = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.cg_pty2.npi");
|
||||
if ((string != NULL) && (*string)) {
|
||||
if (!ftdm_strlen_zero(string)) {
|
||||
val = ftdm_str2ftdm_npi(string);
|
||||
}
|
||||
|
||||
if (val == FTDM_NPI_INVALID) {
|
||||
cgPtyNmb->nmbPlanId.val = caller_data->cid_num.plan;
|
||||
} else {
|
||||
cgPtyNmb->nmbPlanId.val = val;
|
||||
cgPtyNmb->nmbPlanId.val = get_trillium_val(npi_codes, val, IN_NP_UNK);
|
||||
}
|
||||
|
||||
cgPtyNmb->typeNmb1.pres = PRSNT_NODEF;
|
||||
@@ -557,14 +594,14 @@ ftdm_status_t set_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb)
|
||||
/* Type of Number */
|
||||
val = FTDM_TON_INVALID;
|
||||
string = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.cg_pty2.ton");
|
||||
if ((string != NULL) && (*string)) {
|
||||
if (!ftdm_strlen_zero(string)) {
|
||||
val = ftdm_str2ftdm_ton(string);
|
||||
}
|
||||
|
||||
if (val == FTDM_TON_INVALID) {
|
||||
cgPtyNmb->typeNmb1.val = caller_data->cid_num.type;
|
||||
} else {
|
||||
cgPtyNmb->typeNmb1.val = val;
|
||||
cgPtyNmb->typeNmb1.val = get_trillium_val(ton_codes, val, IN_TON_UNK);
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
@@ -577,21 +614,14 @@ ftdm_status_t set_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb)
|
||||
if (!len) {
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
cdPtyNmb->eh.pres = PRSNT_NODEF;
|
||||
|
||||
cdPtyNmb->nmbPlanId.pres = PRSNT_NODEF;
|
||||
if (caller_data->dnis.plan >= FTDM_NPI_INVALID) {
|
||||
cdPtyNmb->nmbPlanId.val = FTDM_NPI_UNKNOWN;
|
||||
} else {
|
||||
cdPtyNmb->nmbPlanId.val = caller_data->dnis.plan;
|
||||
}
|
||||
|
||||
cdPtyNmb->typeNmb0.pres = PRSNT_NODEF;
|
||||
if (caller_data->dnis.type >= FTDM_TON_INVALID) {
|
||||
cdPtyNmb->typeNmb0.val = FTDM_TON_UNKNOWN;
|
||||
} else {
|
||||
cdPtyNmb->typeNmb0.val = caller_data->dnis.type;
|
||||
}
|
||||
cdPtyNmb->eh.pres = PRSNT_NODEF;
|
||||
|
||||
cdPtyNmb->nmbPlanId.pres = PRSNT_NODEF;
|
||||
cdPtyNmb->nmbPlanId.val = get_trillium_val(npi_codes, caller_data->dnis.plan, IN_NP_UNK);
|
||||
|
||||
cdPtyNmb->typeNmb0.pres = PRSNT_NODEF;
|
||||
cdPtyNmb->typeNmb0.val = get_trillium_val(ton_codes, caller_data->dnis.type, IN_TON_UNK);
|
||||
|
||||
cdPtyNmb->nmbDigits.pres = PRSNT_NODEF;
|
||||
cdPtyNmb->nmbDigits.len = len;
|
||||
@@ -612,18 +642,10 @@ ftdm_status_t set_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb)
|
||||
redirNmb->eh.pres = PRSNT_NODEF;
|
||||
|
||||
redirNmb->nmbPlanId.pres = PRSNT_NODEF;
|
||||
if (caller_data->rdnis.plan >= FTDM_NPI_INVALID) {
|
||||
redirNmb->nmbPlanId.val = FTDM_NPI_UNKNOWN;
|
||||
} else {
|
||||
redirNmb->nmbPlanId.val = caller_data->rdnis.plan;
|
||||
}
|
||||
redirNmb->nmbPlanId.val = get_trillium_val(npi_codes, caller_data->rdnis.plan, IN_NP_UNK);
|
||||
|
||||
redirNmb->typeNmb.pres = PRSNT_NODEF;
|
||||
if (caller_data->rdnis.type >= FTDM_TON_INVALID) {
|
||||
redirNmb->typeNmb.val = FTDM_TON_UNKNOWN;
|
||||
} else {
|
||||
redirNmb->typeNmb.val = caller_data->rdnis.type;
|
||||
}
|
||||
redirNmb->typeNmb.val = get_trillium_val(ton_codes, caller_data->rdnis.type, IN_TON_UNK);
|
||||
|
||||
redirNmb->nmbDigits.pres = PRSNT_NODEF;
|
||||
redirNmb->nmbDigits.len = len;
|
||||
@@ -743,7 +765,7 @@ ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_s
|
||||
int loc = prog_ind.loc;
|
||||
|
||||
str = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.prog_ind.descr");
|
||||
if (str && *str) {
|
||||
if (!ftdm_strlen_zero(str)) {
|
||||
/* User wants to override progress indicator */
|
||||
descr = ftdm_str2ftdm_sngisdn_progind_descr(str);
|
||||
}
|
||||
@@ -754,7 +776,7 @@ ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_s
|
||||
}
|
||||
|
||||
str = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.prog_ind.loc");
|
||||
if (str && *str) {
|
||||
if (!ftdm_strlen_zero(str)) {
|
||||
loc = ftdm_str2ftdm_sngisdn_progind_loc(str);
|
||||
}
|
||||
if (loc == SNGISDN_PROGIND_LOC_INVALID) {
|
||||
@@ -1062,25 +1084,27 @@ ftdm_status_t sngisdn_check_free_ids(void)
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
void get_memory_info(void)
|
||||
void sngisdn_get_memory_info(void)
|
||||
{
|
||||
U32 availmen = 0;
|
||||
SRegInfoShow(S_REG, &availmen);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
uint8_t sngisdn_get_infoTranCap_from_user(ftdm_bearer_cap_t bearer_capability)
|
||||
{
|
||||
switch(bearer_capability) {
|
||||
case FTDM_BEARER_CAP_SPEECH:
|
||||
return IN_ITC_SPEECH;
|
||||
case FTDM_BEARER_CAP_64K_UNRESTRICTED:
|
||||
case FTDM_BEARER_CAP_UNRESTRICTED:
|
||||
return IN_ITC_UNRDIG;
|
||||
case FTDM_BEARER_CAP_3_1KHZ_AUDIO:
|
||||
return IN_ITC_A31KHZ;
|
||||
case FTDM_BEARER_CAP_INVALID:
|
||||
return IN_ITC_SPEECH;
|
||||
/* Do not put a default case here, so we can see compile warnings if we have unhandled cases */
|
||||
default:
|
||||
return IN_ITC_SPEECH;
|
||||
}
|
||||
return FTDM_BEARER_CAP_SPEECH;
|
||||
}
|
||||
@@ -1096,7 +1120,8 @@ uint8_t sngisdn_get_usrInfoLyr1Prot_from_user(ftdm_user_layer1_prot_t layer1_pro
|
||||
return IN_UIL1_G711ALAW;
|
||||
case FTDM_USER_LAYER1_PROT_INVALID:
|
||||
return IN_UIL1_G711ULAW;
|
||||
/* Do not put a default case here, so we can see compile warnings if we have unhandled cases */
|
||||
default:
|
||||
return IN_UIL1_G711ULAW;
|
||||
}
|
||||
return IN_UIL1_G711ULAW;
|
||||
}
|
||||
@@ -1105,9 +1130,9 @@ ftdm_bearer_cap_t sngisdn_get_infoTranCap_from_stack(uint8_t bearer_capability)
|
||||
{
|
||||
switch(bearer_capability) {
|
||||
case IN_ITC_SPEECH:
|
||||
return FTDM_BEARER_CAP_SPEECH;
|
||||
return FTDM_BEARER_CAP_SPEECH;
|
||||
case IN_ITC_UNRDIG:
|
||||
return FTDM_BEARER_CAP_64K_UNRESTRICTED;
|
||||
return FTDM_BEARER_CAP_UNRESTRICTED;
|
||||
case IN_ITC_A31KHZ:
|
||||
return FTDM_BEARER_CAP_3_1KHZ_AUDIO;
|
||||
default:
|
||||
@@ -1131,7 +1156,7 @@ ftdm_user_layer1_prot_t sngisdn_get_usrInfoLyr1Prot_from_stack(uint8_t layer1_pr
|
||||
return FTDM_USER_LAYER1_PROT_ULAW;
|
||||
}
|
||||
|
||||
void sngisdn_print_phy_stats(ftdm_stream_handle_t *stream, ftdm_span_t *span)
|
||||
ftdm_status_t sngisdn_show_l1_stats(ftdm_stream_handle_t *stream, ftdm_span_t *span)
|
||||
{
|
||||
L1Mngmt sts;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
|
||||
@@ -1169,11 +1194,11 @@ void sngisdn_print_phy_stats(ftdm_stream_handle_t *stream, ftdm_span_t *span)
|
||||
stream->write_function(stream, " TX Errors Details");
|
||||
stream->write_function(stream, "\n---------------------------------------------------------------------\n");
|
||||
stream->write_function(stream, "Aborted:\t%u\tFifo:\t\t%u\tCarrier:\t%u\n", sts.t.sts.tx_aborted_errors, sts.t.sts.tx_fifo_errors, sts.t.sts.tx_carrier_errors);
|
||||
return;
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
void sngisdn_print_span(ftdm_stream_handle_t *stream, ftdm_span_t *span)
|
||||
ftdm_status_t sngisdn_show_span(ftdm_stream_handle_t *stream, ftdm_span_t *span)
|
||||
{
|
||||
ftdm_signaling_status_t sigstatus;
|
||||
ftdm_alarm_flag_t alarmbits;
|
||||
@@ -1188,18 +1213,18 @@ void sngisdn_print_span(ftdm_stream_handle_t *stream, ftdm_span_t *span)
|
||||
stream->write_function(stream, "span:%s physical:%s signalling:%s\n",
|
||||
span->name, alarmbits ? "ALARMED" : "OK",
|
||||
ftdm_signaling_status2str(sigstatus));
|
||||
return;
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
void sngisdn_print_spans(ftdm_stream_handle_t *stream)
|
||||
ftdm_status_t sngisdn_show_spans(ftdm_stream_handle_t *stream)
|
||||
{
|
||||
int i;
|
||||
for(i=1;i<=MAX_L1_LINKS;i++) {
|
||||
if (g_sngisdn_data.spans[i]) {
|
||||
sngisdn_print_span(stream, g_sngisdn_data.spans[i]->ftdm_span);
|
||||
sngisdn_show_span(stream, g_sngisdn_data.spans[i]->ftdm_span);
|
||||
}
|
||||
}
|
||||
return;
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t sngisdn_add_var(sngisdn_chan_data_t *sngisdn_info, const char* var, const char* val)
|
||||
|
||||
@@ -334,11 +334,12 @@ uint32_t sngisdn_decode_ie(char *str, uint32_t *str_len, uint8_t current_codeset
|
||||
switch(ieId) {
|
||||
case PROT_Q931_IE_BEARER_CAP:
|
||||
{
|
||||
uint8_t codingStandard, infTransferCap, transferMode, infTransferRate, usrL1Prot;
|
||||
uint8_t codingStandard, infTransferCap, infTransferRate, usrL1Prot;
|
||||
/*uint8_t transferMode;*/
|
||||
|
||||
codingStandard = get_bits(OCTET(3),6,7);
|
||||
infTransferCap = get_bits(OCTET(3),1,5);
|
||||
transferMode = get_bits(OCTET(4),6,7);
|
||||
/*transferMode = get_bits(OCTET(4),6,7);*/
|
||||
infTransferRate = get_bits(OCTET(4),1,5);
|
||||
usrL1Prot = get_bits(OCTET(5),1,5);
|
||||
|
||||
@@ -404,8 +405,9 @@ uint32_t sngisdn_decode_ie(char *str, uint32_t *str_len, uint8_t current_codeset
|
||||
uint8_t infoChannelSelection=0;
|
||||
uint8_t prefExclusive=0;
|
||||
uint8_t ifaceIdPresent=0;
|
||||
uint8_t ifaceIdentifier = 0; /* octet_3_1 */
|
||||
uint8_t chanType=0, numberMap=0, codingStandard=0;
|
||||
/* uint8_t ifaceIdentifier = 0; */ /* octet_3_1 */
|
||||
uint8_t chanType=0, numberMap=0;
|
||||
/* uint8_t codingStandard=0; */
|
||||
uint8_t channelNo = 0;
|
||||
|
||||
infoChannelSelection = get_bits(OCTET(3),1,2);
|
||||
@@ -413,15 +415,15 @@ uint32_t sngisdn_decode_ie(char *str, uint32_t *str_len, uint8_t current_codeset
|
||||
ifaceIdPresent = get_bits(OCTET(3),7,7);
|
||||
|
||||
if (ifaceIdPresent) {
|
||||
ifaceIdentifier= get_bits(OCTET(4),1,7);
|
||||
/*ifaceIdentifier= get_bits(OCTET(4),1,7);*/
|
||||
chanType = get_bits(OCTET(5),1,4);
|
||||
numberMap = get_bits(OCTET(5),5,5);
|
||||
codingStandard = get_bits(OCTET(5),6,7);
|
||||
/*codingStandard = get_bits(OCTET(5),6,7);*/
|
||||
channelNo = get_bits(OCTET(6),1,7);
|
||||
} else {
|
||||
chanType = get_bits(OCTET(4),1,4);
|
||||
numberMap = get_bits(OCTET(4),5,5);
|
||||
codingStandard = get_bits(OCTET(4),6,7);
|
||||
/*codingStandard = get_bits(OCTET(4),6,7);*/
|
||||
channelNo = get_bits(OCTET(5),1,7);
|
||||
}
|
||||
|
||||
@@ -755,7 +757,7 @@ void print_hex_dump(char* str, uint32_t *str_len, uint8_t* data, uint32_t index_
|
||||
{
|
||||
uint32_t k;
|
||||
*str_len += sprintf(&str[*str_len], " [ ");
|
||||
for(k=index_start; k <= index_end; k++) {
|
||||
for(k=index_start; k < index_end; k++) {
|
||||
if (k && !(k%32)) {
|
||||
*str_len += sprintf(&str[*str_len], "\n ");
|
||||
}
|
||||
|
||||
@@ -33,12 +33,14 @@
|
||||
|
||||
/* INCLUDE ********************************************************************/
|
||||
#include "ftmod_sangoma_ss7_main.h"
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
/* DEFINES ********************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
/* PROTOTYPES *****************************************************************/
|
||||
@@ -79,14 +81,14 @@ ftdm_status_t handle_olm_msg(uint32_t suInstId, uint32_t spInstId, uint32_t circ
|
||||
/******************************************************************************/
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt)
|
||||
{
|
||||
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
|
||||
sngss7_chan_data_t *sngss7_info = NULL;
|
||||
ftdm_channel_t *ftdmchan = NULL;
|
||||
char nadi[2];
|
||||
|
||||
|
||||
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
|
||||
memset(nadi, '\0', sizeof(nadi));
|
||||
|
||||
/* get the ftdmchan and ss7_chan_data from the circuit */
|
||||
@@ -185,17 +187,11 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
|
||||
SS7_INFO_CHAN(ftdmchan,"No Called party (DNIS) information in IAM!%s\n", " ");
|
||||
}
|
||||
|
||||
/* fill in rdnis information*/
|
||||
if (siConEvnt->redirgNum.eh.pres) {
|
||||
if (siConEvnt->redirgNum.addrSig.pres) {
|
||||
/* fill in the rdnis digits */
|
||||
copy_tknStr_from_sngss7(siConEvnt->redirgNum.addrSig,
|
||||
ftdmchan->caller_data.rdnis.digits,
|
||||
siConEvnt->cgPtyNum.oddEven);
|
||||
}
|
||||
} else {
|
||||
SS7_DEBUG_CHAN(ftdmchan,"No RDNIS party information in IAM!%s\n", " ");
|
||||
}
|
||||
copy_redirgNum_from_sngss7(ftdmchan, &siConEvnt->redirgNum);
|
||||
|
||||
copy_genNmb_from_sngss7(ftdmchan, &siConEvnt->genNmb);
|
||||
|
||||
copy_cgPtyCat_from_sngss7(ftdmchan, &siConEvnt->cgPtyCat);
|
||||
|
||||
/* fill in the TMR/bearer capability */
|
||||
if (siConEvnt->txMedReq.eh.pres) {
|
||||
@@ -214,6 +210,10 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
|
||||
sprintf(nadi, "%d", siConEvnt->cdPtyNum.natAddrInd.val);
|
||||
sngss7_add_var(sngss7_info, "ss7_cld_nadi", nadi);
|
||||
|
||||
if (sngss7_info->circuit->transparent_iam) {
|
||||
sngss7_save_iam(ftdmchan, siConEvnt);
|
||||
}
|
||||
|
||||
/* check if a COT test is requested */
|
||||
if ((siConEvnt->natConInd.eh.pres) &&
|
||||
(siConEvnt->natConInd.contChkInd.pres) &&
|
||||
@@ -237,7 +237,6 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
|
||||
siConEvnt->cgPtyNum.natAddrInd.val,
|
||||
ftdmchan->caller_data.dnis.digits,
|
||||
siConEvnt->cdPtyNum.natAddrInd.val);
|
||||
|
||||
} /* if (channel is usable */
|
||||
|
||||
break;
|
||||
@@ -490,6 +489,47 @@ ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circ
|
||||
case (SUBDIRNUM):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx SUB-DIR\n", sngss7_info->circuit->cic);
|
||||
break;
|
||||
#ifdef SANGOMA_SPIROU
|
||||
case (CHARGE_ACK):
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx TXA\n", sngss7_info->circuit->cic);
|
||||
break;
|
||||
case (CHARGE_UNIT):
|
||||
{
|
||||
uint32_t charging_unit = 0;
|
||||
uint32_t msg_num = 0;
|
||||
char val[3];
|
||||
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx ITX\n", sngss7_info->circuit->cic);
|
||||
|
||||
memset(val, '\0', sizeof(val));
|
||||
|
||||
if (siCnStEvnt->chargUnitNum.eh.pres == PRSNT_NODEF &&
|
||||
siCnStEvnt->chargUnitNum.chargUnitNum.pres == PRSNT_NODEF) {
|
||||
|
||||
charging_unit = siCnStEvnt->chargUnitNum.chargUnitNum.val;
|
||||
}
|
||||
|
||||
if (siCnStEvnt->msgNum.eh.pres == PRSNT_NODEF &&
|
||||
siCnStEvnt->msgNum.msgNum.pres == PRSNT_NODEF) {
|
||||
|
||||
msg_num = siCnStEvnt->msgNum.msgNum.val;
|
||||
}
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Charging Unit:%d Msg Num:%d\n", charging_unit, msg_num);
|
||||
|
||||
sprintf(val, "%d", charging_unit);
|
||||
sngss7_add_var(sngss7_info, "ss7_itx_charge_unit", val);
|
||||
|
||||
sprintf(val, "%d", msg_num);
|
||||
sngss7_add_var(sngss7_info, "ss7_itx_msg_num", val);
|
||||
|
||||
if (sngss7_info->circuit->itx_auto_reply) {
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_INFO, "Auto-reply with TXA msg\n");
|
||||
ft_to_sngss7_txa (ftdmchan);
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
/**************************************************************************/
|
||||
default:
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx Unknown Msg\n", sngss7_info->circuit->cic);
|
||||
@@ -532,7 +572,7 @@ ftdm_status_t handle_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circ
|
||||
|
||||
/* go to UP */
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_UP);
|
||||
|
||||
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case FTDM_CHANNEL_STATE_DIALING:
|
||||
@@ -609,6 +649,7 @@ ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL);
|
||||
break;
|
||||
/**************************************************************************/
|
||||
case FTDM_CHANNEL_STATE_RING:
|
||||
case FTDM_CHANNEL_STATE_RINGING:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
|
||||
case FTDM_CHANNEL_STATE_UP:
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
static sng_isup_event_interface_t sng_event;
|
||||
static ftdm_io_interface_t g_ftdm_sngss7_interface;
|
||||
ftdm_sngss7_data_t g_ftdm_sngss7_data;
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
/* PROTOTYPES *****************************************************************/
|
||||
@@ -509,11 +510,6 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
|
||||
|
||||
SS7_DEBUG_CHAN(ftdmchan, "ftmod_sangoma_ss7 processing state %s\n", ftdm_channel_state2str (ftdmchan->state));
|
||||
|
||||
#if 0
|
||||
/* clear the state change flag...since we might be setting a new state */
|
||||
ftdm_channel_complete_state(ftdmchan);
|
||||
#endif
|
||||
|
||||
/*check what state we are supposed to be in */
|
||||
switch (ftdmchan->state) {
|
||||
/**************************************************************************/
|
||||
|
||||
@@ -60,6 +60,13 @@
|
||||
|
||||
#define MAX_SIZEOF_SUBADDR_IE 24 /* as per Q931 4.5.9 */
|
||||
|
||||
typedef struct ftdm2trillium
|
||||
{
|
||||
uint8_t ftdm_val;
|
||||
uint8_t trillium_val;
|
||||
}ftdm2trillium_t;
|
||||
|
||||
|
||||
typedef enum {
|
||||
SNGSS7_CON_IND_EVENT = 0,
|
||||
SNGSS7_CON_CFM_EVENT,
|
||||
@@ -320,8 +327,19 @@ typedef struct sng_isup_ckt {
|
||||
uint32_t clg_nadi;
|
||||
uint32_t cld_nadi;
|
||||
uint8_t rdnis_nadi;
|
||||
|
||||
/* Generic Number defaults */
|
||||
uint8_t gn_nmbqual; /* Number Qualifier */
|
||||
uint8_t gn_nadi; /* Nature of Address indicator */
|
||||
uint8_t gn_screen_ind; /* Screening Indicator */
|
||||
uint8_t gn_pres_ind; /* Presentation Indicator */
|
||||
uint8_t gn_npi; /* Numbering Plan Indicator */
|
||||
uint8_t gn_num_inc_ind; /* Number Incomplete Indicator */
|
||||
/* END - Generic Number defaults */
|
||||
|
||||
uint32_t min_digits;
|
||||
uint8_t itx_auto_reply;
|
||||
uint8_t transparent_iam;
|
||||
void *obj;
|
||||
uint16_t t3;
|
||||
uint16_t t12;
|
||||
@@ -389,6 +407,7 @@ typedef struct sng_ss7_cfg {
|
||||
uint32_t procId;
|
||||
char license[MAX_PATH];
|
||||
char signature[MAX_PATH];
|
||||
uint32_t transparent_iam_max_size;
|
||||
uint32_t flags;
|
||||
sng_relay_t relay[MAX_RELAY_CHANNELS+1];
|
||||
sng_mtp1_link_t mtp1Link[MAX_MTP_LINKS+1];
|
||||
@@ -728,6 +747,9 @@ void ft_to_sngss7_cgba(ftdm_channel_t * ftdmchan);
|
||||
void ft_to_sngss7_cgua(ftdm_channel_t * ftdmchan);
|
||||
void ft_to_sngss7_cgb(ftdm_channel_t * ftdmchan);
|
||||
void ft_to_sngss7_cgu(ftdm_channel_t * ftdmchan);
|
||||
void ft_to_sngss7_itx (ftdm_channel_t * ftdmchan);
|
||||
void ft_to_sngss7_txa (ftdm_channel_t * ftdmchan);
|
||||
|
||||
|
||||
/* in ftmod_sangoma_ss7_in.c */
|
||||
void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint8_t globalFlg, uint8_t evntType, SiStaEvnt *siStaEvnt);
|
||||
@@ -745,6 +767,10 @@ void sngss7_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiR
|
||||
void sngss7_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt);
|
||||
void sngss7_ssp_sta_cfm(uint32_t infId);
|
||||
|
||||
ftdm_status_t sngss7_bufferzero_iam(SiConEvnt *siConEvnt);
|
||||
ftdm_status_t sngss7_retrieve_iam(ftdm_channel_t *ftdmchan, SiConEvnt *siConEvnt);
|
||||
ftdm_status_t sngss7_save_iam(ftdm_channel_t *ftdmchan, SiConEvnt *siConEvnt);
|
||||
|
||||
/* in ftmod_sangoma_ss7_handle.c */
|
||||
ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt);
|
||||
ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCnStEvnt *siCnStEvnt, uint8_t evntType);
|
||||
@@ -785,12 +811,21 @@ int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *spa
|
||||
ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const char *data);
|
||||
|
||||
/* in ftmod_sangoma_ss7_support.c */
|
||||
uint8_t copy_cgPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum);
|
||||
uint8_t copy_cgPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCgPtyNum *cgPtyNum);
|
||||
uint8_t copy_cdPtyNum_from_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum);
|
||||
uint8_t copy_cdPtyNum_to_sngss7(ftdm_caller_data_t *ftdm, SiCdPtyNum *cdPtyNum);
|
||||
ftdm_status_t copy_cgPtyNum_from_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyNum *cgPtyNum);
|
||||
ftdm_status_t copy_cgPtyNum_to_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyNum *cgPtyNum);
|
||||
ftdm_status_t copy_cdPtyNum_from_sngss7(ftdm_channel_t *ftdmchan, SiCdPtyNum *cdPtyNum);
|
||||
ftdm_status_t copy_cdPtyNum_to_sngss7(ftdm_channel_t *ftdmchan, SiCdPtyNum *cdPtyNum);
|
||||
ftdm_status_t copy_redirgNum_to_sngss7(ftdm_channel_t *ftdmchan, SiRedirNum *redirgNum);
|
||||
|
||||
ftdm_status_t copy_redirgNum_from_sngss7(ftdm_channel_t *ftdmchan, SiRedirNum *redirgNum);
|
||||
ftdm_status_t copy_genNmb_to_sngss7(ftdm_channel_t *ftdmchan, SiGenNum *genNmb);
|
||||
ftdm_status_t copy_genNmb_from_sngss7(ftdm_channel_t *ftdmchan, SiGenNum *genNmb);
|
||||
ftdm_status_t copy_cgPtyCat_to_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyCat *cgPtyCat);
|
||||
ftdm_status_t copy_cgPtyCat_from_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyCat *cgPtyCat);
|
||||
ftdm_status_t copy_accTrnspt_to_sngss7(ftdm_channel_t *ftdmchan, SiAccTrnspt *accTrnspt);
|
||||
ftdm_status_t copy_natConInd_to_sngss7(ftdm_channel_t *ftdmchan, SiNatConInd *natConInd);
|
||||
ftdm_status_t copy_fwdCallInd_to_sngss7(ftdm_channel_t *ftdmchan, SiFwdCallInd *fwdCallInd);
|
||||
ftdm_status_t copy_txMedReq_to_sngss7(ftdm_channel_t *ftdmchan, SiTxMedReq *txMedReq);
|
||||
ftdm_status_t copy_usrServInfoA_to_sngss7(ftdm_channel_t *ftdmchan, SiUsrServInfo *usrServInfoA);
|
||||
|
||||
ftdm_status_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven);
|
||||
ftdm_status_t append_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven);
|
||||
|
||||
@@ -36,10 +36,8 @@
|
||||
/******************************************************************************/
|
||||
|
||||
/* DEFINES ********************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/* GLOBALS ********************************************************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/* PROTOTYPES *****************************************************************/
|
||||
void ft_to_sngss7_iam(ftdm_channel_t * ftdmchan);
|
||||
@@ -66,243 +64,74 @@ void ft_to_sngss7_cgu(ftdm_channel_t * ftdmchan);
|
||||
|
||||
void ft_to_sngss7_cgba(ftdm_channel_t * ftdmchan);
|
||||
void ft_to_sngss7_cgua(ftdm_channel_t * ftdmchan);
|
||||
/******************************************************************************/
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
|
||||
{
|
||||
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
|
||||
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;;
|
||||
const char *clg_nadi = NULL;
|
||||
const char *cld_nadi = NULL;
|
||||
const char *clg_subAddr = NULL;
|
||||
const char *cld_subAddr = NULL;
|
||||
char subAddrIE[MAX_SIZEOF_SUBADDR_IE];
|
||||
{
|
||||
SiConEvnt iam;
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;;
|
||||
|
||||
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
|
||||
|
||||
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_PREFAW;
|
||||
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;
|
||||
|
||||
if ((g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType == LSI_SW_ANS88) ||
|
||||
(g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType == LSI_SW_ANS92) ||
|
||||
(g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType == LSI_SW_ANS95)) {
|
||||
|
||||
/* include only if we're running ANSI */
|
||||
iam.fwdCallInd.transCallNInd.pres = PRSNT_NODEF;
|
||||
iam.fwdCallInd.transCallNInd.val = 0x0;
|
||||
|
||||
iam.usrServInfoA.eh.pres = PRSNT_NODEF;
|
||||
|
||||
iam.usrServInfoA.infoTranCap.pres = PRSNT_NODEF;
|
||||
switch (ftdmchan->caller_data.bearer_capability) {
|
||||
/**********************************************************************/
|
||||
case (FTDM_BEARER_CAP_SPEECH):
|
||||
iam.usrServInfoA.infoTranCap.val = 0x0; /* speech as per ATIS-1000113.3.2005 */
|
||||
break;
|
||||
/**********************************************************************/
|
||||
case (FTDM_BEARER_CAP_64K_UNRESTRICTED):
|
||||
iam.usrServInfoA.infoTranCap.val = 0x8; /* unrestricted digital as per ATIS-1000113.3.2005 */
|
||||
break;
|
||||
/**********************************************************************/
|
||||
case (FTDM_BEARER_CAP_3_1KHZ_AUDIO):
|
||||
iam.usrServInfoA.infoTranCap.val = 0x10; /* 3.1kHz audio as per ATIS-1000113.3.2005 */
|
||||
break;
|
||||
/**********************************************************************/
|
||||
default:
|
||||
SS7_ERROR_CHAN(ftdmchan, "Unknown Bearer capability falling back to speech%s\n", " ");
|
||||
iam.usrServInfoA.infoTranCap.val = 0x0; /* speech as per ATIS-1000113.3.2005 */
|
||||
break;
|
||||
/**********************************************************************/
|
||||
} /* switch (ftdmchan->caller_data.bearer_capability) */
|
||||
|
||||
iam.usrServInfoA.cdeStand.pres = PRSNT_NODEF;
|
||||
iam.usrServInfoA.cdeStand.val = 0x0; /* ITU-T standardized coding */
|
||||
iam.usrServInfoA.tranMode.pres = PRSNT_NODEF;
|
||||
iam.usrServInfoA.tranMode.val = 0x0; /* circuit mode */
|
||||
iam.usrServInfoA.infoTranRate0.pres = PRSNT_NODEF;
|
||||
iam.usrServInfoA.infoTranRate0.val = 0x10; /* 64kbps origination to destination */
|
||||
iam.usrServInfoA.infoTranRate1.pres = PRSNT_NODEF;
|
||||
iam.usrServInfoA.infoTranRate1.val = 0x10; /* 64kbps destination to origination */
|
||||
iam.usrServInfoA.chanStruct.pres = PRSNT_NODEF;
|
||||
iam.usrServInfoA.chanStruct.val = 0x1; /* 8kHz integrity */
|
||||
iam.usrServInfoA.config.pres = PRSNT_NODEF;
|
||||
iam.usrServInfoA.config.val = 0x0; /* point to point configuration */
|
||||
iam.usrServInfoA.establish.pres = PRSNT_NODEF;
|
||||
iam.usrServInfoA.establish.val = 0x0; /* on demand */
|
||||
iam.usrServInfoA.symmetry.pres = PRSNT_NODEF;
|
||||
iam.usrServInfoA.symmetry.val = 0x0; /* bi-directional symmetric */
|
||||
iam.usrServInfoA.usrInfLyr1Prot.pres = PRSNT_NODEF;
|
||||
iam.usrServInfoA.usrInfLyr1Prot.val = 0x2; /* G.711 ulaw */
|
||||
iam.usrServInfoA.rateMultiplier.pres = PRSNT_NODEF;
|
||||
iam.usrServInfoA.rateMultiplier.val = 0x1; /* 1x rate multipler */
|
||||
} /* if ANSI */
|
||||
|
||||
/* 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);
|
||||
|
||||
/* check if the user would like a custom NADI value for the calling Pty Num */
|
||||
clg_nadi = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_clg_nadi");
|
||||
if ((clg_nadi != NULL) && (*clg_nadi)) {
|
||||
SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Calling NADI value \"%s\"\n", clg_nadi);
|
||||
iam.cgPtyNum.natAddrInd.val = atoi(clg_nadi);
|
||||
if (sngss7_info->circuit->transparent_iam &&
|
||||
sngss7_retrieve_iam(ftdmchan, &iam) == FTDM_SUCCESS) {
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Transparent)\n", sngss7_info->circuit->cic);
|
||||
} else {
|
||||
iam.cgPtyNum.natAddrInd.val = g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].clg_nadi;
|
||||
SS7_DEBUG_CHAN(ftdmchan,"No user supplied NADI value found for CLG, using \"%d\"\n", iam.cgPtyNum.natAddrInd.val);
|
||||
}
|
||||
|
||||
cld_nadi = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_cld_nadi");
|
||||
if ((cld_nadi != NULL) && (*cld_nadi)) {
|
||||
SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Called NADI value \"%s\"\n", cld_nadi);
|
||||
iam.cdPtyNum.natAddrInd.val = atoi(cld_nadi);
|
||||
} else {
|
||||
iam.cdPtyNum.natAddrInd.val = g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].cld_nadi;
|
||||
SS7_DEBUG_CHAN(ftdmchan,"No user supplied NADI value found for CLD, using \"%d\"\n", iam.cdPtyNum.natAddrInd.val);
|
||||
}
|
||||
/* Nature of Connection Indicators */
|
||||
copy_natConInd_to_sngss7(ftdmchan, &iam.natConInd);
|
||||
|
||||
/* check if the user would like us to send a clg_sub-address */
|
||||
clg_subAddr = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_clg_subaddr");
|
||||
if ((clg_subAddr != NULL) && (*clg_subAddr)) {
|
||||
SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Calling Sub-Address value \"%s\"\n", clg_subAddr);
|
||||
/* Forward Call Indicators */
|
||||
copy_fwdCallInd_to_sngss7(ftdmchan, &iam.fwdCallInd);
|
||||
|
||||
/* Transmission medium requirements */
|
||||
copy_txMedReq_to_sngss7(ftdmchan, &iam.txMedReq);
|
||||
|
||||
/* User Service Info A */
|
||||
copy_usrServInfoA_to_sngss7(ftdmchan, &iam.usrServInfoA);
|
||||
|
||||
/* clean out the subAddrIE */
|
||||
memset(subAddrIE, 0x0, sizeof(subAddrIE));
|
||||
|
||||
/* check the first character in the sub-address to see what type of encoding to use */
|
||||
switch (clg_subAddr[0]) {
|
||||
case '0': /* NSAP */
|
||||
encode_subAddrIE_nsap(&clg_subAddr[1], subAddrIE, SNG_CALLING);
|
||||
break;
|
||||
case '1': /* national variant */
|
||||
encode_subAddrIE_nat(&clg_subAddr[1], subAddrIE, SNG_CALLING);
|
||||
break;
|
||||
default:
|
||||
SS7_ERROR_CHAN(ftdmchan,"Invalid Calling Sub-Address encoding requested: %c\n", clg_subAddr[0]);
|
||||
break;
|
||||
} /* switch (cld_subAddr[0]) */
|
||||
|
||||
|
||||
/* if subaddIE is still empty don't copy it in */
|
||||
if (subAddrIE[0] != '0') {
|
||||
/* check if the clg_subAddr has already been added */
|
||||
if (iam.accTrnspt.eh.pres == PRSNT_NODEF) {
|
||||
/* append the subAddrIE */
|
||||
memcpy(&iam.accTrnspt.infoElmts.val[iam.accTrnspt.infoElmts.len], subAddrIE, (subAddrIE[1] + 2));
|
||||
iam.accTrnspt.infoElmts.len = iam.accTrnspt.infoElmts.len +subAddrIE[1] + 2;
|
||||
} else {
|
||||
/* fill in from the beginning */
|
||||
iam.accTrnspt.eh.pres = PRSNT_NODEF;
|
||||
iam.accTrnspt.infoElmts.pres = PRSNT_NODEF;
|
||||
memcpy(iam.accTrnspt.infoElmts.val, subAddrIE, (subAddrIE[1] + 2));
|
||||
iam.accTrnspt.infoElmts.len = subAddrIE[1] + 2;
|
||||
} /* if (iam.accTrnspt.eh.pres */
|
||||
} /* if (subAddrIE[0] != '0') */
|
||||
}
|
||||
|
||||
copy_redirgNum_to_sngss7(ftdmchan, &iam.redirgNum);
|
||||
|
||||
/* check if the user would like us to send a cld_sub-address */
|
||||
cld_subAddr = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_cld_subaddr");
|
||||
if ((cld_subAddr != NULL) && (*cld_subAddr)) {
|
||||
SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Called Sub-Address value \"%s\"\n", cld_subAddr);
|
||||
/* Called Number information */
|
||||
copy_cdPtyNum_to_sngss7(ftdmchan, &iam.cdPtyNum);
|
||||
|
||||
/* clean out the subAddrIE */
|
||||
memset(subAddrIE, 0x0, sizeof(subAddrIE));
|
||||
/* Calling Number information */
|
||||
copy_cgPtyNum_to_sngss7(ftdmchan, &iam.cgPtyNum);
|
||||
|
||||
/* check the first character in the sub-address to see what type of encoding to use */
|
||||
switch (cld_subAddr[0]) {
|
||||
case '0': /* NSAP */
|
||||
encode_subAddrIE_nsap(&cld_subAddr[1], subAddrIE, SNG_CALLED);
|
||||
break;
|
||||
case '1': /* national variant */
|
||||
encode_subAddrIE_nat(&cld_subAddr[1], subAddrIE, SNG_CALLED);
|
||||
break;
|
||||
default:
|
||||
SS7_ERROR_CHAN(ftdmchan,"Invalid Called Sub-Address encoding requested: %c\n", cld_subAddr[0]);
|
||||
break;
|
||||
} /* switch (cld_subAddr[0]) */
|
||||
/* Generic Number information */
|
||||
copy_genNmb_to_sngss7(ftdmchan, &iam.genNmb);
|
||||
|
||||
/* if subaddIE is still empty don't copy it in */
|
||||
if (subAddrIE[0] != '0') {
|
||||
/* check if the cld_subAddr has already been added */
|
||||
if (iam.accTrnspt.eh.pres == PRSNT_NODEF) {
|
||||
/* append the subAddrIE */
|
||||
memcpy(&iam.accTrnspt.infoElmts.val[iam.accTrnspt.infoElmts.len], subAddrIE, (subAddrIE[1] + 2));
|
||||
iam.accTrnspt.infoElmts.len = iam.accTrnspt.infoElmts.len +subAddrIE[1] + 2;
|
||||
} else {
|
||||
/* fill in from the beginning */
|
||||
iam.accTrnspt.eh.pres = PRSNT_NODEF;
|
||||
iam.accTrnspt.infoElmts.pres = PRSNT_NODEF;
|
||||
memcpy(iam.accTrnspt.infoElmts.val, subAddrIE, (subAddrIE[1] + 2));
|
||||
iam.accTrnspt.infoElmts.len = subAddrIE[1] + 2;
|
||||
} /* if (iam.accTrnspt.eh.pres */
|
||||
} /* if (subAddrIE[0] != '0') */
|
||||
} /* if ((cld_subAddr != NULL) && (*cld_subAddr)) */
|
||||
/* Calling Party's Category */
|
||||
copy_cgPtyCat_to_sngss7(ftdmchan, &iam.cgPtyCat);
|
||||
|
||||
/* Redirecting Number */
|
||||
copy_redirgNum_to_sngss7(ftdmchan, &iam.redirgNum);
|
||||
|
||||
/* Access Transport */
|
||||
copy_accTrnspt_to_sngss7(ftdmchan, &iam.accTrnspt);
|
||||
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM clg = \"%s\" (NADI=%d), cld = \"%s\" (NADI=%d)\n",
|
||||
sngss7_info->circuit->cic,
|
||||
ftdmchan->caller_data.cid_num.digits,
|
||||
iam.cgPtyNum.natAddrInd.val,
|
||||
ftdmchan->caller_data.dnis.digits,
|
||||
iam.cdPtyNum.natAddrInd.val);
|
||||
}
|
||||
|
||||
sng_cc_con_request (sngss7_info->spId,
|
||||
sngss7_info->suInstId,
|
||||
sngss7_info->spInstId,
|
||||
sngss7_info->circuit->id,
|
||||
&iam,
|
||||
sngss7_info->circuit->id,
|
||||
&iam,
|
||||
0);
|
||||
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM clg = \"%s\" (NADI=%d), cld = \"%s\" (NADI=%d)\n",
|
||||
sngss7_info->circuit->cic,
|
||||
ftdmchan->caller_data.cid_num.digits,
|
||||
iam.cgPtyNum.natAddrInd.val,
|
||||
ftdmchan->caller_data.dnis.digits,
|
||||
iam.cdPtyNum.natAddrInd.val);
|
||||
|
||||
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan)
|
||||
{
|
||||
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
|
||||
@@ -339,7 +168,7 @@ void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan)
|
||||
acm.bckCallInd.echoCtrlDevInd.val = 0x1;
|
||||
break;
|
||||
/**********************************************************************/
|
||||
case (FTDM_BEARER_CAP_64K_UNRESTRICTED):
|
||||
case (FTDM_BEARER_CAP_UNRESTRICTED):
|
||||
acm.bckCallInd.echoCtrlDevInd.val = 0x0;
|
||||
break;
|
||||
/**********************************************************************/
|
||||
@@ -382,7 +211,6 @@ void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan)
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void ft_to_sngss7_anm (ftdm_channel_t * ftdmchan)
|
||||
{
|
||||
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
|
||||
@@ -892,6 +720,69 @@ void ft_to_sngss7_cgu(ftdm_channel_t * ftdmchan)
|
||||
return;
|
||||
}
|
||||
|
||||
/* French SPIROU send Charge Unit */
|
||||
/* No one calls this function yet, but it has been implemented to complement TXA messages */
|
||||
void ft_to_sngss7_itx (ftdm_channel_t * ftdmchan)
|
||||
{
|
||||
#ifndef SANGOMA_SPIROU
|
||||
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "ITX message not supported!, please update your libsng_ss7\n");
|
||||
#else
|
||||
const char* var = NULL;
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
SiCnStEvnt itx;
|
||||
|
||||
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
|
||||
|
||||
memset (&itx, 0x0, sizeof (itx));
|
||||
|
||||
itx.msgNum.eh.pres = PRSNT_NODEF;
|
||||
itx.msgNum.msgNum.pres = PRSNT_NODEF;
|
||||
var = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_itx_msg_num");
|
||||
if (!ftdm_strlen_zero(var)) {
|
||||
itx.msgNum.msgNum.val = atoi(var);
|
||||
} else {
|
||||
itx.msgNum.msgNum.val = 0x1;
|
||||
}
|
||||
|
||||
itx.chargUnitNum.eh.pres = PRSNT_NODEF;
|
||||
itx.chargUnitNum.chargUnitNum.pres = PRSNT_NODEF;
|
||||
var = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_itx_charge_unit");
|
||||
if (!ftdm_strlen_zero(var)) {
|
||||
itx.chargUnitNum.chargUnitNum.val = atoi(var);
|
||||
} else {
|
||||
itx.chargUnitNum.chargUnitNum.val = 0x1;
|
||||
}
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "ITX Charging Unit:%d Msg Num:%d\n", itx.chargUnitNum.chargUnitNum.val, itx.msgNum.msgNum.val);
|
||||
sng_cc_con_status (1, sngss7_info->suInstId, sngss7_info->spInstId, sngss7_info->circuit->id, &itx, CHARGE_UNIT);
|
||||
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx ITX\n", sngss7_info->circuit->cic);
|
||||
#endif
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
/* French SPIROU send Charging Acknowledgement */
|
||||
void ft_to_sngss7_txa (ftdm_channel_t * ftdmchan)
|
||||
{
|
||||
#ifndef SANGOMA_SPIROU
|
||||
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "TXA message not supported!, please update your libsng_ss7\n");
|
||||
#else
|
||||
SiCnStEvnt txa;
|
||||
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
|
||||
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
|
||||
|
||||
memset (&txa, 0x0, sizeof(txa));
|
||||
|
||||
sng_cc_con_status(1, sngss7_info->suInstId, sngss7_info->spInstId, sngss7_info->circuit->id, &txa, CHARGE_ACK);
|
||||
|
||||
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx TXA\n", sngss7_info->circuit->cic);
|
||||
#endif
|
||||
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* For Emacs:
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -124,6 +124,8 @@ typedef struct sng_ccSpan
|
||||
uint32_t cld_nadi;
|
||||
uint32_t rdnis_nadi;
|
||||
uint32_t min_digits;
|
||||
uint8_t itx_auto_reply;
|
||||
uint8_t transparent_iam;
|
||||
uint32_t t3;
|
||||
uint32_t t12;
|
||||
uint32_t t13;
|
||||
@@ -465,6 +467,9 @@ static int ftmod_ss7_parse_sng_gen(ftdm_conf_node_t *sng_gen)
|
||||
SS7_DEBUG("Found license file = %s\n", g_ftdm_sngss7_data.cfg.license);
|
||||
SS7_DEBUG("Found signature file = %s\n", g_ftdm_sngss7_data.cfg.signature);
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "transparent_iam_max_size")) {
|
||||
g_ftdm_sngss7_data.cfg.transparent_iam_max_size = atoi(parm->val);
|
||||
SS7_DEBUG("Found a transparent_iam max size = %d\n", g_ftdm_sngss7_data.cfg.transparent_iam_max_size);
|
||||
} else {
|
||||
/**********************************************************************/
|
||||
SS7_ERROR("Found an invalid parameter \"%s\"!\n", parm->val);
|
||||
@@ -1892,7 +1897,16 @@ static int ftmod_ss7_parse_cc_span(ftdm_conf_node_t *cc_span)
|
||||
sng_ccSpan.typeCntrl = sng_cic_cntrl_type_map[ret].tril_type;
|
||||
SS7_DEBUG("Found an ccSpan typeCntrl = %s\n", sng_cic_cntrl_type_map[ret].sng_type);
|
||||
}
|
||||
/**********************************************************************/
|
||||
} else if (!strcasecmp(parm->var, "itx_auto_reply")) {
|
||||
sng_ccSpan.itx_auto_reply = ftdm_true(parm->val);
|
||||
SS7_DEBUG("Found itx_auto_reply %d\n", sng_ccSpan.itx_auto_reply);
|
||||
} else if (!strcasecmp(parm->var, "transparent_iam")) {
|
||||
#ifndef HAVE_ZLIB
|
||||
SS7_CRIT("Cannot enable transparent IAM becauze zlib not installed\n");
|
||||
#else
|
||||
sng_ccSpan.transparent_iam = ftdm_true(parm->val);
|
||||
SS7_DEBUG("Found transparent_iam %d\n", sng_ccSpan.transparent_iam);
|
||||
#endif
|
||||
} else if (!strcasecmp(parm->var, "cicbase")) {
|
||||
/**********************************************************************/
|
||||
sng_ccSpan.cicbase = atoi(parm->val);
|
||||
@@ -2904,15 +2918,17 @@ static int ftmod_ss7_fill_in_ccSpan(sng_ccSpan_t *ccSpan)
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].cic = 0;
|
||||
}
|
||||
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].infId = ccSpan->isupInf;
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].typeCntrl = ccSpan->typeCntrl;
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].ssf = ccSpan->ssf;
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].cld_nadi = ccSpan->cld_nadi;
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].clg_nadi = ccSpan->clg_nadi;
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].rdnis_nadi = ccSpan->rdnis_nadi;
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].options = ccSpan->options;
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].switchType = ccSpan->switchType;
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].min_digits = ccSpan->min_digits;
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].infId = ccSpan->isupInf;
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].typeCntrl = ccSpan->typeCntrl;
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].ssf = ccSpan->ssf;
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].cld_nadi = ccSpan->cld_nadi;
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].clg_nadi = ccSpan->clg_nadi;
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].rdnis_nadi = ccSpan->rdnis_nadi;
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].options = ccSpan->options;
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].switchType = ccSpan->switchType;
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].min_digits = ccSpan->min_digits;
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].itx_auto_reply = ccSpan->itx_auto_reply;
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].transparent_iam = ccSpan->transparent_iam;
|
||||
|
||||
if (ccSpan->t3 == 0) {
|
||||
g_ftdm_sngss7_data.cfg.isupCkt[x].t3 = 1200;
|
||||
|
||||
@@ -950,7 +950,6 @@ static void wanpipe_read_stats(ftdm_channel_t *ftdmchan, wp_tdm_api_rx_hdr_t *rx
|
||||
static FIO_READ_FUNCTION(wanpipe_read)
|
||||
{
|
||||
int rx_len = 0;
|
||||
int myerrno = 0;
|
||||
wp_tdm_api_rx_hdr_t hdrframe;
|
||||
|
||||
memset(&hdrframe, 0, sizeof(hdrframe));
|
||||
@@ -964,7 +963,6 @@ static FIO_READ_FUNCTION(wanpipe_read)
|
||||
}
|
||||
|
||||
if (rx_len < 0) {
|
||||
myerrno = errno;
|
||||
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", strerror(errno));
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Failed to read from sangoma device: %s (%d)\n", strerror(errno), rx_len);
|
||||
return FTDM_FAIL;
|
||||
@@ -1269,7 +1267,7 @@ static FIO_GET_ALARMS_FUNCTION(wanpipe_get_alarms)
|
||||
ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_LINK_STATUS, &sangoma_status);
|
||||
ftdmchan->alarm_flags = sangoma_status == FTDM_HW_LINK_DISCONNECTED ? FTDM_ALARM_RED : FTDM_ALARM_NONE;
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Link status is %d\n", sangoma_status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (alarms) {
|
||||
@@ -1293,6 +1291,7 @@ static __inline__ ftdm_status_t wanpipe_channel_process_event(ftdm_channel_t *fc
|
||||
switch(tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_type) {
|
||||
case WP_API_EVENT_LINK_STATUS:
|
||||
{
|
||||
if (FTDM_IS_DIGITAL_CHANNEL(fchan)) {
|
||||
switch(tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_link_status) {
|
||||
case WP_TDMAPI_EVENT_LINK_STATUS_CONNECTED:
|
||||
/* *event_id = FTDM_OOB_ALARM_CLEAR; */
|
||||
@@ -1305,6 +1304,22 @@ static __inline__ ftdm_status_t wanpipe_channel_process_event(ftdm_channel_t *fc
|
||||
};
|
||||
/* The WP_API_EVENT_ALARM event should be used to clear alarms */
|
||||
*event_id = FTDM_OOB_NOOP;
|
||||
} else {
|
||||
switch(tdm_api->wp_tdm_cmd.event.wp_tdm_api_event_link_status) {
|
||||
case WP_TDMAPI_EVENT_LINK_STATUS_CONNECTED:
|
||||
/* *event_id = FTDM_OOB_ALARM_CLEAR; */
|
||||
ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "Using analog link connected event as alarm clear\n");
|
||||
*event_id = FTDM_OOB_ALARM_CLEAR;
|
||||
fchan->alarm_flags = FTDM_ALARM_NONE;
|
||||
break;
|
||||
default:
|
||||
/* *event_id = FTDM_OOB_ALARM_TRAP; */
|
||||
ftdm_log_chan_msg(fchan, FTDM_LOG_DEBUG, "Using analog link disconnected event as alarm trap\n");
|
||||
*event_id = FTDM_OOB_ALARM_TRAP;
|
||||
fchan->alarm_flags = FTDM_ALARM_RED;
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
Reference in new issue
Block a user