提交 a0b164c1 authored 作者: David Yat Sin's avatar David Yat Sin

freetdm: ISDN - Fix for not waking up the line on power-saving lines

上级 adc26e63
...@@ -1751,7 +1751,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_chan(ftdm_channel_t *ftdmchan) ...@@ -1751,7 +1751,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_chan(ftdm_channel_t *ftdmchan)
goto done; 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"); 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"); ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Cannot open channel when is alarmed\n");
goto done; goto done;
...@@ -3927,6 +3927,11 @@ static ftdm_status_t ftdm_set_channels_alarms(ftdm_span_t *span, int currindex) ...@@ -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); 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; 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; return FTDM_SUCCESS;
} }
......
...@@ -53,7 +53,6 @@ ...@@ -53,7 +53,6 @@
//#define IODEBUG //#define IODEBUG
/* helper macros */ /* 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) #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); ...@@ -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); 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_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_state_change(ftdm_channel_t *ftdmchan);
static void ftdm_sangoma_isdn_process_stack_event (ftdm_span_t *span, sngisdn_event_data_t *sngisdn_event); 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 ...@@ -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) static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj)
{ {
ftdm_interrupt_t *ftdm_sangoma_isdn_int[2]; ftdm_interrupt_t *ftdm_sangoma_isdn_int[2];
...@@ -300,21 +345,8 @@ static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj) ...@@ -300,21 +345,8 @@ static void *ftdm_sangoma_isdn_run(ftdm_thread_t *me, void *obj)
} }
/* Poll for events, e.g HW DTMF */ /* Poll for events, e.g HW DTMF */
ret_status = ftdm_span_poll_event(span, 0, NULL); ftdm_sangoma_isdn_poll_events(span);
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);
}
if (ftdm_sched_get_time_to_next_timer(signal_data->sched, &sleep) == FTDM_SUCCESS) { if (ftdm_sched_get_time_to_next_timer(signal_data->sched, &sleep) == FTDM_SUCCESS) {
if (sleep < 0 || sleep > SNGISDN_EVENT_POLL_RATE) { if (sleep < 0 || sleep > SNGISDN_EVENT_POLL_RATE) {
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) ...@@ -498,8 +530,20 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
} }
break; break;
case FTDM_CHANNEL_STATE_DIALING: /* outgoing call request */ 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; break;
case FTDM_CHANNEL_STATE_PROGRESS: case FTDM_CHANNEL_STATE_PROGRESS:
...@@ -856,8 +900,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config) ...@@ -856,8 +900,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_isdn_span_config)
if (span->trunk_type == FTDM_TRUNK_BRI_PTMP || if (span->trunk_type == FTDM_TRUNK_BRI_PTMP ||
span->trunk_type == FTDM_TRUNK_BRI) { 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); sng_isdn_set_avail_rate(span, SNGISDN_AVAIL_PWR_SAVING);
} }
...@@ -914,7 +957,7 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_isdn_init) ...@@ -914,7 +957,7 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_isdn_init)
/* initalize sng_isdn library */ /* 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; return FTDM_SUCCESS;
} }
......
...@@ -74,6 +74,7 @@ typedef enum { ...@@ -74,6 +74,7 @@ typedef enum {
FLAG_DELAYED_REL = (1 << 7), FLAG_DELAYED_REL = (1 << 7),
FLAG_SENT_PROCEED = (1 << 8), FLAG_SENT_PROCEED = (1 << 8),
FLAG_SEND_DISC = (1 << 9), FLAG_SEND_DISC = (1 << 9),
FLAG_ACTIVATING = (1 << 10), /* Used for BRI only, flag is set after we request line CONNECTED */
} sngisdn_flag_t; } sngisdn_flag_t;
...@@ -181,6 +182,7 @@ typedef struct sngisdn_span_data { ...@@ -181,6 +182,7 @@ typedef struct sngisdn_span_data {
uint8_t facility; uint8_t facility;
int8_t facility_timeout; int8_t facility_timeout;
uint8_t num_local_numbers; uint8_t num_local_numbers;
uint8_t timer_t3;
char* local_numbers[SNGISDN_NUM_LOCAL_NUMBERS]; char* local_numbers[SNGISDN_NUM_LOCAL_NUMBERS];
ftdm_sched_t *sched; ftdm_sched_t *sched;
ftdm_queue_t *event_queue; ftdm_queue_t *event_queue;
...@@ -368,11 +370,13 @@ void sngisdn_delayed_release(void* p_sngisdn_info); ...@@ -368,11 +370,13 @@ void sngisdn_delayed_release(void* p_sngisdn_info);
void sngisdn_delayed_connect(void* p_sngisdn_info); void sngisdn_delayed_connect(void* p_sngisdn_info);
void sngisdn_delayed_disconnect(void* p_sngisdn_info); void sngisdn_delayed_disconnect(void* p_sngisdn_info);
void sngisdn_facility_timeout(void* p_sngisdn_info); void sngisdn_facility_timeout(void* p_sngisdn_info);
void sngisdn_t3_timeout(void* p_sngisdn_info);
/* Stack management functions */ /* Stack management functions */
ftdm_status_t sng_isdn_stack_cfg(ftdm_span_t *span); 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_start(ftdm_span_t *span);
ftdm_status_t sng_isdn_stack_stop(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_phy_stats(ftdm_stream_handle_t *stream, ftdm_span_t *span);
void sngisdn_print_spans(ftdm_stream_handle_t *stream); 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) ...@@ -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)); 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; 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 */ /* can be > 1 for some BRI variants */
break; break;
default: default:
...@@ -179,6 +181,7 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_ ...@@ -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->min_digits = 8;
signal_data->overlap_dial = SNGISDN_OPT_DEFAULT; signal_data->overlap_dial = SNGISDN_OPT_DEFAULT;
signal_data->setup_arb = SNGISDN_OPT_DEFAULT; signal_data->setup_arb = SNGISDN_OPT_DEFAULT;
signal_data->timer_t3 = 8;
signal_data->link_id = span->span_id; signal_data->link_id = span->span_id;
span->default_caller_data.bearer_capability = IN_ITC_SPEECH; 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_ ...@@ -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 || if (span->trunk_type == FTDM_TRUNK_BRI ||
span->trunk_type == FTDM_TRUNK_BRI_PTMP) { span->trunk_type == FTDM_TRUNK_BRI_PTMP) {
ftdm_span_set_npi("unknown", &span->default_caller_data.dnis.plan); 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_ton("unknown", &span->default_caller_data.dnis.type);
ftdm_span_set_npi("unknown", &span->default_caller_data.cid_num.plan); 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) ...@@ -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) 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 ...@@ -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_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); 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) 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 ...@@ -382,6 +382,28 @@ ftdm_status_t cpy_calling_name_from_user(ConEvnt *conEvnt, ftdm_channel_t *ftdmc
return FTDM_SUCCESS; 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) void sngisdn_delayed_release(void* p_sngisdn_info)
{ {
sngisdn_chan_data_t *sngisdn_info = (sngisdn_chan_data_t*)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) ...@@ -1011,13 +1011,15 @@ static FIO_GET_ALARMS_FUNCTION(wanpipe_get_alarms)
} }
alarms = tdm_api.wp_tdm_cmd.fe_alarms; alarms = tdm_api.wp_tdm_cmd.fe_alarms;
#endif #endif
#if 1 #ifdef WIN32
/* DAVIDY - Temporary fix: in the current trunk of libsangoma, for BRI, /* 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 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 */ not been ported to Windows-libsangoma yet */
if (alarms) { if (FTDM_SPAN_IS_BRI(ftdmchan->span)) {
ftdmchan->alarm_flags |= FTDM_ALARM_RED; if (alarms) {
alarms = 0; ftdmchan->alarm_flags |= FTDM_ALARM_RED;
alarms = 0;
}
} }
#endif #endif
...@@ -1027,6 +1029,7 @@ static FIO_GET_ALARMS_FUNCTION(wanpipe_get_alarms) ...@@ -1027,6 +1029,7 @@ static FIO_GET_ALARMS_FUNCTION(wanpipe_get_alarms)
ftdmchan->alarm_flags |= FTDM_ALARM_RED; ftdmchan->alarm_flags |= FTDM_ALARM_RED;
alarms &= ~WAN_TE_BIT_ALARM_RED; alarms &= ~WAN_TE_BIT_ALARM_RED;
} }
if (alarms & WAN_TE_BIT_ALARM_AIS) { if (alarms & WAN_TE_BIT_ALARM_AIS) {
ftdmchan->alarm_flags |= FTDM_ALARM_BLUE; ftdmchan->alarm_flags |= FTDM_ALARM_BLUE;
......
...@@ -222,6 +222,8 @@ extern "C" { ...@@ -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_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 \brief Copy flags from one arbitrary object to another
\command dest the object to copy the flags to \command dest the object to copy the flags to
......
...@@ -176,10 +176,11 @@ typedef enum { ...@@ -176,10 +176,11 @@ typedef enum {
FTDM_SPAN_USE_CHAN_QUEUE = (1 << 6), FTDM_SPAN_USE_CHAN_QUEUE = (1 << 6),
FTDM_SPAN_SUGGEST_CHAN_ID = (1 << 7), FTDM_SPAN_SUGGEST_CHAN_ID = (1 << 7),
FTDM_SPAN_USE_AV_RATE = (1 << 8), 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 /* 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 * after having called ftdm_send_span_signal(), which with this flag it will just enqueue the signal
* for later delivery */ * for later delivery */
FTDM_SPAN_USE_SIGNALS_QUEUE = (1 << 9), FTDM_SPAN_USE_SIGNALS_QUEUE = (1 << 10),
} ftdm_span_flag_t; } ftdm_span_flag_t;
/*! \brief Channel supported features */ /*! \brief Channel supported features */
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论