freetdm: add initial changes for FreeTDM channel history feature
This commit is contained in:
parent
4999723687
commit
ed01944c15
|
@ -3660,7 +3660,12 @@ SWITCH_STANDARD_API(ft_function)
|
||||||
if(chan_id > ftdm_span_get_chan_count(span)) {
|
if(chan_id > ftdm_span_get_chan_count(span)) {
|
||||||
stream->write_function(stream, "-ERR invalid channel\n");
|
stream->write_function(stream, "-ERR invalid channel\n");
|
||||||
} else {
|
} else {
|
||||||
|
char *dbgstr = NULL;
|
||||||
|
ftdm_channel_t *fchan = ftdm_span_get_channel(span, chan_id);
|
||||||
dump_chan(span, chan_id, stream);
|
dump_chan(span, chan_id, stream);
|
||||||
|
dbgstr = ftdm_channel_get_history_str(fchan);
|
||||||
|
stream->write_function(stream, "%s\n", dbgstr);
|
||||||
|
ftdm_free(dbgstr);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
stream->write_function(stream, "+OK\n");
|
stream->write_function(stream, "+OK\n");
|
||||||
|
@ -3989,7 +3994,7 @@ SWITCH_STANDARD_API(ft_function)
|
||||||
|
|
||||||
if (rply) {
|
if (rply) {
|
||||||
stream->write_function(stream, "%s", rply);
|
stream->write_function(stream, "%s", rply);
|
||||||
free(rply);
|
ftdm_free(rply);
|
||||||
} else {
|
} else {
|
||||||
stream->write_function(stream, "-ERR Usage: %s\n", FT_SYNTAX);
|
stream->write_function(stream, "-ERR Usage: %s\n", FT_SYNTAX);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1293,6 +1293,16 @@ end:
|
||||||
ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Changed state from %s to %s\n", ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state));
|
ftdm_log_chan_ex(ftdmchan, file, func, line, FTDM_LOG_LEVEL_DEBUG, "Changed state from %s to %s\n", ftdm_channel_state2str(ftdmchan->state), ftdm_channel_state2str(state));
|
||||||
ftdmchan->last_state = ftdmchan->state;
|
ftdmchan->last_state = ftdmchan->state;
|
||||||
ftdmchan->state = state;
|
ftdmchan->state = state;
|
||||||
|
ftdmchan->history[ftdmchan->hindex].file = file;
|
||||||
|
ftdmchan->history[ftdmchan->hindex].func = func;
|
||||||
|
ftdmchan->history[ftdmchan->hindex].line = line;
|
||||||
|
ftdmchan->history[ftdmchan->hindex].state = ftdmchan->state;
|
||||||
|
ftdmchan->history[ftdmchan->hindex].last_state = ftdmchan->last_state;
|
||||||
|
ftdmchan->history[ftdmchan->hindex].time = ftdm_current_time_in_ms();
|
||||||
|
ftdmchan->hindex++;
|
||||||
|
if (ftdmchan->hindex == ftdm_array_len(ftdmchan->history)) {
|
||||||
|
ftdmchan->hindex = 0;
|
||||||
|
}
|
||||||
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE);
|
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE);
|
||||||
|
|
||||||
ftdm_mutex_lock(ftdmchan->span->mutex);
|
ftdm_mutex_lock(ftdmchan->span->mutex);
|
||||||
|
@ -5213,6 +5223,57 @@ FT_DECLARE(char *) ftdm_strndup(const char *str, ftdm_size_t inlen)
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define FTDM_DEBUG_LINE_LEN 255
|
||||||
|
FT_DECLARE(char *) ftdm_channel_get_history_str(const ftdm_channel_t *fchan)
|
||||||
|
{
|
||||||
|
uint8_t j = 0;
|
||||||
|
int written = 0;
|
||||||
|
char *buff = NULL;
|
||||||
|
uint8_t i = fchan->hindex;
|
||||||
|
|
||||||
|
int dbglen = ftdm_array_len(fchan->history) * FTDM_DEBUG_LINE_LEN;
|
||||||
|
int len = dbglen;
|
||||||
|
|
||||||
|
char *debugstr = ftdm_calloc(1, dbglen);
|
||||||
|
if (!debugstr) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
buff = debugstr;
|
||||||
|
|
||||||
|
for (i = fchan->hindex; i < ftdm_array_len(fchan->history); i++) {
|
||||||
|
if (!fchan->history[i].file) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
written = snprintf(buff, len, "%s -> %s at %s %s:%d\n",
|
||||||
|
ftdm_channel_state2str(fchan->history[i].last_state), ftdm_channel_state2str(fchan->history[i].state), fchan->history[i].func,
|
||||||
|
fchan->history[i].file, fchan->history[i].line);
|
||||||
|
if (written >= len) {
|
||||||
|
ftdm_free(debugstr);
|
||||||
|
ftdm_log(FTDM_LOG_ERROR, "Not enough memory to build debug history string\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
len -= written;
|
||||||
|
buff += written;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < fchan->hindex; j++) {
|
||||||
|
written = snprintf(buff, len, "%s -> %s at %s %s:%d\n",
|
||||||
|
ftdm_channel_state2str(fchan->history[i].last_state), ftdm_channel_state2str(fchan->history[i].state), fchan->history[i].func,
|
||||||
|
fchan->history[i].file, fchan->history[i].line);
|
||||||
|
if (written >= len) {
|
||||||
|
ftdm_free(debugstr);
|
||||||
|
ftdm_log(FTDM_LOG_ERROR, "Not enough memory to build debug history string\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
len -= written;
|
||||||
|
buff += written;
|
||||||
|
}
|
||||||
|
|
||||||
|
debugstr[dbglen-1] = 0;
|
||||||
|
|
||||||
|
return debugstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* For Emacs:
|
/* For Emacs:
|
||||||
* Local Variables:
|
* Local Variables:
|
||||||
|
|
|
@ -1277,7 +1277,13 @@ FT_DECLARE(const char *) ftdm_channel_get_state_str(const ftdm_channel_t *channe
|
||||||
/*! \brief For display debugging purposes you can display this string which describes the last channel internal state */
|
/*! \brief For display debugging purposes you can display this string which describes the last channel internal state */
|
||||||
FT_DECLARE(const char *) ftdm_channel_get_last_state_str(const ftdm_channel_t *channel);
|
FT_DECLARE(const char *) ftdm_channel_get_last_state_str(const ftdm_channel_t *channel);
|
||||||
|
|
||||||
/*! \brief For display debugging purposes you can display this string which describes the last channel internal state */
|
/*! \brief For display debugging purposes you can display this string which describes the history of the channel
|
||||||
|
* \param The channel
|
||||||
|
* \return History string for the channel. You must free the string with ftdm_free
|
||||||
|
*/
|
||||||
|
FT_DECLARE(char *) ftdm_channel_get_history_str(const ftdm_channel_t *channel);
|
||||||
|
|
||||||
|
/*! \brief Initialize channel state for an outgoing call */
|
||||||
FT_DECLARE(ftdm_status_t) ftdm_channel_init(ftdm_channel_t *ftdmchan);
|
FT_DECLARE(ftdm_status_t) ftdm_channel_init(ftdm_channel_t *ftdmchan);
|
||||||
|
|
||||||
/*! \brief Initialize the library */
|
/*! \brief Initialize the library */
|
||||||
|
|
|
@ -356,6 +356,15 @@ typedef struct {
|
||||||
} ftdm_dtmf_debug_t;
|
} ftdm_dtmf_debug_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *file;
|
||||||
|
const char *func;
|
||||||
|
int line;
|
||||||
|
ftdm_channel_state_t state;
|
||||||
|
ftdm_channel_state_t last_state;
|
||||||
|
ftdm_time_t time;
|
||||||
|
} ftdm_channel_history_entry_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 {
|
||||||
|
@ -381,6 +390,8 @@ struct ftdm_channel {
|
||||||
ftdm_channel_state_t state;
|
ftdm_channel_state_t state;
|
||||||
ftdm_channel_state_t last_state;
|
ftdm_channel_state_t last_state;
|
||||||
ftdm_channel_state_t init_state;
|
ftdm_channel_state_t init_state;
|
||||||
|
ftdm_channel_history_entry_t history[10];
|
||||||
|
uint8_t hindex;
|
||||||
ftdm_mutex_t *mutex;
|
ftdm_mutex_t *mutex;
|
||||||
teletone_dtmf_detect_state_t dtmf_detect;
|
teletone_dtmf_detect_state_t dtmf_detect;
|
||||||
uint32_t buffer_delay;
|
uint32_t buffer_delay;
|
||||||
|
|
Loading…
Reference in New Issue