}
}
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);
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;
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)
{
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");
+#ifdef __WINDOWS__
+ UNREFERENCED_PARAMETER(file);
+ UNREFERENCED_PARAMETER(func);
+ UNREFERENCED_PARAMETER(line);
+#endif
+
+ ftdm_channel_lock(ftdmchan);
+ ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_RESET, 0);
+ 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;
}
}
-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);
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",
+ 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");
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_mutex_unlock(ftdmchan->mutex);
return FTDM_SUCCESS;
}
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 {
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:
}
Q931ReleaseCRV(&isdn_data->q931, gen->CRV);
}
- ftdm_channel_done(ftdmchan);
+ ftdm_channel_close(ftdmchan);
}
break;
case FTDM_CHANNEL_STATE_PROGRESS:
switch (ftdmchan->state) {
case FTDM_CHANNEL_STATE_DOWN:
{
- ftdm_channel_done(ftdmchan);
+ ftdm_channel_close(ftdmchan);
ftdmchan->call_data = NULL;
- ftdm_channel_done(peerchan);
+ ftdm_channel_close(peerchan);
peerchan->call_data = NULL;
}
break;
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));
ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_IN_LOOP, res);
if (res != FTDM_SUCCESS) {
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(ftdmchan);
return;
}
ftdm_log(FTDM_LOG_DEBUG, "%d:%d starting loop\n", ftdmchan->span_id, ftdmchan->chan_id);
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_close(ftdmchan);
}
}
break;
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,
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,
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);
/* 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));
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;
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 */
goto done;
}
+ /* TODO: Move functions to table + function pointers */
if (!strcasecmp(argv[0], "trace")) {
char *trace_opt;
}
sngisdn_print_phy_stats(stream, span);
}
-
+
if (!strcasecmp(argv[0], "show_spans")) {
ftdm_span_t *span = NULL;
if (argc == 2) {
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);
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);
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);
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);
*/
#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)
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;
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));
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));
/* 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));
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;
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:
/* 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:
+ /* User initiated reset, so they do not know about this call */
+ break;
default:
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Received RELEASE in an invalid state (%s)\n",
ftdm_channel_state2str(ftdmchan->state));
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;
+ 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_CRIT, "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;
+ }
- ISDN_FUNC_TRACE_ENTER(__FUNCTION__);
+ 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);
+ }
- /* Function does not require any info from ssHlEvnt struct for now */
- /*Rst *rstEvnt = &sngisdn_event->event.rstEvnt;*/
-
ftdm_log(FTDM_LOG_DEBUG, "Processing RESTART CFM (suId:%u dChan:%d ces:%d type:%d)\n", suId, dChan, ces, evntType);
ISDN_FUNC_TRACE_EXIT(__FUNCTION__);
return;
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;
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;
}
}
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);
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);
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);
}
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);
}
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);
}
return;
}
+
void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare)
{
RelEvnt relEvnt;
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)
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];
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,
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;
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);
}
return FTDM_SUCCESS;
}
-
ftdm_status_t set_facility_ie(ftdm_channel_t *ftdmchan, FacilityStr *facilityStr)
{
ftdm_status_t status;
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)
{
/*! \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))
/*! \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
*
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);
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 {