Merge branch 'davidy.channel_restart'

This commit is contained in:
David Yat Sin 2010-12-15 16:43:33 -05:00
commit c602e04ff6
15 changed files with 440 additions and 317 deletions

View File

@ -2167,6 +2167,7 @@ static FIO_SIGNAL_CB_FUNCTION(on_clear_channel_signal)
}
break;
case FTDM_SIGEVENT_PROGRESS:
case FTDM_SIGEVENT_RINGING:
{
if ((session = ftdm_channel_get_session(sigmsg->channel, 0))) {
channel = switch_core_session_get_channel(session);
@ -3922,6 +3923,28 @@ SWITCH_STANDARD_API(ft_function)
}
}
stream->write_function(stream, "+OK gains set to Rx %f and Tx %f\n", rxgain, txgain);
} else if (!strcasecmp(argv[0], "restart")) {
uint32_t chan_id = 0;
ftdm_channel_t *chan;
ftdm_span_t *span = NULL;
if (argc < 3) {
stream->write_function(stream, "-ERR Usage: ftdm restart <span_id> <chan_id>\n");
goto end;
}
ftdm_span_find_by_name(argv[1], &span);
if (!span) {
stream->write_function(stream, "-ERR invalid span\n");
goto end;
}
chan_id = atoi(argv[2]);
chan = ftdm_span_get_channel(span, chan_id);
if (!chan) {
stream->write_function(stream, "-ERR Could not find chan\n");
goto end;
}
stream->write_function(stream, "Resetting channel %s:%s\n", argv[2], argv[3]);
ftdm_channel_reset(chan);
} else {
char *rply = ftdm_api_execute(cmd);

View File

@ -65,6 +65,8 @@ ftdm_time_t time_current_throttle_log = 0;
static ftdm_iterator_t *get_iterator(ftdm_iterator_type_t type, ftdm_iterator_t *iter);
static ftdm_status_t ftdm_call_set_call_id(ftdm_caller_data_t *caller_data);
static ftdm_status_t ftdm_call_clear_call_id(ftdm_caller_data_t *caller_data);
static ftdm_status_t ftdm_channel_clear_vars(ftdm_channel_t *ftdmchan);
static ftdm_status_t ftdm_channel_done(ftdm_channel_t *ftdmchan);
static int time_is_init = 0;
@ -1874,45 +1876,6 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_span(uint32_t span_id, ftdm_direc
return status;
}
static ftdm_status_t ftdm_channel_reset(ftdm_channel_t *ftdmchan)
{
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_OPEN);
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT);
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_SUPRESS_DTMF);
ftdm_channel_done(ftdmchan);
ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_HOLD);
memset(ftdmchan->tokens, 0, sizeof(ftdmchan->tokens));
ftdmchan->token_count = 0;
ftdm_channel_flush_dtmf(ftdmchan);
if (ftdmchan->gen_dtmf_buffer) {
ftdm_buffer_zero(ftdmchan->gen_dtmf_buffer);
}
if (ftdmchan->digit_buffer) {
ftdm_buffer_zero(ftdmchan->digit_buffer);
}
if (!ftdmchan->dtmf_on) {
ftdmchan->dtmf_on = FTDM_DEFAULT_DTMF_ON;
}
if (!ftdmchan->dtmf_off) {
ftdmchan->dtmf_off = FTDM_DEFAULT_DTMF_OFF;
}
memset(ftdmchan->dtmf_hangup_buf, '\0', ftdmchan->span->dtmf_hangup_len);
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE)) {
ftdmchan->effective_codec = ftdmchan->native_codec;
ftdmchan->packet_len = ftdmchan->native_interval * (ftdmchan->effective_codec == FTDM_CODEC_SLIN ? 16 : 8);
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE);
}
return FTDM_SUCCESS;
}
FT_DECLARE(ftdm_status_t) ftdm_channel_init(ftdm_channel_t *ftdmchan)
{
@ -2416,14 +2379,16 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_indicate(const char *file, const ch
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_PROGRESS);
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_MEDIA);
} else {
if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS) {
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_PROGRESS, 1);
}
if (!ftdm_test_flag(ftdmchan->span, FTDM_SPAN_USE_SKIP_STATES)) {
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;
/* 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);
@ -2462,6 +2427,16 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_send_msg(const char *file, const ch
return status;
}
FT_DECLARE(ftdm_status_t) _ftdm_channel_reset(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan)
{
ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "null channel");
ftdm_channel_lock(ftdmchan);
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_RESET, 1);
ftdm_channel_unlock(ftdmchan);
return FTDM_SUCCESS;
}
FT_DECLARE(ftdm_status_t) _ftdm_channel_call_place(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan)
{
ftdm_status_t status = FTDM_FAIL;
@ -2545,12 +2520,13 @@ FT_DECLARE(ftdm_status_t) ftdm_span_get_sig_status(ftdm_span_t *span, ftdm_signa
}
}
static ftdm_status_t ftdm_channel_clear_vars(ftdm_channel_t *ftdmchan);
FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan)
static ftdm_status_t ftdm_channel_done(ftdm_channel_t *ftdmchan)
{
ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "Null channel can't be done!\n");
ftdm_mutex_lock(ftdmchan->mutex);
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_OPEN);
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_DTMF_DETECT);
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_SUPRESS_DTMF);
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_INUSE);
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND);
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_WINK);
@ -2591,17 +2567,47 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan)
sigmsg.event_id = FTDM_SIGEVENT_RELEASED;
ftdm_span_send_signal(ftdmchan->span, &sigmsg);
ftdm_call_clear_call_id(&ftdmchan->caller_data);
}
if (ftdmchan->txdrops || ftdmchan->rxdrops) {
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "channel dropped data: txdrops = %d, rxdrops = %d\n",
ftdmchan->txdrops, ftdmchan->rxdrops);
}
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "channel done\n");
if (ftdmchan->txdrops || ftdmchan->rxdrops) {
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "channel dropped data: txdrops = %d, rxdrops = %d\n",
ftdmchan->txdrops, ftdmchan->rxdrops);
}
memset(&ftdmchan->caller_data, 0, sizeof(ftdmchan->caller_data));
ftdm_mutex_unlock(ftdmchan->mutex);
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_HOLD);
memset(ftdmchan->tokens, 0, sizeof(ftdmchan->tokens));
ftdmchan->token_count = 0;
ftdm_channel_flush_dtmf(ftdmchan);
if (ftdmchan->gen_dtmf_buffer) {
ftdm_buffer_zero(ftdmchan->gen_dtmf_buffer);
}
if (ftdmchan->digit_buffer) {
ftdm_buffer_zero(ftdmchan->digit_buffer);
}
if (!ftdmchan->dtmf_on) {
ftdmchan->dtmf_on = FTDM_DEFAULT_DTMF_ON;
}
if (!ftdmchan->dtmf_off) {
ftdmchan->dtmf_off = FTDM_DEFAULT_DTMF_OFF;
}
memset(ftdmchan->dtmf_hangup_buf, '\0', ftdmchan->span->dtmf_hangup_len);
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE)) {
ftdmchan->effective_codec = ftdmchan->native_codec;
ftdmchan->packet_len = ftdmchan->native_interval * (ftdmchan->effective_codec == FTDM_CODEC_SLIN ? 16 : 8);
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE);
}
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "channel done\n");
ftdm_mutex_unlock(ftdmchan->mutex);
return FTDM_SUCCESS;
}
@ -2631,8 +2637,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_close(ftdm_channel_t **ftdmchan)
if (ftdm_test_flag(check, FTDM_CHANNEL_OPEN)) {
status = check->fio->close(check);
if (status == FTDM_SUCCESS) {
ftdm_clear_flag(check, FTDM_CHANNEL_INUSE);
ftdm_channel_reset(check);
ftdm_channel_done(check);
*ftdmchan = NULL;
}
} else {

View File

@ -156,7 +156,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
release_request_id((m3ua_request_id_t)ftdmchan->extra_id);
ftdmchan->extra_id = 0;
}
ftdm_channel_done(ftdmchan);
ftdm_channel_close(&ftdmchan);
}
break;
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:

View File

@ -1325,7 +1325,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
}
Q931ReleaseCRV(&isdn_data->q931, gen->CRV);
}
ftdm_channel_done(ftdmchan);
ftdm_channel_close(&ftdmchan);
}
break;
case FTDM_CHANNEL_STATE_PROGRESS:

View File

@ -280,12 +280,12 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
switch (ftdmchan->state) {
case FTDM_CHANNEL_STATE_DOWN:
{
ftdm_channel_done(ftdmchan);
{
ftdmchan->call_data = NULL;
ftdm_channel_close(&ftdmchan);
ftdm_channel_done(peerchan);
peerchan->call_data = NULL;
ftdm_channel_close(&peerchan);
}
break;

View File

@ -839,7 +839,7 @@ static void handle_call_released(ftdm_span_t *span, sangomabc_connection_t *mcon
if ((ftdmchan = find_ftdmchan(span, event, 1))) {
ftdm_log(FTDM_LOG_DEBUG, "Releasing completely chan s%dc%d\n", BOOST_EVENT_SPAN(mcon->sigmod, event),
BOOST_EVENT_CHAN(mcon->sigmod, event));
ftdm_channel_done(ftdmchan);
ftdm_channel_close(&ftdmchan);
} else {
ftdm_log(FTDM_LOG_CRIT, "Odd, We could not find chan: s%dc%d to release the call completely!!\n",
BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event));
@ -1105,8 +1105,9 @@ static void handle_call_loop_start(ftdm_span_t *span, sangomabc_connection_t *mc
ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_IN_LOOP, res);
if (res != FTDM_SUCCESS) {
ftdm_channel_t *toclose = ftdmchan;
ftdm_log(FTDM_LOG_CRIT, "yay, could not set the state of the channel to IN_LOOP, loop will fail\n");
ftdm_channel_done(ftdmchan);
ftdm_channel_close(&toclose);
return;
}
ftdm_log(FTDM_LOG_DEBUG, "%d:%d starting loop\n", ftdmchan->span_id, ftdmchan->chan_id);
@ -1426,11 +1427,12 @@ static __inline__ ftdm_status_t state_advance(ftdm_channel_t *ftdmchan)
ftdmchan->sflags = 0;
memset(ftdmchan->call_data, 0, sizeof(sangoma_boost_call_t));
if (sangoma_boost_data->sigmod && call_stopped_ack_sent) {
/* we dont want to call ftdm_channel_done just yet until call released is received */
/* we dont want to call ftdm_channel_close just yet until call released is received */
ftdm_log(FTDM_LOG_DEBUG, "Waiting for call release confirmation before declaring chan %d:%d as available \n",
ftdmchan->span_id, ftdmchan->chan_id);
} else {
ftdm_channel_done(ftdmchan);
ftdm_channel_t *toclose = ftdmchan;
ftdm_channel_close(&toclose);
}
}
break;

