void sngisdn_set_chan_sig_status(ftdm_channel_t *ftdmchan, ftdm_signaling_status_t status) { ftdm_sigmsg_t sig; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)ftdmchan->span->signal_data; ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Signalling link status changed to %s\n", ftdm_signaling_status2str(status)); memset(&sig, 0, sizeof(sig)); sig.chan_id = ftdmchan->chan_id; sig.span_id = ftdmchan->span_id; sig.channel = ftdmchan; sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; sig.ev_data.sigstatus.status = status; ftdm_span_send_signal(ftdmchan->span, &sig); if (FTDM_SPAN_IS_BRI(ftdmchan->span)) { sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data; if (ftdm_test_flag(sngisdn_info, FLAG_ACTIVATING)) { ftdm_clear_flag(sngisdn_info, FLAG_ACTIVATING); ftdm_sched_timer(signal_data->sched, "delayed_setup", 1000, sngisdn_delayed_setup, (void*) sngisdn_info, NULL); } } return; }
ftdm_status_t sngisdn_set_chan_avail_rate(ftdm_channel_t *chan, sngisdn_avail_t avail) { 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; }
void sngisdn_rcv_q921_ind(BdMngmt *status) { ftdm_span_t *ftdmspan; sngisdn_span_data_t *signal_data = g_sngisdn_data.dchans[status->t.usta.lnkNmb].spans[1]; if (!signal_data) { ftdm_log(FTDM_LOG_INFO, "Received q921 status on unconfigured span (lnkNmb:%d)\n", status->t.usta.lnkNmb); return; } ftdmspan = signal_data->ftdm_span; if (!ftdmspan) { ftdm_log(FTDM_LOG_INFO, "Received q921 status on unconfigured span (lnkNmb:%d)\n", status->t.usta.lnkNmb); return; } switch (status->t.usta.alarm.category) { case (LCM_CATEGORY_PROTOCOL): ftdm_log(FTDM_LOG_DEBUG, "[SNGISDN Q921] %s: %s: %s(%d): %s(%d)\n", ftdmspan->name, DECODE_LCM_CATEGORY(status->t.usta.alarm.category), DECODE_LLD_EVENT(status->t.usta.alarm.event), status->t.usta.alarm.event, DECODE_LLD_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause); if (FTDM_SPAN_IS_BRI(ftdmspan) && (status->t.usta.alarm.event == PROT_ST_DN)) { /* Q.921 link is down - This is a line where the Q.921 stops transmitting after the line goes idle. Do not drop current calls, but set sigstatus do down so that we can try to re-initialize link before trying new outbound calls */ sngisdn_set_span_sig_status(ftdmspan, FTDM_SIG_STATE_DOWN); sngisdn_set_span_avail_rate(ftdmspan, SNGISDN_AVAIL_PWR_SAVING); } break; default: ftdm_log(FTDM_LOG_INFO, "[SNGISDN Q921] %s: %s: %s(%d): %s(%d)\n", ftdmspan->name, DECODE_LCM_CATEGORY(status->t.usta.alarm.category), DECODE_LLD_EVENT(status->t.usta.alarm.event), status->t.usta.alarm.event, DECODE_LLD_CAUSE(status->t.usta.alarm.cause), status->t.usta.alarm.cause); switch (status->t.usta.alarm.event) { case ENTR_CONG: /* Entering Congestion */ ftdm_log(FTDM_LOG_WARNING, "s%d: Entering Congestion\n", ftdmspan->span_id); ftdm_set_flag(ftdmspan, FTDM_SPAN_SUSPENDED); break; case EXIT_CONG: /* Exiting Congestion */ ftdm_log(FTDM_LOG_WARNING, "s%d: Exiting Congestion\n", ftdmspan->span_id); ftdm_clear_flag(ftdmspan, FTDM_SPAN_SUSPENDED); break; } break; } return; }
ftdm_status_t get_callref(ftdm_channel_t *ftdmchan, BCCallRef* callRef) { sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data; if (signal_data->raw_trace_q931) { if (callRef->eh.pres != PRSNT_NODEF || callRef->reference.pres != PRSNT_NODEF) { /* Netborder only supports BRI, so we only care for BRI for now */ if (FTDM_SPAN_IS_BRI(ftdmchan->span) && !sngisdn_info->call_ref) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Failed to obtain call reference\n"); } return FTDM_FAIL; } if (FTDM_SPAN_IS_BRI(ftdmchan->span)) { sngisdn_info->call_ref = 0x7F & callRef->reference.val; } else { sngisdn_info->call_ref = 0x7FFF & callRef->reference.val; } ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Call reference:%04x\n", sngisdn_info->call_ref); } 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); sngisdn_set_chan_avail_rate(((ftdm_channel_t*)ftdm_iterator_current(curr)), avail); } ftdm_iterator_free(chaniter); } return FTDM_SUCCESS; }