freetdm: ISDN - Fix for not waking up the line on power-saving lines
This commit is contained in:
parent
adc26e6316
commit
a0b164c132
|
@ -1751,7 +1751,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_chan(ftdm_channel_t *ftdmchan)
|
|||
goto done;
|
||||
}
|
||||
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_IN_ALARM)) {
|
||||
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_IN_ALARM) && !ftdm_test_flag(ftdmchan->span, FTDM_SPAN_PWR_SAVING)) {
|
||||
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", "Channel is alarmed\n");
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Cannot open channel when is alarmed\n");
|
||||
goto done;
|
||||
|
@ -3927,6 +3927,11 @@ static ftdm_status_t ftdm_set_channels_alarms(ftdm_span_t *span, int currindex)
|
|||
ftdm_log(FTDM_LOG_ERROR, "%d:%d: Failed to get alarms\n", span->channels[chan_index]->physical_span_id, span->channels[chan_index]->physical_chan_id);
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
if (span->channels[chan_index]->alarm_flags) {
|
||||
ftdm_set_flag_locked(span->channels[chan_index], FTDM_CHANNEL_IN_ALARM);
|
||||
} else {
|
||||
ftdm_clear_flag_locked(span->channels[chan_index], FTDM_CHANNEL_IN_ALARM);
|
||||
}
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -53,7 +53,6 @@
|
|||
//#define IODEBUG
|
||||
|
||||
/* helper macros */
|
||||
#define FTDM_SPAN_IS_BRI(x) ((x)->trunk_type == FTDM_TRUNK_BRI || (x)->trunk_type == FTDM_TRUNK_BRI_PTMP)
|
||||
#define FTDM_SPAN_IS_NT(x) (((ftdm_isdn_data_t *)(x)->signal_data)->mode == Q921_NT)
|
||||
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ static ftdm_status_t ftdm_sangoma_isdn_start(ftdm_span_t *span);
|
|||
|
||||
ftdm_channel_t* ftdm_sangoma_isdn_process_event_states(ftdm_span_t *span, sngisdn_event_data_t *sngisdn_event);
|
||||
static void ftdm_sangoma_isdn_advance_chan_states(ftdm_channel_t *ftdmchan);
|
||||
static void ftdm_sangoma_isdn_poll_events(ftdm_span_t *span);
|
||||
|
||||
static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan);
|
||||
static void ftdm_sangoma_isdn_process_stack_event (ftdm_span_t *span, sngisdn_event_data_t *sngisdn_event);
|
||||
|
@ -238,6 +239,50 @@ static __inline__ void ftdm_sangoma_isdn_advance_chan_states(ftdm_channel_t *ftd
|
|||
}
|
||||
}
|
||||
|
||||
static void ftdm_sangoma_isdn_poll_events(ftdm_span_t *span)
|
||||
{
|
||||
ftdm_status_t ret_status;
|
||||
ftdm_channel_t *ftdmchan;
|
||||
ftdm_iterator_t *chaniter = NULL;
|
||||
ftdm_iterator_t *curr = NULL;
|
||||
|
||||
ret_status = ftdm_span_poll_event(span, 0, NULL);
|
||||
switch(ret_status) {
|
||||
case FTDM_SUCCESS:
|
||||
{
|
||||
ftdm_event_t *event;
|
||||
while (ftdm_span_next_event(span, &event) == FTDM_SUCCESS) {
|
||||
|
||||
if (FTDM_SPAN_IS_BRI(span)) {
|
||||
switch (event->enum_id) {
|
||||
/* Check if the span woke up from power-saving mode */
|
||||
case FTDM_OOB_ALARM_CLEAR:
|
||||
{
|
||||
chaniter = ftdm_span_get_chan_iterator(span, NULL);
|
||||
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
|
||||
ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr);
|
||||
sngisdn_chan_data_t *sngisdn_info = ftdmchan->call_data;
|
||||
|
||||
if (ftdm_test_flag(sngisdn_info, FLAG_ACTIVATING)) {
|
||||
ftdm_clear_flag(sngisdn_info, FLAG_ACTIVATING);
|
||||
sngisdn_snd_setup((ftdm_channel_t*)ftdmchan);
|
||||
}
|
||||
}
|
||||
ftdm_iterator_free(chaniter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FTDM_TIMEOUT:
|
||||
/* No events pending */
|
||||
break;
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_WARNING, "%s:Failed to poll span event\n", span->name);
|
||||
}
|
||||
}
|
||||
|
||||
static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj)
|
||||
{
|
||||
ftdm_interrupt_t *ftdm_sangoma_isdn_int[2];
|
||||
|
@ -300,21 +345,8 @@ static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj)
|
|||
}
|
||||
|
||||
/* Poll for events, e.g HW DTMF */
|
||||
ret_status = ftdm_span_poll_event(span, 0, NULL);
|
||||
switch(ret_status) {
|
||||
case FTDM_SUCCESS:
|
||||
{
|
||||
ftdm_event_t *event;
|
||||
while (ftdm_span_next_event(span, &event) == FTDM_SUCCESS);
|
||||
}
|
||||
break;
|
||||
case FTDM_TIMEOUT:
|
||||
/* No events pending */
|
||||
break;
|
||||
default:
|
||||
ftdm_log(FTDM_LOG_WARNING, "%s:Failed to poll span event\n", span->name);
|
||||
}
|
||||
|
||||
ftdm_sangoma_isdn_poll_events(span);
|
||||
|
||||
if (ftdm_sched_get_time_to_next_timer(signal_data->sched, &sleep) == FTDM_SUCCESS) {
|
||||
if (sleep < 0 || sleep > SNGISDN_EVENT_POLL_RATE) {
|
||||
sleep = SNGISDN_EVENT_POLL_RATE;
|
||||
|
@ -498,8 +530,20 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
|
|||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_DIALING: /* outgoing call request */
|
||||
{
|
||||
sngisdn_snd_setup(ftdmchan);
|
||||
{
|
||||
if (FTDM_SPAN_IS_BRI(ftdmchan->span) &&
|
||||
ftdm_test_flag(ftdmchan, FTDM_CHANNEL_IN_ALARM) &&
|
||||
ftdm_test_flag(ftdmchan->span, FTDM_SPAN_PWR_SAVING)) {
|
||||
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Requesting Line activation\n");
|
||||
sngisdn_set_flag(sngisdn_info, FLAG_ACTIVATING);
|
||||
sng_isdn_wake_up_phy(ftdmchan->span);
|
||||
ftdm_sched_timer(signal_data->sched, "timer_t3", signal_data->timer_t3*1000, sngisdn_t3_timeout, (void*) sngisdn_info, NULL);
|
||||
} else {
|
||||
sngisdn_snd_setup(ftdmchan);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FTDM_CHANNEL_STATE_PROGRESS:
|
||||
|
@ -856,8 +900,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) {
|
||||
|
||||
ftdm_set_flag(span, FTDM_SPAN_USE_AV_RATE);
|
||||
|
||||
sng_isdn_set_avail_rate(span, SNGISDN_AVAIL_PWR_SAVING);
|
||||
}
|
||||
|
||||
|
@ -914,7 +957,7 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_isdn_init)
|
|||
|
||||
/* initalize sng_isdn library */
|
||||
|
||||
ftdm_assert_return(!sng_isdn_init(&g_sngisdn_event_interface), FTDM_FAIL, "Failed to initialize stack\n");
|
||||
ftdm_assert_return(!sng_isdn_init(&g_sngisdn_event_interface), FTDM_FAIL, "Failed to initialize stack\n");
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -74,6 +74,7 @@ typedef enum {
|
|||
FLAG_DELAYED_REL = (1 << 7),
|
||||
FLAG_SENT_PROCEED = (1 << 8),
|
||||
FLAG_SEND_DISC = (1 << 9),
|
||||
FLAG_ACTIVATING = (1 << 10), /* Used for BRI only, flag is set after we request line CONNECTED */
|
||||
} sngisdn_flag_t;
|
||||
|
||||
|
||||
|
@ -181,6 +182,7 @@ typedef struct sngisdn_span_data {
|
|||
uint8_t facility;
|
||||
int8_t facility_timeout;
|
||||
uint8_t num_local_numbers;
|
||||
uint8_t timer_t3;
|
||||
char* local_numbers[SNGISDN_NUM_LOCAL_NUMBERS];
|
||||
ftdm_sched_t *sched;
|
||||
ftdm_queue_t *event_queue;
|
||||
|
@ -368,11 +370,13 @@ void sngisdn_delayed_release(void* p_sngisdn_info);
|
|||
void sngisdn_delayed_connect(void* p_sngisdn_info);
|
||||
void sngisdn_delayed_disconnect(void* p_sngisdn_info);
|
||||
void sngisdn_facility_timeout(void* p_sngisdn_info);
|
||||
void sngisdn_t3_timeout(void* p_sngisdn_info);
|
||||
|
||||
/* Stack management functions */
|
||||
ftdm_status_t sng_isdn_stack_cfg(ftdm_span_t *span);
|
||||
ftdm_status_t sng_isdn_stack_start(ftdm_span_t *span);
|
||||
ftdm_status_t sng_isdn_stack_stop(ftdm_span_t *span);
|
||||
ftdm_status_t sng_isdn_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);
|
||||
|
|
|
@ -98,6 +98,8 @@ ftdm_status_t parse_switchtype(const char* switch_name, ftdm_span_t *span)
|
|||
ftdm_log(FTDM_LOG_ERROR, "%s:Unsupported switchtype %s for trunktype:%s\n", span->name, switch_name, ftdm_trunk_type2str(span->trunk_type));
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
ftdm_set_flag(span, FTDM_SPAN_USE_AV_RATE);
|
||||
ftdm_set_flag(span, FTDM_SPAN_PWR_SAVING);
|
||||
/* can be > 1 for some BRI variants */
|
||||
break;
|
||||
default:
|
||||
|
@ -179,6 +181,7 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_
|
|||
signal_data->min_digits = 8;
|
||||
signal_data->overlap_dial = SNGISDN_OPT_DEFAULT;
|
||||
signal_data->setup_arb = SNGISDN_OPT_DEFAULT;
|
||||
signal_data->timer_t3 = 8;
|
||||
|
||||
signal_data->link_id = span->span_id;
|
||||
span->default_caller_data.bearer_capability = IN_ITC_SPEECH;
|
||||
|
@ -189,6 +192,7 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_
|
|||
if (span->trunk_type == FTDM_TRUNK_BRI ||
|
||||
span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
|
||||
|
||||
|
||||
ftdm_span_set_npi("unknown", &span->default_caller_data.dnis.plan);
|
||||
ftdm_span_set_ton("unknown", &span->default_caller_data.dnis.type);
|
||||
ftdm_span_set_npi("unknown", &span->default_caller_data.cid_num.plan);
|
||||
|
|
|
@ -113,6 +113,40 @@ ftdm_status_t sng_isdn_stack_stop(ftdm_span_t *span)
|
|||
}
|
||||
|
||||
|
||||
ftdm_status_t sng_isdn_wake_up_phy(ftdm_span_t *span)
|
||||
{
|
||||
L1Mngmt cntrl;
|
||||
Pst pst;
|
||||
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*)span->signal_data;
|
||||
|
||||
/* initalize the post structure */
|
||||
stack_pst_init(&pst);
|
||||
|
||||
/* insert the destination Entity */
|
||||
pst.dstEnt = ENTL1;
|
||||
|
||||
/* initalize the control structure */
|
||||
memset(&cntrl, 0, sizeof(cntrl));
|
||||
|
||||
/* initalize the control header */
|
||||
stack_hdr_init(&cntrl.hdr);
|
||||
|
||||
cntrl.hdr.msgType = TCNTRL; /* configuration */
|
||||
cntrl.hdr.entId.ent = ENTL1; /* entity */
|
||||
cntrl.hdr.entId.inst = S_INST; /* instance */
|
||||
cntrl.hdr.elmId.elmnt = STTSAP; /* SAP Specific cntrl */
|
||||
|
||||
cntrl.t.cntrl.action = AENA;
|
||||
cntrl.t.cntrl.subAction = SAELMNT;
|
||||
cntrl.t.cntrl.sapId = signal_data->link_id;
|
||||
|
||||
if (sng_isdn_phy_cntrl(&pst, &cntrl)) {
|
||||
return FTDM_FAIL;
|
||||
}
|
||||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
ftdm_status_t sng_isdn_activate_phy(ftdm_span_t *span)
|
||||
{
|
||||
|
||||
|
|
|
@ -38,13 +38,6 @@ extern ftdm_status_t cpy_calling_num_from_user(CgPtyNmb *cgPtyNmb, ftdm_caller_d
|
|||
extern ftdm_status_t cpy_called_num_from_user(CdPtyNmb *cdPtyNmb, ftdm_caller_data_t *ftdm);
|
||||
extern ftdm_status_t cpy_calling_name_from_user(ConEvnt *conEvnt, ftdm_channel_t *ftdmchan);
|
||||
|
||||
void sngisdn_snd_setup(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_proceed(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_progress(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_connect(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_disconnect(ftdm_channel_t *ftdmchan);
|
||||
void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare);
|
||||
|
||||
|
||||
void sngisdn_snd_setup(ftdm_channel_t *ftdmchan)
|
||||
{
|
||||
|
|
|
@ -382,6 +382,28 @@ ftdm_status_t cpy_calling_name_from_user(ConEvnt *conEvnt, ftdm_channel_t *ftdmc
|
|||
return FTDM_SUCCESS;
|
||||
}
|
||||
|
||||
void sngisdn_t3_timeout(void* p_sngisdn_info)
|
||||
{
|
||||
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info;
|
||||
ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan;
|
||||
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data;
|
||||
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Timer T3 expired (suId:%d suInstId:%u spInstId:%u)\n",
|
||||
signal_data->cc_id, sngisdn_info->glare.spInstId, sngisdn_info->glare.suInstId);
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
if (ftdm_test_flag(sngisdn_info, FLAG_ACTIVATING)){
|
||||
/* PHY layer timed-out, need to clear the call */
|
||||
ftdm_log_chan(ftdmchan, FTDM_LOG_INFO, "Failed to Wake-Up line (suId:%d suInstId:%u spInstId:%u)\n",
|
||||
signal_data->cc_id, sngisdn_info->glare.spInstId, sngisdn_info->glare.suInstId);
|
||||
|
||||
ftdmchan->caller_data.hangup_cause = FTDM_CAUSE_NO_ROUTE_DESTINATION;
|
||||
ftdm_clear_flag(sngisdn_info, FLAG_ACTIVATING);
|
||||
ftdm_set_flag(sngisdn_info, FLAG_LOCAL_ABORT);
|
||||
ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING);
|
||||
}
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
}
|
||||
|
||||
void sngisdn_delayed_release(void* p_sngisdn_info)
|
||||
{
|
||||
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)p_sngisdn_info;
|
||||
|
|
|
@ -1011,13 +1011,15 @@ static FIO_GET_ALARMS_FUNCTION(wanpipe_get_alarms)
|
|||
}
|
||||
alarms = tdm_api.wp_tdm_cmd.fe_alarms;
|
||||
#endif
|
||||
#if 1
|
||||
/* DAVIDY - Temporary fix: in the current trunk of libsangoma, for BRI,
|
||||
#ifdef WIN32
|
||||
/* Temporary fix: in the current trunk of libsangoma, for BRI,
|
||||
WAN_TE_BIT_ALARM_RED bit is set if the card is in disconnected state, but this has
|
||||
not been ported to Windows-libsangoma yet */
|
||||
if (alarms) {
|
||||
ftdmchan->alarm_flags |= FTDM_ALARM_RED;
|
||||
alarms = 0;
|
||||
if (FTDM_SPAN_IS_BRI(ftdmchan->span)) {
|
||||
if (alarms) {
|
||||
ftdmchan->alarm_flags |= FTDM_ALARM_RED;
|
||||
alarms = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1027,6 +1029,7 @@ static FIO_GET_ALARMS_FUNCTION(wanpipe_get_alarms)
|
|||
ftdmchan->alarm_flags |= FTDM_ALARM_RED;
|
||||
alarms &= ~WAN_TE_BIT_ALARM_RED;
|
||||
}
|
||||
|
||||
|
||||
if (alarms & WAN_TE_BIT_ALARM_AIS) {
|
||||
ftdmchan->alarm_flags |= FTDM_ALARM_BLUE;
|
||||
|
|
|
@ -222,6 +222,8 @@ extern "C" {
|
|||
|
||||
#define ftdm_is_dtmf(key) ((key > 47 && key < 58) || (key > 64 && key < 69) || (key > 96 && key < 101) || key == 35 || key == 42 || key == 87 || key == 119)
|
||||
|
||||
#define FTDM_SPAN_IS_BRI(x) ((x)->trunk_type == FTDM_TRUNK_BRI || (x)->trunk_type == FTDM_TRUNK_BRI_PTMP)
|
||||
|
||||
/*!
|
||||
\brief Copy flags from one arbitrary object to another
|
||||
\command dest the object to copy the flags to
|
||||
|
|
|
@ -176,10 +176,11 @@ typedef enum {
|
|||
FTDM_SPAN_USE_CHAN_QUEUE = (1 << 6),
|
||||
FTDM_SPAN_SUGGEST_CHAN_ID = (1 << 7),
|
||||
FTDM_SPAN_USE_AV_RATE = (1 << 8),
|
||||
FTDM_SPAN_PWR_SAVING = (1 << 9),
|
||||
/* If you use this flag, you MUST call ftdm_span_trigger_signals to deliver the user signals
|
||||
* after having called ftdm_send_span_signal(), which with this flag it will just enqueue the signal
|
||||
* for later delivery */
|
||||
FTDM_SPAN_USE_SIGNALS_QUEUE = (1 << 9),
|
||||
FTDM_SPAN_USE_SIGNALS_QUEUE = (1 << 10),
|
||||
} ftdm_span_flag_t;
|
||||
|
||||
/*! \brief Channel supported features */
|
||||
|
|
Loading…
Reference in New Issue