View File

@ -65,7 +65,13 @@ ftdm_state_map_t sangoma_isdn_state_map = {
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
{FTDM_ANY_STATE, FTDM_END},
{FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_SUSPENDED, FTDM_END}
{FTDM_CHANNEL_STATE_RESET, FTDM_CHANNEL_STATE_RESTART, FTDM_END}
},
{
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_RESET, FTDM_END},
{FTDM_CHANNEL_STATE_DOWN, FTDM_END}
},
{
ZSD_INBOUND,
@ -170,7 +176,13 @@ ftdm_state_map_t sangoma_isdn_state_map = {
ZSD_OUTBOUND,
ZSM_UNACCEPTABLE,
{FTDM_ANY_STATE, FTDM_END},
{FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_SUSPENDED, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}
{FTDM_CHANNEL_STATE_RESET, FTDM_CHANNEL_STATE_RESTART, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END}
},
{
ZSD_OUTBOUND,
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_RESET, FTDM_END},
{FTDM_CHANNEL_STATE_DOWN, FTDM_END}
},
{
ZSD_OUTBOUND,
@ -203,7 +215,7 @@ ftdm_state_map_t sangoma_isdn_state_map = {
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_DIALING, FTDM_END},
{FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
FTDM_CHANNEL_STATE_PROCEED, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP,
FTDM_CHANNEL_STATE_PROCEED, FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP,
FTDM_CHANNEL_STATE_DOWN, FTDM_END}
},
{
@ -211,14 +223,20 @@ ftdm_state_map_t sangoma_isdn_state_map = {
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_PROCEED, FTDM_END},
{FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP,
FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END},
},
FTDM_CHANNEL_STATE_RINGING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END},
},
{
ZSD_OUTBOUND,
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_PROGRESS, FTDM_END},
{FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END},
},
{
ZSD_OUTBOUND,
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_RINGING, FTDM_END},
{FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END},
},
{
ZSD_OUTBOUND,
ZSM_UNACCEPTABLE,
@ -680,8 +698,17 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
break;
case FTDM_CHANNEL_STATE_RINGING:
{
ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN};
sngisdn_snd_alert(ftdmchan, prog_ind);
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
/* OUTBOUND...so we were told by the line of this so notify the user */
sigev.event_id = FTDM_SIGEVENT_RINGING;
ftdm_span_send_signal(ftdmchan->span, &sigev);
if (sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY)) {
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
}
} else {
ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN};
sngisdn_snd_alert(ftdmchan, prog_ind);
}
}
break;
case FTDM_CHANNEL_STATE_PROGRESS:
@ -692,12 +719,9 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
sigev.event_id = FTDM_SIGEVENT_PROGRESS;
ftdm_span_send_signal(ftdmchan->span, &sigev);
} else {
/* If we already sent a PROCEED before, do not send a PROGRESS as there is nothing to indicate to the remote switch */
if (ftdmchan->last_state != FTDM_CHANNEL_STATE_PROCEED) {
/* Send a progress message, indicating: Call is not end-to-end ISDN, further call progress may be available */
ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN};
sngisdn_snd_progress(ftdmchan, prog_ind);
}
/* Send a progress message, indicating: Call is not end-to-end ISDN, further call progress may be available */
ftdm_sngisdn_progind_t prog_ind = {SNGISDN_PROGIND_LOC_USER, SNGISDN_PROGIND_DESCR_NETE_ISDN};
sngisdn_snd_progress(ftdmchan, prog_ind);
}
}
break;
@ -780,7 +804,7 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
sngisdn_snd_release(ftdmchan, 0);
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) {
sngisdn_set_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN);
sngisdn_set_span_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN);
}
} else {
sngisdn_snd_disconnect(ftdmchan);
@ -838,6 +862,11 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
/* IMPLEMENT ME */
}
break;
case FTDM_CHANNEL_STATE_RESET:
{
sngisdn_snd_restart(ftdmchan);
}
break;
default:
{
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "unsupported sngisdn_rcvd state %s\n", ftdm_channel_state2str(ftdmchan->state));
@ -862,10 +891,6 @@ static FIO_CHANNEL_SEND_MSG_FUNCTION(ftdm_sangoma_isdn_send_msg)
ftdm_status_t status = FTDM_FAIL;
switch (sigmsg->event_id) {
case FTDM_SIGEVENT_RESTART:
/* TODO: Send a channel restart here */
/* Implement me */
break;
case FTDM_SIGEVENT_FACILITY:
sngisdn_snd_fac_req(ftdmchan);
break;
@ -1072,7 +1097,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config)
if (span->trunk_type == FTDM_TRUNK_BRI_PTMP ||
span->trunk_type == FTDM_TRUNK_BRI) {
sngisdn_set_avail_rate(span, SNGISDN_AVAIL_PWR_SAVING);
sngisdn_set_span_avail_rate(span, SNGISDN_AVAIL_PWR_SAVING);
}
/* Initialize scheduling context */
@ -1167,6 +1192,7 @@ static FIO_API_FUNCTION(ftdm_sangoma_isdn_api)
goto done;
}
/* TODO: Move functions to table + function pointers */
if (!strcasecmp(argv[0], "trace")) {
char *trace_opt;
@ -1210,7 +1236,7 @@ static FIO_API_FUNCTION(ftdm_sangoma_isdn_api)
}
sngisdn_print_phy_stats(stream, span);
}
if (!strcasecmp(argv[0], "show_spans")) {
ftdm_span_t *span = NULL;
if (argc == 2) {

View File

@ -101,9 +101,11 @@ typedef enum {
FLAG_GLARE = (1 << 6),
FLAG_DELAYED_REL = (1 << 7),
FLAG_SENT_PROCEED = (1 << 8),
FLAG_SEND_DISC = (1 << 9),
FLAG_SEND_DISC = (1 << 9),
/* Used for BRI only, flag is set after we request line CONNECTED */
FLAG_ACTIVATING = (1 << 10),
FLAG_ACTIVATING = (1 << 10),
/* Used when we receive an ALERT msg + inband tones ready */
FLAG_MEDIA_READY = (1 << 11),
} sngisdn_flag_t;
@ -352,8 +354,11 @@ void clear_call_glare_data(sngisdn_chan_data_t *sngisdn_info);
ftdm_status_t get_ftdmchan_by_suInstId(int16_t cc_id, uint32_t suInstId, sngisdn_chan_data_t **sngisdn_data);
ftdm_status_t get_ftdmchan_by_spInstId(int16_t cc_id, uint32_t spInstId, sngisdn_chan_data_t **sngisdn_data);
ftdm_status_t sngisdn_set_span_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail);
ftdm_status_t sngisdn_set_chan_avail_rate(ftdm_channel_t *chan, sngisdn_avail_t avail);
void sngisdn_set_span_sig_status(ftdm_span_t *ftdmspan, ftdm_signaling_status_t status);
void sngisdn_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status_t status);
ftdm_status_t sngisdn_set_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail);
ftdm_status_t sngisdn_activate_trace(ftdm_span_t *span, sngisdn_tracetype_t trace_opt);
@ -374,6 +379,7 @@ void sngisdn_snd_con_complete(ftdm_channel_t *ftdmchan);
void sngisdn_snd_fac_req(ftdm_channel_t *ftdmchan);
void sngisdn_snd_info_req(ftdm_channel_t *ftdmchan);
void sngisdn_snd_status_enq(ftdm_channel_t *ftdmchan);
void sngisdn_snd_restart(ftdm_channel_t *ftdmchan);
void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len);
void sngisdn_snd_event(ftdm_channel_t *dchan, ftdm_oob_event_t event);
@ -453,6 +459,9 @@ ftdm_status_t set_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb);
ftdm_status_t set_calling_name(ftdm_channel_t *ftdmchan, ConEvnt *conEvnt);
ftdm_status_t set_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad);
ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_sngisdn_progind_t prog_ind);
ftdm_status_t set_bear_cap_ie(ftdm_channel_t *ftdmchan, BearCap *bearCap);
ftdm_status_t set_chan_id_ie(ftdm_channel_t *ftdmchan, ChanId *chanId);
ftdm_status_t set_restart_ind_ie(ftdm_channel_t *ftdmchan, RstInd *rstInd);
ftdm_status_t set_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr);
ftdm_status_t set_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, uint8_t *data_len);
@ -482,7 +491,6 @@ static __inline__ void sngisdn_set_flag(sngisdn_chan_data_t *sngisdn_info, sngis
void handle_sng_log(uint8_t level, char *fmt,...);
void sngisdn_set_span_sig_status(ftdm_span_t *ftdmspan, ftdm_signaling_status_t status);
void sngisdn_delayed_setup(void* p_sngisdn_info);
void sngisdn_delayed_release(void* p_sngisdn_info);
void sngisdn_delayed_connect(void* p_sngisdn_info);

View File

@ -33,7 +33,8 @@
*/
#include "ftmod_sangoma_isdn.h"
ftdm_status_t sngisdn_cause_val_requires_disconnect(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn);
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);
/* Remote side transmit a SETUP */
void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
@ -232,6 +233,9 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event)
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
}
break;
case FTDM_CHANNEL_STATE_RESET:
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
break;
default:
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing SETUP in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
break;
@ -274,6 +278,7 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event)
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
switch(ftdmchan->state) {
case FTDM_CHANNEL_STATE_PROCEED:
case FTDM_CHANNEL_STATE_RINGING:
case FTDM_CHANNEL_STATE_PROGRESS:
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
case FTDM_CHANNEL_STATE_DIALING:
@ -285,6 +290,9 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event)
case FTDM_CHANNEL_STATE_HANGUP:
/* Race condition, we just hung up the call - ignore this message */
break;
case FTDM_CHANNEL_STATE_RESET:
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
break;
default:
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing CONNECT/CONNECT ACK in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
@ -301,6 +309,9 @@ void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event)
case FTDM_CHANNEL_STATE_HANGUP_COMPLETE:
/* Race condition, We just hung up an incoming call right after we sent a CONNECT - ignore this message */
break;
case FTDM_CHANNEL_STATE_RESET:
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
break;
default:
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing CONNECT/CONNECT ACK in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
@ -354,27 +365,47 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
goto sngisdn_process_cnst_ind_end;
}
switch(ftdmchan->state) {
case FTDM_CHANNEL_STATE_DIALING:
case FTDM_CHANNEL_STATE_PROCEED:
if (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL) {
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
} else if (evntType == MI_CALLPROC) {
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROCEED);
} else {
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
}
break;
case FTDM_CHANNEL_STATE_PROGRESS:
case FTDM_CHANNEL_STATE_RINGING:
if (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL) {
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
sngisdn_set_flag(sngisdn_info, FLAG_MEDIA_READY);
}
switch (evntType) {
case MI_CALLPROC:
if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALING) {
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROCEED);
}
break;
case MI_ALERTING:
if (ftdmchan->state == FTDM_CHANNEL_STATE_PROCEED) {
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RINGING);
}
break;
case MI_PROGRESS:
if (sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY)) {
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA);
} else if (ftdmchan->state != FTDM_CHANNEL_STATE_PROGRESS) {
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS);
}
break;
default:
/* We should never reach this section !*/
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Don't know how to handle this event %d\n", evntType);
}
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;
case FTDM_CHANNEL_STATE_RESET:
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
break;
default:
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Processing ALERT/PROCEED/PROGRESS in an invalid state (%s)\n", ftdm_channel_state2str(ftdmchan->state));
@ -414,6 +445,9 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event)
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;
case FTDM_CHANNEL_STATE_RESET:
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
break;
default:
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "\n", suId, suInstId, spInstId);
break;
@ -477,6 +511,9 @@ void sngisdn_process_disc_ind (sngisdn_event_data_t *sngisdn_event)
/* This is a race condition. We just sent a DISCONNECT, on this channel */
/* Do nothing */
break;
case FTDM_CHANNEL_STATE_RESET:
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
break;
default:
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received DISCONNECT in an invalid state (%s)\n",
ftdm_channel_state2str(ftdmchan->state));
@ -531,7 +568,7 @@ void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event)
case FTDM_CHANNEL_STATE_DIALING:
/* Remote side rejected our SETUP message on outbound call */
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) {
sngisdn_set_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN);
sngisdn_set_span_avail_rate(ftdmchan->span, SNGISDN_AVAIL_DOWN);
}
/* fall-through */
case FTDM_CHANNEL_STATE_PROCEED:
@ -581,6 +618,9 @@ void sngisdn_process_rel_ind (sngisdn_event_data_t *sngisdn_event)
/* set abort flag so that we do not transmit another release complete on this channel once FS core is done */
}
break;
case FTDM_CHANNEL_STATE_RESET:
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Processing SETUP but channel in RESET state, ignoring\n");
break;
default:
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received RELEASE in an invalid state (%s)\n",
ftdm_channel_state2str(ftdmchan->state));
@ -1050,18 +1090,91 @@ void sngisdn_process_srv_cfm (sngisdn_event_data_t *sngisdn_event)
return;
}
static void sngisdn_process_restart_confirm(ftdm_channel_t *ftdmchan)
{
switch (ftdmchan->state) {
case FTDM_CHANNEL_STATE_RESET:
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
break;
case FTDM_CHANNEL_STATE_DOWN:
/* Do nothing */
break;
default:
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received RESTART CFM in an invalid state (%s)\n",
ftdm_channel_state2str(ftdmchan->state));
}
return;
}
void sngisdn_process_rst_cfm (sngisdn_event_data_t *sngisdn_event)
{
int16_t suId = sngisdn_event->suId;
int16_t dChan = sngisdn_event->dChan;
uint8_t ces = sngisdn_event->ces;
uint8_t evntType = sngisdn_event->evntType;
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
/* Function does not require any info from ssHlEvnt struct for now */
/*Rst *rstEvnt = &sngisdn_event->event.rstEvnt;*/
uint8_t chan_no = 0;
Rst *rstEvnt = &sngisdn_event->event.rstEvnt;
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);
return;
}
if (!rstEvnt->rstInd.eh.pres || !rstEvnt->rstInd.rstClass.pres) {
ftdm_log(FTDM_LOG_DEBUG, "Receved RESTART, 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 on invalid channel:%d\n", chan_no);
} else {
ftdm_channel_t *ftdmchan = ftdm_span_get_channel(signal_data->ftdm_span, chan_no);
sngisdn_process_restart_confirm(ftdmchan);
}
} 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_process_restart_confirm((ftdm_channel_t*)ftdm_iterator_current(curr));
}
ftdm_iterator_free(chaniter);
}
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;
@ -1090,7 +1203,7 @@ void sngisdn_process_rst_ind (sngisdn_event_data_t *sngisdn_event)
return;
}
ftdm_status_t sngisdn_cause_val_requires_disconnect(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn)
static ftdm_status_t sngisdn_cause_val_requires_disconnect(ftdm_channel_t *ftdmchan, CauseDgn *causeDgn)
{
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;

View File

@ -51,72 +51,6 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan)
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 = 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;
conEvnt.bearCap[0].infoTranRate0.pres = PRSNT_NODEF;
conEvnt.bearCap[0].infoTranRate0.val = IN_ITR_64KBIT;
conEvnt.bearCap[0].tranMode.pres = PRSNT_NODEF;
conEvnt.bearCap[0].tranMode.val = IN_TM_CIRCUIT;
conEvnt.chanId.eh.pres = PRSNT_NODEF;
conEvnt.chanId.prefExc.pres = PRSNT_NODEF;
conEvnt.chanId.prefExc.val = IN_PE_EXCLSVE;
conEvnt.chanId.dChanInd.pres = PRSNT_NODEF;
conEvnt.chanId.dChanInd.val = IN_DSI_NOTDCHAN;
conEvnt.chanId.intIdentPres.pres = PRSNT_NODEF;
conEvnt.chanId.intIdentPres.val = IN_IIP_IMPLICIT;
conEvnt.chanId.intIdent.pres = NOTPRSNT;
if (ftdmchan->span->trunk_type == FTDM_TRUNK_BRI ||
ftdmchan->span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
/* Trillium stack rejests lyr1Ident on BRI, but Netbricks always sends it.
Check with Trillium if this ever causes calls to fail in the field */
/* BRI only params */
conEvnt.chanId.intType.pres = PRSNT_NODEF;
conEvnt.chanId.intType.val = IN_IT_BASIC;
conEvnt.chanId.infoChanSel.pres = PRSNT_NODEF;
conEvnt.chanId.infoChanSel.val = ftdmchan->physical_chan_id;
} else {
/* PRI only params */
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;
conEvnt.chanId.nmbMap.val = IN_NM_CHNNMB;
conEvnt.chanId.codeStand1.pres = PRSNT_NODEF;
conEvnt.chanId.codeStand1.val = IN_CSTD_CCITT;
conEvnt.chanId.chanNmbSlotMap.pres = PRSNT_NODEF;
conEvnt.chanId.chanNmbSlotMap.len = 1;
conEvnt.chanId.chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id;
}
if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN) {
conEvnt.sndCmplt.eh.pres = PRSNT_NODEF;
}
@ -126,6 +60,8 @@ void sngisdn_snd_setup(ftdm_channel_t *ftdmchan)
}
ftdm_log_chan(sngisdn_info->ftdmchan, FTDM_LOG_INFO, "Outgoing call: Called No:[%s] Calling No:[%s]\n", ftdmchan->caller_data.dnis.digits, ftdmchan->caller_data.cid_num.digits);
set_chan_id_ie(ftdmchan, &conEvnt.chanId);
set_bear_cap_ie(ftdmchan, &conEvnt.bearCap[0]);
set_called_num(ftdmchan, &conEvnt.cdPtyNmb);
set_calling_num(ftdmchan, &conEvnt.cgPtyNmb);
set_calling_num2(ftdmchan, &conEvnt.cgPtyNmb2);
@ -161,38 +97,7 @@ void sngisdn_snd_setup_ack(ftdm_channel_t *ftdmchan)
memset(&cnStEvnt, 0, sizeof(cnStEvnt));
cnStEvnt.chanId.eh.pres = PRSNT_NODEF;
cnStEvnt.chanId.prefExc.pres = PRSNT_NODEF;
cnStEvnt.chanId.prefExc.val = IN_PE_EXCLSVE;
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);
@ -221,38 +126,7 @@ void sngisdn_snd_con_complete(ftdm_channel_t *ftdmchan)
memset(&cnStEvnt, 0, sizeof(cnStEvnt));
cnStEvnt.chanId.eh.pres = PRSNT_NODEF;
cnStEvnt.chanId.prefExc.pres = PRSNT_NODEF;
cnStEvnt.chanId.prefExc.val = IN_PE_EXCLSVE;
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;
}
set_chan_id_ie(ftdmchan, &cnStEvnt.chanId);
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);
@ -277,41 +151,11 @@ void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan, ftdm_sngisdn_progind_t prog_i
}
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;
}
set_chan_id_ie(ftdmchan, &cnStEvnt.chanId);
set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind);
set_facility_ie(ftdmchan, &cnStEvnt.facilityStr);
ftdm_call_clear_data(&ftdmchan->caller_data);
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);
@ -397,39 +241,8 @@ void sngisdn_snd_connect(ftdm_channel_t *ftdmchan)
}
memset(&cnStEvnt, 0, sizeof(cnStEvnt));
cnStEvnt.chanId.eh.pres = PRSNT_NODEF;
cnStEvnt.chanId.prefExc.pres = PRSNT_NODEF;
cnStEvnt.chanId.prefExc.val = IN_PE_EXCLSVE;
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;
}
set_chan_id_ie(ftdmchan, &cnStEvnt.chanId);
set_prog_ind_ie(ftdmchan, &cnStEvnt.progInd, prog_ind);
set_facility_ie(ftdmchan, &cnStEvnt.facilityStr);
ftdm_call_clear_data(&ftdmchan->caller_data);
@ -563,6 +376,7 @@ void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan)
}
return;
}
void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare)
{
RelEvnt relEvnt;
@ -618,6 +432,24 @@ void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare)
return;
}
void sngisdn_snd_restart(ftdm_channel_t *ftdmchan)
{
Rst rstEvnt;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
memset(&rstEvnt, 0, sizeof(rstEvnt));
set_chan_id_ie(ftdmchan, &rstEvnt.chanId);
set_restart_ind_ie(ftdmchan, &rstEvnt.rstInd);
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Sending RESTART (suId:%d dchan:%d ces:%d)\n", signal_data->cc_id, signal_data->dchan_id, CES_MNGMNT);
if (sng_isdn_restart_request(signal_data->cc_id, &rstEvnt, signal_data->dchan_id, CES_MNGMNT, IN_SND_RST)) {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "stack refused RESTART request\n");
}
return;
}
/* We received an incoming frame on the d-channel, send data to the stack */
void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len)

