freetdm: allow IO statistics access to users
added ftdm iostats command
This commit is contained in:
parent
f527ed686f
commit
68b887c760
|
@ -4346,6 +4346,76 @@ end:
|
|||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static void exec_io_command(const char *cmd, switch_stream_handle_t *stream, ftdm_channel_t *fchan)
|
||||
{
|
||||
int enable = 0;
|
||||
ftdm_channel_iostats_t stats;
|
||||
if (!strcasecmp("enable", cmd)) {
|
||||
enable = 1;
|
||||
ftdm_channel_command(fchan, FTDM_COMMAND_SWITCH_IOSTATS, &enable);
|
||||
} else if (!strcasecmp("disable", cmd)) {
|
||||
enable = 0;
|
||||
ftdm_channel_command(fchan, FTDM_COMMAND_SWITCH_IOSTATS, &enable);
|
||||
} else if (!strcasecmp("flush", cmd)) {
|
||||
ftdm_channel_command(fchan, FTDM_COMMAND_FLUSH_IOSTATS, NULL);
|
||||
} else {
|
||||
ftdm_channel_command(fchan, FTDM_COMMAND_GET_IOSTATS, &stats);
|
||||
stream->write_function(stream, "-- IO statistics for channel %d:%d --\n",
|
||||
ftdm_channel_get_span_id(fchan), ftdm_channel_get_id(fchan));
|
||||
stream->write_function(stream, "Rx errors: %u\n", stats.rx.errors);
|
||||
stream->write_function(stream, "Rx queue size: %u\n", stats.rx.queue_size);
|
||||
stream->write_function(stream, "Rx queue len: %u\n", stats.rx.queue_len);
|
||||
stream->write_function(stream, "Rx count: %lu\n", stats.rx.packets);
|
||||
|
||||
stream->write_function(stream, "Tx errors: %u\n", stats.tx.errors);
|
||||
stream->write_function(stream, "Tx queue len: %u\n", stats.tx.queue_len);
|
||||
stream->write_function(stream, "Tx queue len: %u\n", stats.tx.queue_len);
|
||||
stream->write_function(stream, "Tx count: %lu\n", stats.tx.packets);
|
||||
stream->write_function(stream, "Tx idle: %u\n", stats.tx.idle_packets);
|
||||
}
|
||||
}
|
||||
|
||||
static switch_status_t ftdm_cmd_iostats(const char *cmd, switch_core_session_t *session,
|
||||
switch_stream_handle_t *stream, int argc, char *argv[])
|
||||
{
|
||||
uint32_t chan_id = 0;
|
||||
ftdm_channel_t *chan;
|
||||
ftdm_iterator_t *iter = NULL;
|
||||
ftdm_iterator_t *curr = NULL;
|
||||
ftdm_span_t *span = NULL;
|
||||
|
||||
if (argc < 3) {
|
||||
stream->write_function(stream, "-ERR Usage: ftdm iostats enable|disable|flush|print <span_id> [<chan_id>]\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
ftdm_span_find_by_name(argv[2], &span);
|
||||
if (!span) {
|
||||
stream->write_function(stream, "-ERR invalid span\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (argc > 3) {
|
||||
chan_id = atoi(argv[3]);
|
||||
if (chan_id > ftdm_span_get_chan_count(span)) {
|
||||
stream->write_function(stream, "-ERR invalid chan\n");
|
||||
goto end;
|
||||
}
|
||||
chan = ftdm_span_get_channel(span, chan_id);
|
||||
exec_io_command(argv[1], stream, chan);
|
||||
} else {
|
||||
iter = ftdm_span_get_chan_iterator(span, NULL);
|
||||
for (curr = iter; curr; curr = ftdm_iterator_next(curr)) {
|
||||
chan = ftdm_iterator_current(curr);
|
||||
exec_io_command(argv[1], stream, chan);
|
||||
}
|
||||
ftdm_iterator_free(iter);
|
||||
}
|
||||
stream->write_function(stream, "+OK\n");
|
||||
end:
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
typedef switch_status_t (*ftdm_cli_function_t)(const char *cmd, switch_core_session_t *session,
|
||||
switch_stream_handle_t *stream, int argc, char *argv[]);
|
||||
typedef struct ftdm_cli_entry {
|
||||
|
@ -4368,6 +4438,7 @@ static ftdm_cli_entry_t ftdm_cli_options[] =
|
|||
{ "gains", "<rxgain> <txgain> <span_id|span_name> [<chan_id>]", "", ftdm_cmd_gains },
|
||||
{ "dtmf", "on|off <span_id|span_name> [<chan_id>]", "::[on:off", ftdm_cmd_dtmf },
|
||||
{ "queuesize", "<rxsize> <txsize> <span_id|span_name> [<chan_id>]", "", ftdm_cmd_queuesize },
|
||||
{ "iostats", "enable|disable|flush|print <span_id|span_name> <chan_id>", "::[enable:disable:flush:print", ftdm_cmd_iostats },
|
||||
{ "voice_detect", "[on|off] <span_id|span_name> [<chan_id>]", "::[on:off", ftdm_cmd_voice_detect },
|
||||
|
||||
/* Fake handlers as they are handled within freetdm library,
|
||||
|
|
|
@ -2825,9 +2825,9 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co
|
|||
ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "No channel\n");
|
||||
ftdm_assert_return(ftdmchan->fio != NULL, FTDM_FAIL, "No IO attached to channel\n");
|
||||
|
||||
ftdm_mutex_lock(ftdmchan->mutex);
|
||||
ftdm_channel_lock(ftdmchan);
|
||||
|
||||
switch(command) {
|
||||
switch (command) {
|
||||
|
||||
case FTDM_COMMAND_ENABLE_CALLERID_DETECT:
|
||||
{
|
||||
|
@ -3278,12 +3278,31 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co
|
|||
GOTO_STATUS(done, FTDM_SUCCESS);
|
||||
}
|
||||
break;
|
||||
case FTDM_COMMAND_GET_IOSTATS:
|
||||
{
|
||||
if (!obj) {
|
||||
GOTO_STATUS(done, FTDM_EINVAL);
|
||||
}
|
||||
memcpy(obj, &ftdmchan->iostats, sizeof(ftdmchan->iostats));
|
||||
GOTO_STATUS(done, FTDM_SUCCESS);
|
||||
}
|
||||
break;
|
||||
case FTDM_COMMAND_SWITCH_IOSTATS:
|
||||
{
|
||||
ftdm_bool_t enable = *(ftdm_bool_t *)obj;
|
||||
if (enable) {
|
||||
ftdm_channel_set_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS);
|
||||
} else {
|
||||
ftdm_channel_clear_feature(ftdmchan, FTDM_CHANNEL_FEATURE_IO_STATS);
|
||||
}
|
||||
GOTO_STATUS(done, FTDM_SUCCESS);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ftdmchan->fio->command) {
|
||||
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "method not implemented");
|
||||
ftdm_log(FTDM_LOG_ERROR, "no command function defined by the I/O freetdm module!\n");
|
||||
GOTO_STATUS(done, FTDM_FAIL);
|
||||
}
|
||||
|
@ -3291,11 +3310,12 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co
|
|||
status = ftdmchan->fio->command(ftdmchan, command, obj);
|
||||
|
||||
if (status == FTDM_NOTIMPL) {
|
||||
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "I/O command %d not implemented in backend", command);
|
||||
ftdm_log(FTDM_LOG_ERROR, "I/O backend does not support command %d!\n", command);
|
||||
}
|
||||
|
||||
done:
|
||||
ftdm_mutex_unlock(ftdmchan->mutex);
|
||||
ftdm_channel_unlock(ftdmchan);
|
||||
|
||||
return status;
|
||||
|
||||
}
|
||||
|
|
|
@ -707,7 +707,10 @@ typedef enum {
|
|||
FTDM_COMMAND_FLUSH_TX_BUFFERS = 45,
|
||||
FTDM_COMMAND_FLUSH_RX_BUFFERS = 46,
|
||||
FTDM_COMMAND_FLUSH_BUFFERS = 47,
|
||||
|
||||
/*!< Flush IO statistics */
|
||||
FTDM_COMMAND_FLUSH_IOSTATS = 48,
|
||||
|
||||
FTDM_COMMAND_SET_PRE_BUFFER_SIZE = 49,
|
||||
FTDM_COMMAND_SET_LINK_STATUS = 50,
|
||||
FTDM_COMMAND_GET_LINK_STATUS = 51,
|
||||
|
@ -719,6 +722,11 @@ typedef enum {
|
|||
FTDM_COMMAND_START_MF_PLAYBACK = 57,
|
||||
FTDM_COMMAND_STOP_MF_PLAYBACK = 58,
|
||||
|
||||
/*!< Get a copy of the current IO stats */
|
||||
FTDM_COMMAND_GET_IOSTATS = 59,
|
||||
/*!< Enable/disable IO stats in the channel */
|
||||
FTDM_COMMAND_SWITCH_IOSTATS = 60,
|
||||
|
||||
FTDM_COMMAND_COUNT,
|
||||
} ftdm_command_t;
|
||||
|
||||
|
@ -903,6 +911,37 @@ typedef enum {
|
|||
FTDM_MF_DIRECTION_BACKWARD = (1 << 9)
|
||||
} ftdm_mf_direction_flag_t;
|
||||
|
||||
/*! \brief IO Error statistics */
|
||||
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;
|
||||
|
||||
/*! \brief IO statistics */
|
||||
typedef struct {
|
||||
struct {
|
||||
uint32_t errors;
|
||||
uint16_t flags;
|
||||
uint8_t queue_size; /*!< max queue size configured */
|
||||
uint8_t queue_len; /*!< Current number of elements in queue */
|
||||
uint64_t packets;
|
||||
} rx;
|
||||
|
||||
struct {
|
||||
uint32_t errors;
|
||||
uint16_t flags;
|
||||
uint8_t idle_packets;
|
||||
uint8_t queue_size; /*!< max queue size configured */
|
||||
uint8_t queue_len; /*!< Current number of elements in queue */
|
||||
uint64_t packets;
|
||||
} tx;
|
||||
} ftdm_channel_iostats_t;
|
||||
|
||||
/*! \brief Override the default queue handler */
|
||||
FT_DECLARE(ftdm_status_t) ftdm_global_set_queue_handler(ftdm_queue_handler_t *handler);
|
||||
|
||||
|
|
|
@ -359,35 +359,6 @@ typedef struct {
|
|||
ftdm_mutex_t *mutex;
|
||||
} ftdm_dtmf_debug_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 {
|
||||
struct {
|
||||
uint32_t errors;
|
||||
uint16_t flags;
|
||||
uint8_t queue_size; /* max queue size configured */
|
||||
uint8_t queue_len; /* Current number of elements in queue */
|
||||
uint64_t packets;
|
||||
} rx;
|
||||
|
||||
struct {
|
||||
uint32_t errors;
|
||||
uint16_t flags;
|
||||
uint8_t idle_packets;
|
||||
uint8_t queue_size; /* max queue size configured */
|
||||
uint8_t queue_len; /* Current number of elements in queue */
|
||||
uint64_t packets;
|
||||
} tx;
|
||||
} ftdm_channel_iostats_t;
|
||||
|
||||
/* 2^8 table size, one for each byte (sample) value */
|
||||
#define FTDM_GAINS_TABLE_SIZE 256
|
||||
struct ftdm_channel {
|
||||
|
|
Loading…
Reference in New Issue