freetdm: Changes for FTDM IO commands

This commit is contained in:
David Yat Sin 2010-11-15 14:13:01 -05:00
parent d0b6117325
commit caacb24500
7 changed files with 329 additions and 193 deletions

View File

@ -56,6 +56,9 @@
#define FTDM_READ_TRACE_INDEX 0 #define FTDM_READ_TRACE_INDEX 0
#define FTDM_WRITE_TRACE_INDEX 1 #define FTDM_WRITE_TRACE_INDEX 1
ftdm_time_t time_last_throttle_log = 0;
ftdm_time_t time_current_throttle_log = 0;
static int time_is_init = 0; static int time_is_init = 0;
static void time_init(void) static void time_init(void)

View File

@ -242,10 +242,10 @@ static __inline__ void ftdm_sangoma_isdn_advance_chan_states(ftdm_channel_t *ftd
static void ftdm_sangoma_isdn_process_phy_events(ftdm_span_t *span, ftdm_oob_event_t event) static void ftdm_sangoma_isdn_process_phy_events(ftdm_span_t *span, ftdm_oob_event_t event)
{ {
sngisdn_snd_event(span, event);
switch (event) { switch (event) {
/* Check if the span woke up from power-saving mode */ /* Check if the span woke up from power-saving mode */
case FTDM_OOB_ALARM_CLEAR: case FTDM_OOB_ALARM_CLEAR:
sngisdn_snd_event(span, SNG_L1EVENT_ALARM_OFF);
if (FTDM_SPAN_IS_BRI(span)) { if (FTDM_SPAN_IS_BRI(span)) {
ftdm_channel_t *ftdmchan; ftdm_channel_t *ftdmchan;
sngisdn_chan_data_t *sngisdn_info; sngisdn_chan_data_t *sngisdn_info;
@ -267,9 +267,6 @@ static void ftdm_sangoma_isdn_process_phy_events(ftdm_span_t *span, ftdm_oob_eve
ftdm_iterator_free(chaniter); ftdm_iterator_free(chaniter);
} }
break; break;
case FTDM_OOB_ALARM_TRAP:
sngisdn_snd_event(span, SNG_L1EVENT_ALARM_ON);
break;
default: default:
/* Ignore other events for now */ /* Ignore other events for now */
break; break;
@ -327,7 +324,7 @@ static void *ftdm_sangoma_isdn_dchan_run(ftdm_thread_t *me, void *obj)
len = 1000; len = 1000;
status = ftdm_channel_read(dchan, data, &len); status = ftdm_channel_read(dchan, data, &len);
if (status == FTDM_SUCCESS) { if (status == FTDM_SUCCESS) {
sngisdn_snd_data(span, data, len); sngisdn_snd_data(dchan, data, len);
} else { } else {
ftdm_log_chan_msg(dchan, FTDM_LOG_WARNING, "Failed to read from channel \n"); ftdm_log_chan_msg(dchan, FTDM_LOG_WARNING, "Failed to read from channel \n");
} }
@ -1019,7 +1016,8 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_isdn_init)
g_sngisdn_event_interface.sta.sng_q931_trc_ind = sngisdn_rcv_q931_trace; g_sngisdn_event_interface.sta.sng_q931_trc_ind = sngisdn_rcv_q931_trace;
g_sngisdn_event_interface.sta.sng_cc_sta_ind = sngisdn_rcv_cc_ind; g_sngisdn_event_interface.sta.sng_cc_sta_ind = sngisdn_rcv_cc_ind;
g_sngisdn_event_interface.io.sng_data_req = sngisdn_rcv_data_req; g_sngisdn_event_interface.io.sng_l1_data_req = sngisdn_rcv_l1_data_req;
g_sngisdn_event_interface.io.sng_l1_cmd_req = sngisdn_rcv_l1_cmd_req;
for(i=1;i<=MAX_VARIANTS;i++) { for(i=1;i<=MAX_VARIANTS;i++) {
ftdm_mutex_create(&g_sngisdn_data.ccs[i].mutex); ftdm_mutex_create(&g_sngisdn_data.ccs[i].mutex);

View File

@ -293,8 +293,8 @@ void sngisdn_snd_reset(ftdm_channel_t *ftdmchan);
void sngisdn_snd_con_complete(ftdm_channel_t *ftdmchan); void sngisdn_snd_con_complete(ftdm_channel_t *ftdmchan);
void sngisdn_snd_info_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_status_enq(ftdm_channel_t *ftdmchan);
void sngisdn_snd_data(ftdm_span_t *span, uint8_t *data, ftdm_size_t len); void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len);
void sngisdn_snd_event(ftdm_span_t *span, sng_isdn_l1_event_t l1_event); void sngisdn_snd_event(ftdm_channel_t *span, sng_isdn_l1_event_t l1_event);
/* Inbound Call Control functions */ /* Inbound Call Control functions */
void sngisdn_rcv_con_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, ConEvnt *conEvnt, int16_t dChan, uint8_t ces); void sngisdn_rcv_con_ind(int16_t suId, uint32_t suInstId, uint32_t spInstId, ConEvnt *conEvnt, int16_t dChan, uint8_t ces);
@ -314,7 +314,9 @@ void sngisdn_rcv_srv_ind(int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces)
void sngisdn_rcv_srv_cfm(int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces); void sngisdn_rcv_srv_cfm(int16_t suId, Srv *srvEvnt, int16_t dChan, uint8_t ces);
void sngisdn_rcv_rst_cfm(int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces, uint8_t evntType); void sngisdn_rcv_rst_cfm(int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces, uint8_t evntType);
void sngisdn_rcv_rst_ind(int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces, uint8_t evntType); void sngisdn_rcv_rst_ind(int16_t suId, Rst *rstEvnt, int16_t dChan, uint8_t ces, uint8_t evntType);
int16_t sngisdn_rcv_data_req(uint16_t spId, uint8_t *buff, uint32_t length); int16_t sngisdn_rcv_l1_data_req(uint16_t spId, sng_isdn_l1_frame_t *l1_frame);
int16_t sngisdn_rcv_l1_cmd_req(uint16_t spId, sng_l1_cmd_t *l1_cmd);
void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event); void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event);
void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event); void sngisdn_process_con_cfm (sngisdn_event_data_t *sngisdn_event);

View File

@ -181,7 +181,7 @@ ftdm_status_t sngisdn_stack_cfg_phy_gen(void)
cfg.t.cfg.s.l1Gen.sm.srcEnt = ENTL1; cfg.t.cfg.s.l1Gen.sm.srcEnt = ENTL1;
cfg.t.cfg.s.l1Gen.sm.dstEnt = ENTSM; cfg.t.cfg.s.l1Gen.sm.dstEnt = ENTSM;
cfg.t.cfg.s.l1Gen.nmbLnks = MAX_L1_LINKS+1; cfg.t.cfg.s.l1Gen.nmbLnks = MAX_L1_LINKS;
cfg.t.cfg.s.l1Gen.poolTrUpper = POOL_UP_TR; /* upper pool threshold */ cfg.t.cfg.s.l1Gen.poolTrUpper = POOL_UP_TR; /* upper pool threshold */
cfg.t.cfg.s.l1Gen.poolTrLower = POOL_LW_TR; /* lower pool threshold */ cfg.t.cfg.s.l1Gen.poolTrLower = POOL_LW_TR; /* lower pool threshold */
@ -897,7 +897,6 @@ ftdm_status_t sngisdn_stack_cfg_q931_lce(ftdm_span_t *span)
cfg.t.cfg.s.inLCe.tRstAck.enb = TRUE; cfg.t.cfg.s.inLCe.tRstAck.enb = TRUE;
cfg.t.cfg.s.inLCe.tRstAck.val = 10; cfg.t.cfg.s.inLCe.tRstAck.val = 10;
cfg.t.cfg.s.inLCe.usid = 0; cfg.t.cfg.s.inLCe.usid = 0;
cfg.t.cfg.s.inLCe.tid = 0; cfg.t.cfg.s.inLCe.tid = 0;

View File

@ -595,16 +595,65 @@ void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare)
return; return;
} }
void sngisdn_snd_data(ftdm_span_t *span, uint8_t *data, ftdm_size_t len) /* 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)
{ {
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data; l1_frame_t l1_frame;
sng_isdn_data_ind(signal_data->link_id, data, len); sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) dchan->span->signal_data;
memset(&l1_frame, 0, sizeof(l1_frame));
l1_frame.len = len;
memcpy(&l1_frame.data, data, len);
if (ftdm_test_flag(&(dchan->iostats.s.rx), FTDM_IOSTATS_ERROR_CRC)) {
l1_frame.flags |= SNG_L1FRAME_ERROR_CRC;
}
if (ftdm_test_flag(&(dchan->iostats.s.rx), FTDM_IOSTATS_ERROR_FRAME)) {
l1_frame.flags |= SNG_L1FRAME_ERROR_FRAME;
}
if (ftdm_test_flag(&(dchan->iostats.s.rx), FTDM_IOSTATS_ERROR_ABORT)) {
l1_frame.flags |= SNG_L1FRAME_ERROR_ABORT;
}
if (ftdm_test_flag(&(dchan->iostats.s.rx), FTDM_IOSTATS_ERROR_FIFO)) {
l1_frame.flags |= SNG_L1FRAME_ERROR_FIFO;
}
if (ftdm_test_flag(&(dchan->iostats.s.rx), FTDM_IOSTATS_ERROR_DMA)) {
l1_frame.flags |= SNG_L1FRAME_ERROR_DMA;
}
if (ftdm_test_flag(&(dchan->iostats.s.rx), FTDM_IOSTATS_QUEUE_THRES)) {
/* Should we trigger congestion here? */
l1_frame.flags |= SNG_L1FRAME_QUEUE_THRES;
}
if (ftdm_test_flag(&(dchan->iostats.s.rx), FTDM_IOSTATS_QUEUE_FULL)) {
/* Should we trigger congestion here? */
l1_frame.flags |= SNG_L1FRAME_QUEUE_FULL;
}
sng_isdn_data_ind(signal_data->link_id, &l1_frame);
} }
void sngisdn_snd_event(ftdm_span_t *span, sng_isdn_l1_event_t l1_event) void sngisdn_snd_event(ftdm_channel_t *dchan, ftdm_oob_event_t event)
{ {
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) dchan->span->signal_data;
sng_isdn_event_ind(signal_data->link_id, l1_event); switch(event) {
case FTDM_OOB_ALARM_CLEAR:
sng_isdn_event_ind(signal_data->link_id, SNG_L1EVENT_ALARM_OFF);
break;
case FTDM_OOB_ALARM_TRAP:
sng_isdn_event_ind(signal_data->link_id, SNG_L1EVENT_ALARM_ON);
break;
default:
/* We do not care about the other OOB events for now */
return;
}
return;
} }