View File

@ -630,8 +630,9 @@ void sngisdn_rcv_rst_cfm (int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces
ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
ftdm_log(FTDM_LOG_INFO, "Received RESTART CFM (dChan:%d ces:%u type:%u)\n", dChan, ces, evntType);
/* Enqueue the event to each span within the dChan */
for(i=1; i<=g_sngisdn_data.dchans[dChan].num_spans; i++) {
signal_data = g_sngisdn_data.dchans[dChan].spans[i];
@ -725,14 +726,25 @@ void sngisdn_rcv_q931_ind(InMngmt *status)
ftdmspan = signal_data->ftdm_span;
if (status->t.usta.alarm.event == LCM_EVENT_UP) {
uint32_t chan_no = status->t.usta.evntParm[2];
ftdm_log(FTDM_LOG_INFO, "[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);
sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_UP);
sngisdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_UP);
if (chan_no) {
ftdm_channel_t *ftdmchan = ftdm_span_get_channel(ftdmspan, chan_no);
if (ftdmchan) {
sngisdn_set_chan_sig_status(ftdmchan, FTDM_SIG_STATE_UP);
sngisdn_set_chan_avail_rate(ftdmchan, SNGISDN_AVAIL_UP);
} else {
ftdm_log(FTDM_LOG_CRIT, "stack alarm event on invalid channel :%d\n", chan_no);
}
} else {
sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_UP);
sngisdn_set_span_avail_rate(ftdmspan, SNGISDN_AVAIL_UP);
}
} else {
ftdm_log(FTDM_LOG_WARNING, "[SNGISDN Q931] s%d: %s: %s(%d): %s(%d)\n",
status->t.usta.suId,
@ -741,7 +753,7 @@ void sngisdn_rcv_q931_ind(InMngmt *status)
DECODE_LCM_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause);
sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_DOWN);
sngisdn_set_avail_rate(ftdmspan, SNGISDN_AVAIL_PWR_SAVING);
sngisdn_set_span_avail_rate(ftdmspan, SNGISDN_AVAIL_PWR_SAVING);
}
}
break;

