freetdm:Changes for shared IO

This commit is contained in:
David Yat Sin 2010-11-15 19:16:09 -05:00
parent caacb24500
commit a2add13963
8 changed files with 153 additions and 53 deletions

View File

@ -51,6 +51,8 @@ static void ftdm_sangoma_isdn_poll_events(ftdm_span_t *span);
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);
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);
static void ftdm_sangoma_isdn_wakeup_phy(ftdm_channel_t *dchan);
static void ftdm_sangoma_isdn_dchan_set_queue_size(ftdm_channel_t *ftdmchan);
static ftdm_io_interface_t g_sngisdn_io_interface; static ftdm_io_interface_t g_sngisdn_io_interface;
static sng_isdn_event_interface_t g_sngisdn_event_interface; static sng_isdn_event_interface_t g_sngisdn_event_interface;
@ -241,8 +243,9 @@ 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_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data;
sngisdn_snd_event(span, event); sngisdn_snd_event(signal_data->dchan, 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:
@ -251,8 +254,7 @@ static void ftdm_sangoma_isdn_process_phy_events(ftdm_span_t *span, ftdm_oob_eve
sngisdn_chan_data_t *sngisdn_info; sngisdn_chan_data_t *sngisdn_info;
ftdm_iterator_t *chaniter = NULL; ftdm_iterator_t *chaniter = NULL;
ftdm_iterator_t *curr = NULL; ftdm_iterator_t *curr = NULL;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data;
chaniter = ftdm_span_get_chan_iterator(span, NULL); chaniter = ftdm_span_get_chan_iterator(span, NULL);
for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) { for (curr = chaniter; curr; curr = ftdm_iterator_next(curr)) {
ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr); ftdmchan = (ftdm_channel_t*)ftdm_iterator_current(curr);
@ -261,7 +263,7 @@ static void ftdm_sangoma_isdn_process_phy_events(ftdm_span_t *span, ftdm_oob_eve
if (ftdm_test_flag(sngisdn_info, FLAG_ACTIVATING)) { if (ftdm_test_flag(sngisdn_info, FLAG_ACTIVATING)) {
ftdm_clear_flag(sngisdn_info, FLAG_ACTIVATING); ftdm_clear_flag(sngisdn_info, FLAG_ACTIVATING);
ftdm_sched_timer(signal_data->sched, "delayed_setup", 1, sngisdn_delayed_setup, (void*) ftdmchan->call_data, NULL); ftdm_sched_timer(signal_data->sched, "delayed_setup", 1000, sngisdn_delayed_setup, (void*) ftdmchan->call_data, NULL);
} }
} }
ftdm_iterator_free(chaniter); ftdm_iterator_free(chaniter);
@ -276,9 +278,7 @@ static void ftdm_sangoma_isdn_process_phy_events(ftdm_span_t *span, ftdm_oob_eve
static void ftdm_sangoma_isdn_poll_events(ftdm_span_t *span) static void ftdm_sangoma_isdn_poll_events(ftdm_span_t *span)
{ {
ftdm_status_t ret_status; ftdm_status_t ret_status;
ftdm_iterator_t *chaniter = NULL;
ftdm_iterator_t *curr = NULL;
ret_status = ftdm_span_poll_event(span, 0, NULL); ret_status = ftdm_span_poll_event(span, 0, NULL);
switch(ret_status) { switch(ret_status) {
case FTDM_SUCCESS: case FTDM_SUCCESS:
@ -297,6 +297,33 @@ static void ftdm_sangoma_isdn_poll_events(ftdm_span_t *span)
} }
} }
static void ftdm_sangoma_isdn_dchan_set_queue_size(ftdm_channel_t *dchan)
{
ftdm_status_t ret_status;
uint32_t queue_size;
queue_size = SNGISDN_DCHAN_QUEUE_LEN;
ret_status = ftdm_channel_command(dchan, FTDM_COMMAND_SET_RX_QUEUE_SIZE, &queue_size);
ftdm_assert(ret_status == FTDM_SUCCESS, "Failed to set Rx Queue size");
queue_size = SNGISDN_DCHAN_QUEUE_LEN;
ret_status = ftdm_channel_command(dchan, FTDM_COMMAND_SET_TX_QUEUE_SIZE, &queue_size);
ftdm_assert(ret_status == FTDM_SUCCESS, "Failed to set Tx Queue size");
RETVOID;
}
static void ftdm_sangoma_isdn_wakeup_phy(ftdm_channel_t *dchan)
{
ftdm_status_t ret_status;
ftdm_channel_hw_link_status_t status = FTDM_HW_LINK_CONNECTED;
ret_status = ftdm_channel_command(dchan, FTDM_COMMAND_SET_LINK_STATUS, &status);
if (ret_status != FTDM_SUCCESS) {
ftdm_log_chan_msg(dchan, FTDM_LOG_WARNING, "Failed to wake-up link\n");
}
return;
}
static void *ftdm_sangoma_isdn_dchan_run(ftdm_thread_t *me, void *obj) static void *ftdm_sangoma_isdn_dchan_run(ftdm_thread_t *me, void *obj)
{ {
uint8_t data[1000]; uint8_t data[1000];
@ -306,7 +333,9 @@ static void *ftdm_sangoma_isdn_dchan_run(ftdm_thread_t *me, void *obj)
ftdm_channel_t *dchan = ((sngisdn_span_data_t*)span->signal_data)->dchan; ftdm_channel_t *dchan = ((sngisdn_span_data_t*)span->signal_data)->dchan;
ftdm_size_t len = 0; ftdm_size_t len = 0;
ftdm_channel_set_feature(dchan, FTDM_CHANNEL_FEATURE_IO_STATS);
ftdm_sangoma_isdn_dchan_set_queue_size(dchan);
ftdm_assert(dchan, "Span does not have a dchannel"); ftdm_assert(dchan, "Span does not have a dchannel");
ftdm_channel_open_chan(dchan); ftdm_channel_open_chan(dchan);
@ -597,8 +626,8 @@ static void ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdmchan)
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; 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"); ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Requesting Line activation\n");
sngisdn_set_flag(sngisdn_info, FLAG_ACTIVATING); sngisdn_set_flag(sngisdn_info, FLAG_ACTIVATING);
sngisdn_wake_up_phy(ftdmchan->span); ftdm_sangoma_isdn_wakeup_phy(ftdmchan);
ftdm_sched_timer(signal_data->sched, "timer_t3", signal_data->timer_t3*1000, sngisdn_t3_timeout, (void*) sngisdn_info, NULL); ftdm_sched_timer(signal_data->sched, "timer_t3", signal_data->timer_t3*1000, sngisdn_t3_timeout, (void*) sngisdn_info, NULL);
} else { } else {
sngisdn_snd_setup(ftdmchan); sngisdn_snd_setup(ftdmchan);

View File

@ -60,6 +60,7 @@
#define SNGISDN_EVENT_QUEUE_SIZE 100 #define SNGISDN_EVENT_QUEUE_SIZE 100
#define SNGISDN_EVENT_POLL_RATE 100 #define SNGISDN_EVENT_POLL_RATE 100
#define SNGISDN_NUM_LOCAL_NUMBERS 8 #define SNGISDN_NUM_LOCAL_NUMBERS 8
#define SNGISDN_DCHAN_QUEUE_LEN 200
/* TODO: rename all *_cc_* to *_an_* */ /* TODO: rename all *_cc_* to *_an_* */
@ -294,7 +295,7 @@ 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_channel_t *dchan, 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_channel_t *span, sng_isdn_l1_event_t l1_event); void sngisdn_snd_event(ftdm_channel_t *dchan, ftdm_oob_event_t 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 +315,7 @@ 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_l1_data_req(uint16_t spId, sng_isdn_l1_frame_t *l1_frame); int16_t sngisdn_rcv_l1_data_req(uint16_t spId, sng_l1_frame_t *l1_frame);
int16_t sngisdn_rcv_l1_cmd_req(uint16_t spId, sng_l1_cmd_t *l1_cmd); int16_t sngisdn_rcv_l1_cmd_req(uint16_t spId, sng_l1_cmd_t *l1_cmd);

View File

@ -598,7 +598,7 @@ void sngisdn_snd_release(ftdm_channel_t *ftdmchan, uint8_t glare)
/* We received an incoming frame on the d-channel, send data to the stack */ /* 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) void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len)
{ {
l1_frame_t l1_frame; sng_l1_frame_t l1_frame;
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) dchan->span->signal_data; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) dchan->span->signal_data;
memset(&l1_frame, 0, sizeof(l1_frame)); memset(&l1_frame, 0, sizeof(l1_frame));
@ -606,32 +606,32 @@ void sngisdn_snd_data(ftdm_channel_t *dchan, uint8_t *data, ftdm_size_t len)
memcpy(&l1_frame.data, data, len); memcpy(&l1_frame.data, data, len);
if (ftdm_test_flag(&(dchan->iostats.s.rx), FTDM_IOSTATS_ERROR_CRC)) { if (ftdm_test_flag(&(dchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_CRC)) {
l1_frame.flags |= SNG_L1FRAME_ERROR_CRC; l1_frame.flags |= SNG_L1FRAME_ERROR_CRC;
} }
if (ftdm_test_flag(&(dchan->iostats.s.rx), FTDM_IOSTATS_ERROR_FRAME)) { if (ftdm_test_flag(&(dchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_FRAME)) {
l1_frame.flags |= SNG_L1FRAME_ERROR_FRAME; l1_frame.flags |= SNG_L1FRAME_ERROR_FRAME;
} }
if (ftdm_test_flag(&(dchan->iostats.s.rx), FTDM_IOSTATS_ERROR_ABORT)) { if (ftdm_test_flag(&(dchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_ABORT)) {
l1_frame.flags |= SNG_L1FRAME_ERROR_ABORT; l1_frame.flags |= SNG_L1FRAME_ERROR_ABORT;
} }
if (ftdm_test_flag(&(dchan->iostats.s.rx), FTDM_IOSTATS_ERROR_FIFO)) { if (ftdm_test_flag(&(dchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_FIFO)) {
l1_frame.flags |= SNG_L1FRAME_ERROR_FIFO; l1_frame.flags |= SNG_L1FRAME_ERROR_FIFO;
} }
if (ftdm_test_flag(&(dchan->iostats.s.rx), FTDM_IOSTATS_ERROR_DMA)) { if (ftdm_test_flag(&(dchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_DMA)) {
l1_frame.flags |= SNG_L1FRAME_ERROR_DMA; l1_frame.flags |= SNG_L1FRAME_ERROR_DMA;
} }
if (ftdm_test_flag(&(dchan->iostats.s.rx), FTDM_IOSTATS_QUEUE_THRES)) { if (ftdm_test_flag(&(dchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES)) {
/* Should we trigger congestion here? */ /* Should we trigger congestion here? */
l1_frame.flags |= SNG_L1FRAME_QUEUE_THRES; l1_frame.flags |= SNG_L1FRAME_QUEUE_THRES;
} }
if (ftdm_test_flag(&(dchan->iostats.s.rx), FTDM_IOSTATS_QUEUE_FULL)) { if (ftdm_test_flag(&(dchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_QUEUE_FULL)) {
/* Should we trigger congestion here? */ /* Should we trigger congestion here? */
l1_frame.flags |= SNG_L1FRAME_QUEUE_FULL; l1_frame.flags |= SNG_L1FRAME_QUEUE_FULL;
} }
@ -640,14 +640,20 @@ 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) void sngisdn_snd_event(ftdm_channel_t *dchan, ftdm_oob_event_t event)
{ {
sng_l1_event_t l1_event;
memset(&l1_event, 0, sizeof(l1_event));
sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) dchan->span->signal_data; sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) dchan->span->signal_data;
switch(event) { switch(event) {
case FTDM_OOB_ALARM_CLEAR: case FTDM_OOB_ALARM_CLEAR:
sng_isdn_event_ind(signal_data->link_id, SNG_L1EVENT_ALARM_OFF); l1_event.type = SNG_L1EVENT_ALARM_OFF;
sng_isdn_event_ind(signal_data->link_id, &l1_event);
break; break;
case FTDM_OOB_ALARM_TRAP: case FTDM_OOB_ALARM_TRAP:
sng_isdn_event_ind(signal_data->link_id, SNG_L1EVENT_ALARM_ON); l1_event.type = SNG_L1EVENT_ALARM_ON;
sng_isdn_event_ind(signal_data->link_id, &l1_event);
break; break;
default: default:
/* We do not care about the other OOB events for now */ /* We do not care about the other OOB events for now */

View File

@ -866,13 +866,15 @@ end_of_trace:
return; return;
} }
int16_t sngisdn_rcv_data_req(uint16_t spId, uint8_t *buff, uint32_t length) /* The stacks is wants to transmit a frame */
int16_t sngisdn_rcv_l1_data_req(uint16_t spId, sng_l1_frame_t *l1_frame)
{ {
ftdm_status_t status; ftdm_status_t status;
ftdm_wait_flag_t flags = FTDM_WRITE; ftdm_wait_flag_t flags = FTDM_WRITE;
sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[spId]; sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[spId];
ftdm_assert(signal_data, "Received Data request on unconfigured span\n"); ftdm_assert(signal_data, "Received Data request on unconfigured span\n");
ftdm_size_t length = l1_frame->len;
do { do {
flags = FTDM_WRITE; flags = FTDM_WRITE;
status = signal_data->dchan->fio->wait(signal_data->dchan, &flags, 1000); status = signal_data->dchan->fio->wait(signal_data->dchan, &flags, 1000);
@ -883,7 +885,7 @@ int16_t sngisdn_rcv_data_req(uint16_t spId, uint8_t *buff, uint32_t length)
if ((flags & FTDM_WRITE)) { if ((flags & FTDM_WRITE)) {
status = signal_data->dchan->fio->write(signal_data->dchan, buff, (ftdm_size_t*)&length); status = signal_data->dchan->fio->write(signal_data->dchan, l1_frame->data, (ftdm_size_t*)&length);
if (status != FTDM_SUCCESS) { if (status != FTDM_SUCCESS) {
ftdm_log_chan_msg(signal_data->dchan, FTDM_LOG_CRIT, "Failed to transmit frame\n"); ftdm_log_chan_msg(signal_data->dchan, FTDM_LOG_CRIT, "Failed to transmit frame\n");
return -1; return -1;
@ -900,6 +902,45 @@ int16_t sngisdn_rcv_data_req(uint16_t spId, uint8_t *buff, uint32_t length)
return 0; return 0;
} }
int16_t sngisdn_rcv_l1_cmd_req(uint16_t spId, sng_l1_cmd_t *l1_cmd)
{
sngisdn_span_data_t *signal_data = g_sngisdn_data.spans[spId];
ftdm_assert(signal_data, "Received Data request on unconfigured span\n");
switch(l1_cmd->type) {
case SNG_L1CMD_SET_LINK_STATUS:
{
ftdm_channel_hw_link_status_t status = FTDM_HW_LINK_CONNECTED;
ftdm_channel_command(signal_data->dchan, FTDM_COMMAND_SET_LINK_STATUS, &status);
}
break;
case SNG_L1CMD_GET_LINK_STATUS:
{
ftdm_channel_hw_link_status_t status = 0;
ftdm_channel_command(signal_data->dchan, FTDM_COMMAND_GET_LINK_STATUS, &status);
if (status == FTDM_HW_LINK_CONNECTED) {
l1_cmd->cmd.status = 1;
} else if (status == FTDM_HW_LINK_DISCONNECTED) {
l1_cmd->cmd.status = 0;
} else {
ftdm_log_chan(signal_data->dchan, FTDM_LOG_CRIT, "Invalid link status reported %d\n", status);
l1_cmd->cmd.status = 0;
}
}
break;
case SNG_L1CMD_FLUSH_STATS:
ftdm_channel_command(signal_data->dchan, FTDM_COMMAND_FLUSH_IOSTATS, NULL);
break;
case SNG_L1CMD_FLUSH_BUFFERS:
ftdm_channel_command(signal_data->dchan, FTDM_COMMAND_FLUSH_BUFFERS, NULL);
break;
default:
ftdm_log_chan(signal_data->dchan, FTDM_LOG_CRIT, "Unsupported channel command:%d\n", l1_cmd->type);
return -1;
}
return 0;
}
void sngisdn_rcv_sng_assert(char *message) void sngisdn_rcv_sng_assert(char *message)
{ {
ftdm_assert(0, message); ftdm_assert(0, message);

View File

@ -746,6 +746,28 @@ static FIO_COMMAND_FUNCTION(wanpipe_command)
} }
} }
break; break;
case FTDM_COMMAND_FLUSH_BUFFERS:
{
err = sangoma_flush_bufs(ftdmchan->sockfd, &tdm_api);
}
break;
case FTDM_COMMAND_FLUSH_IOSTATS:
{
err = sangoma_flush_stats(ftdmchan->sockfd, &tdm_api);
}
break;
case FTDM_COMMAND_SET_RX_QUEUE_SIZE:
{
uint32_t queue_size = FTDM_COMMAND_OBJ_INT;
err = sangoma_set_rx_queue_sz(ftdmchan->sockfd, &tdm_api, queue_size);
}
break;
case FTDM_COMMAND_SET_TX_QUEUE_SIZE:
{
uint32_t queue_size = FTDM_COMMAND_OBJ_INT;
err = sangoma_set_tx_queue_sz(ftdmchan->sockfd, &tdm_api, queue_size);
}
break;
default: default:
break; break;
}; };
@ -759,45 +781,42 @@ 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) static void wanpipe_read_stats(ftdm_channel_t *ftdmchan, wp_tdm_api_rx_hdr_t *rx_stats)
{ {
ftdmchan->iostats.s.rx.error_flags = 0; ftdmchan->iostats.stats.rx.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.stats.rx.errors = rx_stats->wp_api_rx_hdr_errors;
ftdmchan->iostats.s.rx_queue_len = rx_stats->rx_h.current_number_of_frames_in_rx_queue; ftdmchan->iostats.stats.rx.rx_queue_size = rx_stats->wp_api_rx_hdr_max_queue_length;
ftdmchan->iostats.stats.rx.rx_queue_len = rx_stats->wp_api_rx_hdr_number_of_frames_in_queue;
if (rx_stats->rx_h.wp_api_rx_hdr_error_map & (1<<WP_ABORT_ERROR_BIT)) { if (rx_stats->wp_api_rx_hdr_error_map & (1<<WP_ABORT_ERROR_BIT)) {
ftdm_set_flag(&(ftdmchan->iostats.s.rx), FTDM_IOSTATS_ERROR_ABORT); ftdm_set_flag(&(ftdmchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_ABORT);
} }
if (rx_stats->rx_h.wp_api_rx_hdr_error_map & (1<<WP_DMA_ERROR_BIT)) { if (rx_stats->wp_api_rx_hdr_error_map & (1<<WP_DMA_ERROR_BIT)) {
ftdm_set_flag(&(ftdmchan->iostats.s.rx), FTDM_IOSTATS_ERROR_DMA); ftdm_set_flag(&(ftdmchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_DMA);
} }
if (rx_stats->rx_h.wp_api_rx_hdr_error_map & (1<<WP_FIFO_ERROR_BIT)) { if (rx_stats->wp_api_rx_hdr_error_map & (1<<WP_FIFO_ERROR_BIT)) {
ftdm_set_flag(&(ftdmchan->iostats.s.rx), FTDM_IOSTATS_ERROR_FIFO); ftdm_set_flag(&(ftdmchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_FIFO);
} }
if (rx_stats->rx_h.wp_api_rx_hdr_error_map & (1<<WP_CRC_ERROR_BIT)) { if (rx_stats->wp_api_rx_hdr_error_map & (1<<WP_CRC_ERROR_BIT)) {
ftdm_set_flag(&(ftdmchan->iostats.s.rx), FTDM_IOSTATS_ERROR_CRC); ftdm_set_flag(&(ftdmchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_CRC);
} }
if (rx_stats->rx_h.wp_api_rx_hdr_error_map & (1<<WP_FRAME_ERROR_BIT)) { if (rx_stats->wp_api_rx_hdr_error_map & (1<<WP_FRAME_ERROR_BIT)) {
ftdm_set_flag(&(ftdmchan->iostats.s.rx), FTDM_IOSTATS_ERROR_FRAME); ftdm_set_flag(&(ftdmchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_FRAME);
} }
if (ftdmchan->iostats.s.rx_queue_len >= (0.8*ftdmchan->iostats.s.rx_queue_size)) { if (ftdmchan->iostats.stats.rx.rx_queue_len >= (0.8*ftdmchan->iostats.stats.rx.rx_queue_size)) {
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Rx Queue length exceeded threshold (%d/%d)\n", 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); ftdmchan->iostats.stats.rx.rx_queue_len, ftdmchan->iostats.stats.rx.rx_queue_size);
ftdm_set_flag(&(ftdmchan->iostats.s.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES); ftdm_set_flag(&(ftdmchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_QUEUE_THRES);
} }
if (ftdmchan->iostats.s.rx_queue_len >= ftdmchan->iostats.s.rx_queue_size) { if (ftdmchan->iostats.stats.rx.rx_queue_len >= ftdmchan->iostats.stats.rx.rx_queue_size) {
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Rx Queue Full (%d/%d)\n", 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); ftdmchan->iostats.stats.rx.rx_queue_len, ftdmchan->iostats.stats.rx.rx_queue_size);
ftdm_set_flag(&(ftdmchan->iostats.s.rx), FTDM_IOSTATS_ERROR_QUEUE_FULL); ftdm_set_flag(&(ftdmchan->iostats.stats.rx), FTDM_IOSTATS_ERROR_QUEUE_FULL);
} }
return; return;
} }

View File

@ -430,12 +430,15 @@ typedef enum {
FTDM_COMMAND_FLUSH_TX_BUFFERS, FTDM_COMMAND_FLUSH_TX_BUFFERS,
FTDM_COMMAND_FLUSH_RX_BUFFERS, FTDM_COMMAND_FLUSH_RX_BUFFERS,
FTDM_COMMAND_FLUSH_BUFFERS, FTDM_COMMAND_FLUSH_BUFFERS,
FTDM_COMMAND_FLUSH_IOSTATS,
FTDM_COMMAND_SET_PRE_BUFFER_SIZE, FTDM_COMMAND_SET_PRE_BUFFER_SIZE,
FTDM_COMMAND_SET_LINK_STATUS, FTDM_COMMAND_SET_LINK_STATUS,
FTDM_COMMAND_GET_LINK_STATUS, FTDM_COMMAND_GET_LINK_STATUS,
FTDM_COMMAND_ENABLE_LOOP, FTDM_COMMAND_ENABLE_LOOP,
FTDM_COMMAND_DISABLE_LOOP, FTDM_COMMAND_DISABLE_LOOP,
FTDM_COMMAND_COUNT FTDM_COMMAND_COUNT,
FTDM_COMMAND_SET_RX_QUEUE_SIZE,
FTDM_COMMAND_SET_TX_QUEUE_SIZE,
} ftdm_command_t; } ftdm_command_t;
/*! \brief Custom memory handler hooks. Not recommended to use unless you need memory allocation customizations */ /*! \brief Custom memory handler hooks. Not recommended to use unless you need memory allocation customizations */

View File

@ -391,7 +391,7 @@ typedef struct {
uint8_t tx_queue_size; /* max queue size configured */ uint8_t tx_queue_size; /* max queue size configured */
uint8_t tx_queue_len; /* Current number of elements in queue */ uint8_t tx_queue_len; /* Current number of elements in queue */
} tx; } tx;
} s; } stats;
} ftdm_channel_iostats_t; } ftdm_channel_iostats_t;
/* 2^8 table size, one for each byte (sample) value */ /* 2^8 table size, one for each byte (sample) value */

View File

@ -194,6 +194,7 @@ typedef enum {
FTDM_CHANNEL_FEATURE_CALLWAITING = (1 << 6), /*!< Channel will allow call waiting (ie: FXS devices) (read/write) */ FTDM_CHANNEL_FEATURE_CALLWAITING = (1 << 6), /*!< Channel will allow call waiting (ie: FXS devices) (read/write) */
FTDM_CHANNEL_FEATURE_HWEC = (1<<7), /*!< Channel has a hardware echo canceller */ FTDM_CHANNEL_FEATURE_HWEC = (1<<7), /*!< Channel has a hardware echo canceller */
FTDM_CHANNEL_FEATURE_HWEC_DISABLED_ON_IDLE = (1<<8), /*!< hardware echo canceller is disabled when there are no calls on this channel */ FTDM_CHANNEL_FEATURE_HWEC_DISABLED_ON_IDLE = (1<<8), /*!< hardware echo canceller is disabled when there are no calls on this channel */
FTDM_CHANNEL_FEATURE_IO_STATS = (1<<9), /*!< Channel supports IO statistics (HDLC channels only) */
} ftdm_channel_feature_t; } ftdm_channel_feature_t;
typedef enum { typedef enum {