From 318866b7f95a5d8119073198a5379f3d9ea02b62 Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Tue, 27 Apr 2010 14:32:36 -0400 Subject: [PATCH] freetdm: Added signalling status report Fix for ftmod_libpri not reporting proper physical and protocol alarms on init --- libs/freetdm/mod_freetdm/mod_freetdm.c | 11 ++- libs/freetdm/src/ftdm_io.c | 99 +++++++++++++------ .../src/ftmod/ftmod_analog/ftmod_analog.c | 29 ++++++ .../ftmod/ftmod_analog_em/ftmod_analog_em.c | 28 ++++++ .../src/ftmod/ftmod_libpri/ftmod_libpri.c | 79 ++++++++++++++- .../src/ftmod/ftmod_libpri/lpwrap_pri.c | 2 +- libs/freetdm/src/include/freetdm.h | 11 +++ libs/freetdm/src/include/ftdm_types.h | 1 + 8 files changed, 221 insertions(+), 39 deletions(-) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 269908ba27..733ee84781 100644 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -25,6 +25,7 @@ * * Anthony Minessale II * Moises Silva + * David Yat Sin * * * mod_freetdm.c -- FreeTDM Endpoint Module @@ -3002,8 +3003,8 @@ void dump_chan(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t *stre "chan_id: %u\n" "physical_span_id: %u\n" "physical_chan_id: %u\n" - "physical_state: %s\n" - "signaling_state: %s\n" + "physical_status: %s\n" + "signaling_status: %s\n" "type: %s\n" "state: %s\n" "last_state: %s\n" @@ -3051,8 +3052,8 @@ void dump_chan_xml(ftdm_span_t *span, uint32_t chan_id, switch_stream_handle_t * " %u>\n" " %u\n" " %u\n" - " %s\n" - " %s\n" + " %s\n" + " %s\n" " %s\n" " %s\n" " %s\n" @@ -3186,7 +3187,7 @@ SWITCH_STANDARD_API(ft_function) stream->write_function(stream, "+OK\n" "span: %u (%s)\n" - "type: %s\n" + "type: %s\n" "signaling_status: %s\n" "chan_count: %u\n" "dialplan: %s\n" diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 86fbd88da4..ae4385c0a3 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -143,6 +143,8 @@ FTDM_STR2ENUM(ftdm_str2ftdm_chan_type, ftdm_chan_type2str, ftdm_chan_type_t, CHA FTDM_ENUM_NAMES(SIGNALING_STATUS_NAMES, SIGSTATUS_STRINGS) FTDM_STR2ENUM(ftdm_str2ftdm_signaling_status, ftdm_signaling_status2str, ftdm_signaling_status_t, SIGNALING_STATUS_NAMES, FTDM_SIG_STATE_INVALID) +static ftdm_status_t ftdm_group_add_channels(ftdm_span_t* span, int currindex, const char* name); + static const char *cut_path(const char *in) { const char *p, *ret = in; @@ -775,7 +777,7 @@ FT_DECLARE(ftdm_status_t) ftdm_span_add_channel(ftdm_span_t *span, ftdm_socket_t i++; } - ftdm_set_flag(new_chan, FTDM_CHANNEL_CONFIGURED | FTDM_CHANNEL_READY); + ftdm_set_flag(new_chan, FTDM_CHANNEL_CONFIGURED | FTDM_CHANNEL_READY); *chan = new_chan; return FTDM_SUCCESS; } @@ -2853,26 +2855,71 @@ FT_DECLARE(char *) ftdm_api_execute(const char *type, const char *cmd) return rval; } -static void ftdm_set_channels_gains(ftdm_span_t *span, int currindex, float rxgain, float txgain) +static ftdm_status_t ftdm_set_channels_gains(ftdm_span_t *span, int currindex, float rxgain, float txgain) { unsigned chan_index = 0; if (!span->chan_count) { - return; + ftdm_log(FTDM_LOG_ERROR, "%d:Failed to set gains because span has no channels\n"); + return FTDM_FAIL; } for (chan_index = currindex+1; chan_index <= span->chan_count; chan_index++) { if (!FTDM_IS_VOICE_CHANNEL(span->channels[chan_index])) { continue; } - ftdm_channel_command(span->channels[chan_index], FTDM_COMMAND_SET_RX_GAIN, &rxgain); - ftdm_channel_command(span->channels[chan_index], FTDM_COMMAND_SET_TX_GAIN, &txgain); + if (ftdm_channel_command(span->channels[chan_index], FTDM_COMMAND_SET_RX_GAIN, &rxgain) != FTDM_SUCCESS) { + return FTDM_FAIL; + } + if (ftdm_channel_command(span->channels[chan_index], FTDM_COMMAND_SET_TX_GAIN, &txgain) != FTDM_SUCCESS) { + return FTDM_FAIL; + } } + return FTDM_SUCCESS; +} + +static ftdm_status_t ftdm_set_channels_alarms(ftdm_span_t *span, int currindex) { + unsigned chan_index = 0; + + if (!span->chan_count) { + ftdm_log(FTDM_LOG_ERROR, "%d:Failed to set alarms because span has no channels\n"); + return FTDM_FAIL; + } + + if (!span->fio->get_alarms) { + ftdm_log(FTDM_LOG_WARNING, "%d: Span does not support alarms\n", span->span_id); + return FTDM_SUCCESS; + } + + for (chan_index = currindex+1; chan_index <= span->chan_count; chan_index++) { + /* fio->get_alarms will update ftdm_chan->alarm_flags */ + if (span->fio->get_alarms(span->channels[chan_index]) != FTDM_SUCCESS) { + 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_SUCCESS; } +FT_DECLARE(ftdm_status_t) ftdm_configure_span_channels(ftdm_span_t *span, int currindex, ftdm_channel_config_t *chan_config) +{ + if (ftdm_group_add_channels(span, currindex, chan_config->group_name) != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_ERROR, "%d:Failed to add channels to group %s\n", span->span_id, chan_config->group_name); + return FTDM_FAIL; + } + if (ftdm_set_channels_alarms(span, currindex) != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_ERROR, "%d:Failed to set channel alarms\n", span->span_id); + return FTDM_FAIL; + } + if (ftdm_set_channels_gains(span, currindex, chan_config->rxgain, chan_config->txgain) != FTDM_SUCCESS) { + ftdm_log(FTDM_LOG_ERROR, "%d:Failed to set channel gains\n", span->span_id); + return FTDM_FAIL; + } + return FTDM_SUCCESS; +} + -static ftdm_status_t ftdm_group_add_channels(const char* name, ftdm_span_t* span, int currindex); static ftdm_status_t load_config(void) { char cfg_name[] = "freetdm.conf"; @@ -2883,14 +2930,15 @@ static ftdm_status_t load_config(void) int currindex = 0; ftdm_span_t *span = NULL; unsigned configured = 0, d = 0; - char name[80] = ""; + char name[FTDM_MAX_NAME_STR_SZ] = ""; char number[25] = ""; - char group_name[80] = "default"; ftdm_io_interface_t *fio = NULL; ftdm_analog_start_type_t tmp; - float rxgain = 0.0; - float txgain = 0.0; ftdm_size_t len = 0; + ftdm_channel_config_t chan_config; + + memset(&chan_config, 0, sizeof(chan_config)); + sprintf(chan_config.group_name,"default"); if (!ftdm_config_open_file(&cfg, cfg_name)) { return FTDM_FAIL; @@ -2997,8 +3045,7 @@ static ftdm_status_t load_config(void) if (span->trunk_type == FTDM_TRUNK_FXO) { currindex = span->chan_count; configured += fio->configure_span(span, val, FTDM_CHAN_TYPE_FXO, name, number); - ftdm_set_channels_gains(span, currindex, rxgain, txgain); - ftdm_group_add_channels(group_name, span, currindex); + ftdm_configure_span_channels(span, currindex, &chan_config); } else { ftdm_log(FTDM_LOG_WARNING, "Cannot add FXO channels to an FXS trunk!\n"); } @@ -3011,8 +3058,7 @@ static ftdm_status_t load_config(void) if (span->trunk_type == FTDM_TRUNK_FXS) { currindex = span->chan_count; configured += fio->configure_span(span, val, FTDM_CHAN_TYPE_FXS, name, number); - ftdm_set_channels_gains(span, currindex, rxgain, txgain); - ftdm_group_add_channels(group_name, span, currindex); + ftdm_configure_span_channels(span, currindex, &chan_config); } else { ftdm_log(FTDM_LOG_WARNING, "Cannot add FXS channels to an FXO trunk!\n"); } @@ -3025,16 +3071,14 @@ static ftdm_status_t load_config(void) if (span->trunk_type == FTDM_TRUNK_EM) { currindex = span->chan_count; configured += fio->configure_span(span, val, FTDM_CHAN_TYPE_EM, name, number); - ftdm_set_channels_gains(span, currindex, rxgain, txgain); - ftdm_group_add_channels(group_name, span, currindex); + ftdm_configure_span_channels(span, currindex, &chan_config); } else { ftdm_log(FTDM_LOG_WARNING, "Cannot add EM channels to a non-EM trunk!\n"); } } else if (!strcasecmp(var, "b-channel")) { currindex = span->chan_count; configured += fio->configure_span(span, val, FTDM_CHAN_TYPE_B, name, number); - ftdm_set_channels_gains(span, currindex, rxgain, txgain); - ftdm_group_add_channels(group_name, span, currindex); + ftdm_configure_span_channels(span, currindex, &chan_config); } else if (!strcasecmp(var, "d-channel")) { if (d) { ftdm_log(FTDM_LOG_WARNING, "ignoring extra d-channel\n"); @@ -3051,28 +3095,27 @@ static ftdm_status_t load_config(void) } } else if (!strcasecmp(var, "cas-channel")) { currindex = span->chan_count; - configured += fio->configure_span(span, val, FTDM_CHAN_TYPE_CAS, name, number); - ftdm_set_channels_gains(span, currindex, rxgain, txgain); - ftdm_group_add_channels(group_name, span, currindex); + configured += fio->configure_span(span, val, FTDM_CHAN_TYPE_CAS, name, number); + ftdm_configure_span_channels(span, currindex, &chan_config); } else if (!strcasecmp(var, "dtmf_hangup")) { span->dtmf_hangup = ftdm_strdup(val); span->dtmf_hangup_len = strlen(val); } else if (!strcasecmp(var, "txgain")) { - if (sscanf(val, "%f", &txgain) != 1) { + if (sscanf(val, "%f", &(chan_config.txgain)) != 1) { ftdm_log(FTDM_LOG_ERROR, "invalid txgain: '%s'\n", val); } } else if (!strcasecmp(var, "rxgain")) { - if (sscanf(val, "%f", &rxgain) != 1) { + if (sscanf(val, "%f", &(chan_config.rxgain)) != 1) { ftdm_log(FTDM_LOG_ERROR, "invalid rxgain: '%s'\n", val); } } else if (!strcasecmp(var, "group")) { len = strlen(val); - if (len >= sizeof(group_name)) { - len = sizeof(group_name) - 1; + if (len >= FTDM_MAX_NAME_STR_SZ) { + len = FTDM_MAX_NAME_STR_SZ - 1; ftdm_log(FTDM_LOG_WARNING, "Truncating group name %s to %zd length\n", val, len); } - memcpy(group_name, val, len); - group_name[len] = '\0'; + memcpy(chan_config.group_name, val, len); + chan_config.group_name[len] = '\0'; } else { ftdm_log(FTDM_LOG_ERROR, "unknown span variable '%s'\n", var); } @@ -3529,7 +3572,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_remove_from_group(ftdm_group_t* group, ft return FTDM_FAIL; } -static ftdm_status_t ftdm_group_add_channels(const char* name, ftdm_span_t* span, int currindex) +static ftdm_status_t ftdm_group_add_channels(ftdm_span_t* span, int currindex, const char* name) { unsigned chan_index = 0; diff --git a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c index c71b19d202..c7ad6b9870 100644 --- a/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c +++ b/libs/freetdm/src/ftmod/ftmod_analog/ftmod_analog.c @@ -84,6 +84,32 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(analog_fxs_outgoing_call) return FTDM_SUCCESS; } +/** + * \brief Returns the signalling status on a channel + * \param ftdmchan Channel to get status on + * \param status Pointer to set signalling status + * \return Success or failure + */ + +static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(analog_get_channel_sig_status) +{ + *status = FTDM_SIG_STATE_UP; + return FTDM_SUCCESS; +} + +/** + * \brief Returns the signalling status on a span + * \param span Span to get status on + * \param status Pointer to set signalling status + * \return Success or failure + */ + +static FIO_SPAN_GET_SIG_STATUS_FUNCTION(analog_get_span_sig_status) +{ + *status = FTDM_SIG_STATE_UP; + return FTDM_SUCCESS; +} + /** * \brief Starts an analog span thread (monitor) * \param span Span to monitor @@ -181,6 +207,9 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_configure_span) span->signal_type = FTDM_SIGTYPE_ANALOG; span->signal_data = analog_data; span->outgoing_call = span->trunk_type == FTDM_TRUNK_FXS ? analog_fxs_outgoing_call : analog_fxo_outgoing_call; + span->get_channel_sig_status = analog_get_channel_sig_status; + span->get_span_sig_status = analog_get_span_sig_status; + ftdm_span_load_tones(span, tonemap); return FTDM_SUCCESS; diff --git a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c index bb11798c68..146bcb9ea4 100644 --- a/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c +++ b/libs/freetdm/src/ftmod/ftmod_analog_em/ftmod_analog_em.c @@ -82,6 +82,32 @@ static ftdm_status_t ftdm_analog_em_start(ftdm_span_t *span) return ftdm_thread_create_detached(ftdm_analog_em_run, span); } +/** + * \brief Returns the signalling status on a channel + * \param ftdmchan Channel to get status on + * \param status Pointer to set signalling status + * \return Success or failure + */ + +static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(analog_em_get_channel_sig_status) +{ + *status = FTDM_SIG_STATE_UP; + return FTDM_SUCCESS; +} + +/** + * \brief Returns the signalling status on a span + * \param span Span to get status on + * \param status Pointer to set signalling status + * \return Success or failure + */ + +static FIO_SPAN_GET_SIG_STATUS_FUNCTION(analog_em_get_span_sig_status) +{ + *status = FTDM_SIG_STATE_UP; + return FTDM_SUCCESS; +} + /** * \brief Initialises an EM span from configuration variables * \param span Span to configure @@ -149,6 +175,8 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_analog_em_configure_span) span->signal_type = FTDM_SIGTYPE_ANALOG; span->signal_data = analog_data; span->outgoing_call = analog_em_outgoing_call; + span->get_channel_sig_status = analog_em_get_channel_sig_status; + span->get_span_sig_status = analog_em_get_span_sig_status; ftdm_span_load_tones(span, tonemap); return FTDM_SUCCESS; diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c index 871769e49e..be9313f1ca 100644 --- a/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c +++ b/libs/freetdm/src/ftmod/ftmod_libpri/ftmod_libpri.c @@ -43,6 +43,43 @@ static FIO_IO_UNLOAD_FUNCTION(ftdm_libpri_unload) return FTDM_SUCCESS; } +/** + * \brief Returns the signalling status on a channel + * \param ftdmchan Channel to get status on + * \param status Pointer to set signalling status + * \return Success or failure + */ + +static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(isdn_get_channel_sig_status) +{ + *status = FTDM_SIG_STATE_DOWN; + + ftdm_libpri_data_t *isdn_data = ftdmchan->span->signal_data; + if (ftdm_test_flag(&(isdn_data->spri), LPWRAP_PRI_READY)) { + *status = FTDM_SIG_STATE_UP; + } + return FTDM_SUCCESS; +} + +/** + * \brief Returns the signalling status on a span + * \param span Span to get status on + * \param status Pointer to set signalling status + * \return Success or failure + */ + +static FIO_SPAN_GET_SIG_STATUS_FUNCTION(isdn_get_span_sig_status) +{ + *status = FTDM_SIG_STATE_DOWN; + + ftdm_libpri_data_t *isdn_data = span->signal_data; + if (ftdm_test_flag(&(isdn_data->spri), LPWRAP_PRI_READY)) { + *status = FTDM_SIG_STATE_UP; + } + return FTDM_SUCCESS; +} + + /** * \brief Starts a libpri channel (outgoing call) * \param ftdmchan Channel to initiate call on @@ -937,13 +974,27 @@ static int on_restart(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_eve */ static int on_dchan_up(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent) { - if (!ftdm_test_flag(spri, LPWRAP_PRI_READY)) { + ftdm_signaling_status_t status = FTDM_SIG_STATE_UP; + ftdm_channel_t *ftdmchan = NULL; + ftdm_sigmsg_t sig; + int i; ftdm_log(FTDM_LOG_INFO, "Span %d D-Chan UP!\n", spri->span->span_id); ftdm_set_flag(spri, LPWRAP_PRI_READY); ftdm_set_state_all(spri->span, FTDM_CHANNEL_STATE_RESTART); - } + ftdm_log(FTDM_LOG_NOTICE, "%d:Signaling link status changed to %s\n", spri->span->span_id, ftdm_signaling_status2str(status)); + for(i=1; i <= spri->span->chan_count; i++) { + ftdmchan = spri->span->channels[i]; + memset(&sig, 0, sizeof(sig)); + sig.chan_id = ftdmchan->chan_id; + sig.span_id = ftdmchan->span_id; + sig.channel = ftdmchan; + sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; + sig.raw_data = &status; + ftdm_span_send_signal(spri->span, &sig); + } + } return 0; } @@ -955,13 +1006,28 @@ static int on_dchan_up(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_ev * \return 0 */ static int on_dchan_down(lpwrap_pri_t *spri, lpwrap_pri_event_t event_type, pri_event *pevent) -{ - +{ if (ftdm_test_flag(spri, LPWRAP_PRI_READY)) { + ftdm_signaling_status_t status = FTDM_SIG_STATE_DOWN; + ftdm_channel_t *ftdmchan = NULL; + ftdm_sigmsg_t sig; + int i; ftdm_log(FTDM_LOG_INFO, "Span %d D-Chan DOWN!\n", spri->span->span_id); ftdm_clear_flag(spri, LPWRAP_PRI_READY); ftdm_set_state_all(spri->span, FTDM_CHANNEL_STATE_RESTART); - + + + ftdm_log(FTDM_LOG_NOTICE, "%d:Signaling link status changed to %s\n", spri->span->span_id, ftdm_signaling_status2str(status)); + for(i=1; i <= spri->span->chan_count; i++) { + ftdmchan = spri->span->channels[i]; + memset(&sig, 0, sizeof(sig)); + sig.chan_id = ftdmchan->chan_id; + sig.span_id = ftdmchan->span_id; + sig.channel = ftdmchan; + sig.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; + sig.raw_data = &status; + ftdm_span_send_signal(spri->span, &sig); + } } return 0; @@ -1329,6 +1395,9 @@ static FIO_SIG_CONFIGURE_FUNCTION(ftdm_libpri_configure_span) span->signal_type = FTDM_SIGTYPE_ISDN; span->outgoing_call = isdn_outgoing_call; + span->get_channel_sig_status = isdn_get_channel_sig_status; + span->get_span_sig_status = isdn_get_span_sig_status; + if ((isdn_data->opts & FTMOD_LIBPRI_OPT_SUGGEST_CHANNEL)) { span->channel_request = isdn_channel_request; ftdm_set_flag(span, FTDM_SPAN_SUGGEST_CHAN_ID); diff --git a/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c b/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c index de6a311ef9..2a9f1b77c2 100644 --- a/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c +++ b/libs/freetdm/src/ftmod/ftmod_libpri/lpwrap_pri.c @@ -182,7 +182,7 @@ int lpwrap_init_pri(struct lpwrap_pri *spri, ftdm_span_t *span, ftdm_channel_t * size_t buflen = sizeof(buf), len = 0; pri_set_debug(spri->pri, debug); ret = 0; - ftdm_set_flag(spri, LPWRAP_PRI_READY); + ftdm_channel_write(spri->dchan, buf, buflen, &len); } else { fprintf(stderr, "Unable to create PRI\n"); diff --git a/libs/freetdm/src/include/freetdm.h b/libs/freetdm/src/include/freetdm.h index a924e3587a..870d9bce11 100644 --- a/libs/freetdm/src/include/freetdm.h +++ b/libs/freetdm/src/include/freetdm.h @@ -198,6 +198,8 @@ extern "C" { #define FTDM_MAX_CHANNELS_GROUP 1024 #define FTDM_MAX_GROUPS_INTERFACE FTDM_MAX_SPANS_INTERFACE +#define FTDM_MAX_NAME_STR_SZ 80 + #define GOTO_STATUS(label,st) status = st; goto label ; #define ftdm_copy_string(x,y,z) strncpy(x, y, z - 1) @@ -611,6 +613,12 @@ struct ftdm_channel { float txgain; }; +struct ftdm_channel_config { + char group_name[FTDM_MAX_NAME_STR_SZ]; + float rxgain; + float txgain; +}; + struct ftdm_sigmsg { ftdm_signal_event_t event_id; @@ -831,6 +839,9 @@ FT_DECLARE(ftdm_status_t) ftdm_conf_node_create(const char *name, ftdm_conf_node FT_DECLARE(ftdm_status_t) ftdm_conf_node_add_param(ftdm_conf_node_t *node, const char *param, const char *val); FT_DECLARE(ftdm_status_t) ftdm_conf_node_destroy(ftdm_conf_node_t *node); + +FT_DECLARE(ftdm_status_t) ftdm_configure_span_channels(ftdm_span_t *span, int currindex, ftdm_channel_config_t *chan_config); + FIO_CODEC_FUNCTION(fio_slin2ulaw); FIO_CODEC_FUNCTION(fio_ulaw2slin); FIO_CODEC_FUNCTION(fio_slin2alaw); diff --git a/libs/freetdm/src/include/ftdm_types.h b/libs/freetdm/src/include/ftdm_types.h index 938f61805d..3230d3c66f 100644 --- a/libs/freetdm/src/include/ftdm_types.h +++ b/libs/freetdm/src/include/ftdm_types.h @@ -468,6 +468,7 @@ typedef struct ftdm_conf_parameter_s { } ftdm_conf_parameter_t; typedef struct ftdm_channel ftdm_channel_t; +typedef struct ftdm_channel_config ftdm_channel_config_t; typedef struct ftdm_event ftdm_event_t; typedef struct ftdm_sigmsg ftdm_sigmsg_t; typedef struct ftdm_span ftdm_span_t;