View File

@ -136,19 +136,25 @@ ftdm_status_t get_ftdmchan_by_spInstId(int16_t cc_id, uint32_t spInstId, sngisdn
return FTDM_SUCCESS;
}
ftdm_status_t sngisdn_set_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail)
ftdm_status_t sngisdn_set_chan_avail_rate(ftdm_channel_t *chan, sngisdn_avail_t avail)
{
if (span->trunk_type == FTDM_TRUNK_BRI ||
span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
if (FTDM_SPAN_IS_BRI(chan->span)) {
ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Setting availability rate to:%d\n", avail);
chan->availability_rate = avail;
}
return FTDM_SUCCESS;
}
ftdm_status_t sngisdn_set_span_avail_rate(ftdm_span_t *span, sngisdn_avail_t avail)
{
if (FTDM_SPAN_IS_BRI(span)) {
ftdm_iterator_t *chaniter = NULL;
ftdm_iterator_t *curr = NULL;
chaniter = ftdm_span_get_chan_iterator(span, NULL);
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
ftdm_log_chan(((ftdm_channel_t*)ftdm_iterator_current(curr)), FTDM_LOG_DEBUG, "Setting availability rate to:%d\n", avail);
((ftdm_channel_t*)ftdm_iterator_current(curr))->availability_rate = avail;
sngisdn_set_chan_avail_rate(((ftdm_channel_t*)ftdm_iterator_current(curr)), avail);
}
ftdm_iterator_free(chaniter);
}
@ -676,7 +682,6 @@ ftdm_status_t set_calling_subaddr(ftdm_channel_t *ftdmchan, CgPtySad *cgPtySad)
return FTDM_SUCCESS;
}
ftdm_status_t set_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr)
{
ftdm_status_t status;
@ -789,6 +794,93 @@ ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_s
return FTDM_SUCCESS;
}
ftdm_status_t set_chan_id_ie(ftdm_channel_t *ftdmchan, ChanId *chanId)
{
if (!ftdmchan) {
return FTDM_SUCCESS;
}
chanId->eh.pres = PRSNT_NODEF;
chanId->prefExc.pres = PRSNT_NODEF;
chanId->prefExc.val = IN_PE_EXCLSVE;
chanId->dChanInd.pres = PRSNT_NODEF;
chanId->dChanInd.val = IN_DSI_NOTDCHAN;
chanId->intIdentPres.pres = PRSNT_NODEF;
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 */
chanId->intType.pres = PRSNT_NODEF;
chanId->intType.val = IN_IT_BASIC;
chanId->infoChanSel.pres = PRSNT_NODEF;
chanId->infoChanSel.val = ftdmchan->physical_chan_id;
} else {
chanId->intType.pres = PRSNT_NODEF;
chanId->intType.val = IN_IT_OTHER;
chanId->infoChanSel.pres = PRSNT_NODEF;
chanId->infoChanSel.val = IN_ICS_B1CHAN;
chanId->chanMapType.pres = PRSNT_NODEF;
chanId->chanMapType.val = IN_CMT_BCHAN;
chanId->nmbMap.pres = PRSNT_NODEF;
chanId->nmbMap.val = IN_NM_CHNNMB;
chanId->codeStand1.pres = PRSNT_NODEF;
chanId->codeStand1.val = IN_CSTD_CCITT;
chanId->chanNmbSlotMap.pres = PRSNT_NODEF;
chanId->chanNmbSlotMap.len = 1;
chanId->chanNmbSlotMap.val[0] = ftdmchan->physical_chan_id;
}
return FTDM_SUCCESS;
}
ftdm_status_t set_bear_cap_ie(ftdm_channel_t *ftdmchan, BearCap *bearCap)
{
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
bearCap->eh.pres = PRSNT_NODEF;
bearCap->infoTranCap.pres = PRSNT_NODEF;
bearCap->infoTranCap.val = sngisdn_get_infoTranCap_from_user(ftdmchan->caller_data.bearer_capability);
bearCap->codeStand0.pres = PRSNT_NODEF;
bearCap->codeStand0.val = IN_CSTD_CCITT;
bearCap->infoTranRate0.pres = PRSNT_NODEF;
bearCap->infoTranRate0.val = IN_ITR_64KBIT;
bearCap->tranMode.pres = PRSNT_NODEF;
bearCap->tranMode.val = IN_TM_CIRCUIT;
if (!FTDM_SPAN_IS_BRI(ftdmchan->span)) {
/* Trillium stack rejests lyr1Ident on BRI, but Netbricks always sends it.
Check with Trillium if this ever causes calls to fail in the field */
/* PRI only params */
bearCap->usrInfoLyr1Prot.pres = PRSNT_NODEF;
bearCap->usrInfoLyr1Prot.val = sngisdn_get_usrInfoLyr1Prot_from_user(ftdmchan->caller_data.bearer_layer1);
if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN &&
bearCap->usrInfoLyr1Prot.val == IN_UIL1_G711ULAW) {
/* We are bridging a call from T1 */
bearCap->usrInfoLyr1Prot.val = IN_UIL1_G711ALAW;
} else if (bearCap->usrInfoLyr1Prot.val == IN_UIL1_G711ALAW) {
/* We are bridging a call from E1 */
bearCap->usrInfoLyr1Prot.val = IN_UIL1_G711ULAW;
}
bearCap->lyr1Ident.pres = PRSNT_NODEF;
bearCap->lyr1Ident.val = IN_L1_IDENT;
}
return FTDM_SUCCESS;
}
ftdm_status_t set_restart_ind_ie(ftdm_channel_t *ftdmchan, RstInd *rstInd)
{
rstInd->eh.pres = PRSNT_NODEF;
rstInd->rstClass.pres = PRSNT_NODEF;
rstInd->rstClass.val = IN_CL_INDCHAN;
return FTDM_SUCCESS;
}
void sngisdn_t3_timeout(void* p_sngisdn_info)
{

View File

@ -314,7 +314,8 @@ typedef enum {
FTDM_SIGEVENT_RELEASED, /*!< Channel is completely released and available */
FTDM_SIGEVENT_UP, /*!< Outgoing call has been answered */
FTDM_SIGEVENT_FLASH, /*!< Flash event (typically on-hook/off-hook for analog devices) */
FTDM_SIGEVENT_PROCEED, /*!< Outgoing call got a response */
FTDM_SIGEVENT_PROCEED, /*!< Outgoing call got a response */
FTDM_SIGEVENT_RINGING, /*!< Remote side is in ringing state */
FTDM_SIGEVENT_PROGRESS, /*!< Outgoing call is making progress */
FTDM_SIGEVENT_PROGRESS_MEDIA, /*!< Outgoing call is making progress and there is media available */
FTDM_SIGEVENT_ALARM_TRAP, /*!< Hardware alarm ON */
@ -327,7 +328,7 @@ typedef enum {
FTDM_SIGEVENT_FACILITY, /* !< In call facility event */
FTDM_SIGEVENT_INVALID
} ftdm_signal_event_t;
#define SIGNAL_STRINGS "START", "STOP", "RELEASED", "UP", "FLASH", "PROCEED", "PROGRESS", \
#define SIGNAL_STRINGS "START", "STOP", "RELEASED", "UP", "FLASH", "PROCEED", "RINGING", "PROGRESS", \
"PROGRESS_MEDIA", "ALARM_TRAP", "ALARM_CLEAR", \
"COLLECTED_DIGIT", "ADD_CALL", "RESTART", "SIGSTATUS_CHANGED", "COLLISION", "MSG", "INVALID"
@ -702,6 +703,14 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_hangup(const char *file, const char
/*! \brief Hangup the call with cause recording the source code point where it was called (see ftdm_channel_call_hangup_with_cause for an easy to use macro) */
FT_DECLARE(ftdm_status_t) _ftdm_channel_call_hangup_with_cause(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan, ftdm_call_cause_t);
/*! \brief Reset the channel */
#define ftdm_channel_reset(ftdmchan) _ftdm_channel_reset(__FILE__, __FUNCTION__, __LINE__, (ftdmchan))
/*! \brief Reset the channel (see _ftdm_channel_reset for an easy to use macro)
* \note if there was a call on this channel, call will be cleared without any notifications to the user
*/
FT_DECLARE(ftdm_status_t) _ftdm_channel_reset(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan);
/*! \brief Put a call on hold (if supported by the signaling stack) */
#define ftdm_channel_call_hold(ftdmchan) _ftdm_channel_call_hold(__FILE__, __FUNCTION__, __LINE__, (ftdmchan))
@ -741,6 +750,7 @@ FT_DECLARE(ftdm_status_t) ftdm_span_set_sig_status(ftdm_span_t *span, ftdm_signa
/*! \brief Get span signaling status (ie: whether protocol layer is up or down) */
FT_DECLARE(ftdm_status_t) ftdm_span_get_sig_status(ftdm_span_t *span, ftdm_signaling_status_t *status);
/*!
* \brief Set user private data in the channel
*

View File

@ -599,7 +599,6 @@ FT_DECLARE(void) ftdm_channel_rotate_tokens(ftdm_channel_t *ftdmchan);
FT_DECLARE(int) ftdm_load_module(const char *name);
FT_DECLARE(int) ftdm_load_module_assume(const char *name);
FT_DECLARE(int) ftdm_vasprintf(char **ret, const char *fmt, va_list ap);
FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan);
FT_DECLARE(ftdm_status_t) ftdm_span_close_all(void);
FT_DECLARE(ftdm_status_t) ftdm_channel_open_chan(ftdm_channel_t *ftdmchan);

View File

@ -228,12 +228,13 @@ typedef enum {
FTDM_CHANNEL_STATE_HANGUP,
FTDM_CHANNEL_STATE_HANGUP_COMPLETE,
FTDM_CHANNEL_STATE_IN_LOOP,
FTDM_CHANNEL_STATE_RESET,
FTDM_CHANNEL_STATE_INVALID
} ftdm_channel_state_t;
#define CHANNEL_STATE_STRINGS "DOWN", "HOLD", "SUSPENDED", "DIALTONE", "COLLECT", \
"RING", "RINGING", "BUSY", "ATTN", "GENRING", "DIALING", "GET_CALLERID", "CALLWAITING", \
"RESTART", "PROCEED", "PROGRESS", "PROGRESS_MEDIA", "UP", "IDLE", "TERMINATING", "CANCEL", \
"HANGUP", "HANGUP_COMPLETE", "IN_LOOP", "INVALID"
"HANGUP", "HANGUP_COMPLETE", "IN_LOOP", "RESET", "INVALID"
FTDM_STR2ENUM_P(ftdm_str2ftdm_channel_state, ftdm_channel_state2str, ftdm_channel_state_t)
typedef enum {