View File

@ -759,6 +759,49 @@ static FIO_COMMAND_FUNCTION(wanpipe_command)
return FTDM_SUCCESS; return FTDM_SUCCESS;
} }
static void wanpipe_read_stats(ftdmchan, wp_tdm_api_rx_hdr_t *rx_stats)
{
ftdmchan->iostats.s.rx.error_flags = 0;
if (rx_stats->rx_hdr_errors) {
wanpipe_reset_stats(ftdmchan);
ftdm_log_chan_msg_throttle(ftdmchan, "IO errors\n");
}
ftdmchan->iostats.s.rx_queue_size = rx_stats->rx_h.rx_h.max_rx_queue_length;
ftdmchan->iostats.s.rx_queue_len = rx_stats->rx_h.current_number_of_frames_in_rx_queue;
if (rx_stats->rx_h.wp_api_rx_hdr_error_map & (1<<WP_ABORT_ERROR_BIT)) {
ftdm_set_flag(&(ftdmchan->iostats.s.rx), FTDM_IOSTATS_ERROR_ABORT);
}
if (rx_stats->rx_h.wp_api_rx_hdr_error_map & (1<<WP_DMA_ERROR_BIT)) {
ftdm_set_flag(&(ftdmchan->iostats.s.rx), FTDM_IOSTATS_ERROR_DMA);
}
if (rx_stats->rx_h.wp_api_rx_hdr_error_map & (1<<WP_FIFO_ERROR_BIT)) {
ftdm_set_flag(&(ftdmchan->iostats.s.rx), FTDM_IOSTATS_ERROR_FIFO);
}
if (rx_stats->rx_h.wp_api_rx_hdr_error_map & (1<<WP_CRC_ERROR_BIT)) {
ftdm_set_flag(&(ftdmchan->iostats.s.rx), FTDM_IOSTATS_ERROR_CRC);
}
if (rx_stats->rx_h.wp_api_rx_hdr_error_map & (1<<WP_FRAME_ERROR_BIT)) {
ftdm_set_flag(&(ftdmchan->iostats.s.rx), FTDM_IOSTATS_ERROR_FRAME);
}
if (ftdmchan->iostats.s.rx_queue_len >= (0.8*ftdmchan->iostats.s.rx_queue_size)) {
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Rx Queue length exceeded threshold (%d/%d)\n",
ftdmchan->iostats.s.rx_queue_len, ftdmchan->iostats.s.rx_queue_size);
ftdm_set_flag(&(ftdmchan->iostats.s.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES);
}
if (ftdmchan->iostats.s.rx_queue_len >= ftdmchan->iostats.s.rx_queue_size) {
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Rx Queue Full (%d/%d)\n",
ftdmchan->iostats.s.rx_queue_len, ftdmchan->iostats.s.rx_queue_size);
ftdm_set_flag(&(ftdmchan->iostats.s.rx), FTDM_IOSTATS_ERROR_QUEUE_FULL);
}
return;
}
/** /**
* \brief Reads data from a Wanpipe channel * \brief Reads data from a Wanpipe channel
* \param ftdmchan Channel to read from * \param ftdmchan Channel to read from
@ -789,7 +832,9 @@ static FIO_READ_FUNCTION(wanpipe_read)
return FTDM_FAIL; return FTDM_FAIL;
} }
if (ftdm_channel_test_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS)) {
wanpipe_read_stats(ftdmchan, &hdrframe);
}
return FTDM_SUCCESS; return FTDM_SUCCESS;
} }

View File

@ -357,6 +357,7 @@ typedef struct {
} ftdm_dtmf_debug_t; } ftdm_dtmf_debug_t;
#endif #endif
typedef struct { typedef struct {
const char *file; const char *file;
const char *func; const char *func;
@ -366,6 +367,33 @@ typedef struct {
ftdm_time_t time; ftdm_time_t time;
} ftdm_channel_history_entry_t; } ftdm_channel_history_entry_t;
typedef enum {
FTDM_IOSTATS_ERROR_CRC = (1<<0),
FTDM_IOSTATS_ERROR_FRAME = (1<<1),
FTDM_IOSTATS_ERROR_ABORT = (1<<2),
FTDM_IOSTATS_ERROR_FIFO = (1<<3),
FTDM_IOSTATS_ERROR_DMA = (1<<4),
FTDM_IOSTATS_ERROR_QUEUE_THRES = (1<<5), /* Queue reached high threshold */
FTDM_IOSTATS_ERROR_QUEUE_FULL = (1<<6), /* Queue is full */
} ftdm_iostats_error_type_t;
typedef struct {
union {
struct {
uint32_t errors;
uint16_t flags;
uint8_t rx_queue_size; /* max queue size configured */
uint8_t rx_queue_len; /* Current number of elements in queue */
} rx;
struct {
uint32_t errors;
uint16_t flags;
uint8_t tx_queue_size; /* max queue size configured */
uint8_t tx_queue_len; /* Current number of elements in queue */
} tx;
} s;
} ftdm_channel_iostats_t;
/* 2^8 table size, one for each byte (sample) value */ /* 2^8 table size, one for each byte (sample) value */
#define FTDM_GAINS_TABLE_SIZE 256 #define FTDM_GAINS_TABLE_SIZE 256
struct ftdm_channel { struct ftdm_channel {
@ -438,6 +466,7 @@ struct ftdm_channel {
int availability_rate; int availability_rate;
void *user_private; void *user_private;
ftdm_timer_id_t hangup_timer; ftdm_timer_id_t hangup_timer;
ftdm_channel_iostats_t iostats;
#ifdef FTDM_DEBUG_DTMF #ifdef FTDM_DEBUG_DTMF
ftdm_dtmf_debug_t dtmfdbg; ftdm_dtmf_debug_t dtmfdbg;
#endif #endif
@ -632,10 +661,21 @@ FT_DECLARE(void) ftdm_channel_clear_detected_tones(ftdm_channel_t *ftdmchan);
#define ftdm_channel_lock(chan) ftdm_mutex_lock(chan->mutex) #define ftdm_channel_lock(chan) ftdm_mutex_lock(chan->mutex)
#define ftdm_channel_unlock(chan) ftdm_mutex_unlock(chan->mutex) #define ftdm_channel_unlock(chan) ftdm_mutex_unlock(chan->mutex)
#define ftdm_log_throttle(level, ...) \
time_current_throttle_log = ftdm_current_time_in_ms(); \
if (time_current_throttle_log - time_last_throttle_log > FTDM_THROTTLE_LOG_INTERVAL) {\
ftdm_log(level, __VA_ARGS__); \
time_last_throttle_log = time_current_throttle_log; \
}
#define ftdm_log_chan_ex(fchan, file, func, line, level, format, ...) ftdm_log(file, func, line, level, "[s%dc%d][%d:%d] " format, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, __VA_ARGS__) #define ftdm_log_chan_ex(fchan, file, func, line, level, format, ...) ftdm_log(file, func, line, level, "[s%dc%d][%d:%d] " format, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, __VA_ARGS__)
#define ftdm_log_chan(fchan, level, format, ...) ftdm_log(level, "[s%dc%d][%d:%d] " format, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, __VA_ARGS__) #define ftdm_log_chan(fchan, level, format, ...) ftdm_log(level, "[s%dc%d][%d:%d] " format, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, __VA_ARGS__)
#define ftdm_log_chan_msg(fchan, level, msg) ftdm_log(level, "[s%dc%d][%d:%d] " msg, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id) #define ftdm_log_chan_msg(fchan, level, msg) ftdm_log(level, "[s%dc%d][%d:%d] " msg, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id)
#define ftdm_log_chan_throttle(fchan, level, format, ...) ftdm_log_throttle(level, "[s%dc%d][%d:%d] " format, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, __VA_ARGS__)
#define ftdm_log_chan_msg_throttle(fchan, level, format, ...) ftdm_log_throttle(level, "[s%dc%d][%d:%d] " format, fchan->span_id, fchan->chan_id, fchan->physical_span_id, fchan->physical_chan_id, __VA_ARGS__)
#define ftdm_span_lock(span) ftdm_mutex_lock(span->mutex) #define ftdm_span_lock(span) ftdm_mutex_lock(span->mutex)
#define ftdm_span_unlock(span) ftdm_mutex_unlock(span->mutex) #define ftdm_span_unlock(span) ftdm_mutex_unlock(span->mutex)