FreeTDM: Add trunk mode (NET/CPE) to span configuration in freetdm.conf and use it in ftmod_misdn and ftmod_libpri.
Some I/O implementations (e.g. mISDN) need this information to correctly set up the port configuration. In FreeTDM, the mode of a span has been. up until now, a part of the signalling module configuration ("node" or "mode" for libpri and isdn spans), which is parsed _after_ the I/O part of a span has been initialized. This limitation currently prevents us from using mISDN in NT mode. To work around this problem (without adding a lot of new tunk_type values like "E1_NET" etc.), add a new "trunk_mode" parameter to the span categories in freetdm.conf, which by default is "CPE" for all trunk types, except "FXS" (which defaults to "NET"). ftmod_misdn uses trunk_type + trunk_mode to correctly choose the d-channel protocol for a port. ftmod_libpri uses trunk_mode as a hint for the default "mode" setting. (NOTE: It will print a warning if trunk_mode and signalling mode do not match.) All other modules currently ignore the value of trunk_mode. Example freetdm.conf snippet for a mISDN span in NET/NT mode (using a HFC-S USB dongle): [span misdn MBRI_1] trunk_type => BRI_PTMP trunk_mode => NET b-channel => HFC-S_USB.1:1-2 d-channel => HFC-S_USB.1:3 Signed-off-by: Stefan Knoblich <stkn@openisdn.net>
This commit is contained in:
parent
61cfafe6c2
commit
7a12804577
|
@ -262,9 +262,12 @@ FTDM_STR2ENUM(ftdm_str2ftdm_tonemap, ftdm_tonemap2str, ftdm_tonemap_t, TONEMAP_N
|
||||||
FTDM_ENUM_NAMES(OOB_NAMES, OOB_STRINGS)
|
FTDM_ENUM_NAMES(OOB_NAMES, OOB_STRINGS)
|
||||||
FTDM_STR2ENUM(ftdm_str2ftdm_oob_event, ftdm_oob_event2str, ftdm_oob_event_t, OOB_NAMES, FTDM_OOB_INVALID)
|
FTDM_STR2ENUM(ftdm_str2ftdm_oob_event, ftdm_oob_event2str, ftdm_oob_event_t, OOB_NAMES, FTDM_OOB_INVALID)
|
||||||
|
|
||||||
FTDM_ENUM_NAMES(TRUNK_TYPE_NAMES, TRUNK_STRINGS)
|
FTDM_ENUM_NAMES(TRUNK_TYPE_NAMES, TRUNK_TYPE_STRINGS)
|
||||||
FTDM_STR2ENUM(ftdm_str2ftdm_trunk_type, ftdm_trunk_type2str, ftdm_trunk_type_t, TRUNK_TYPE_NAMES, FTDM_TRUNK_NONE)
|
FTDM_STR2ENUM(ftdm_str2ftdm_trunk_type, ftdm_trunk_type2str, ftdm_trunk_type_t, TRUNK_TYPE_NAMES, FTDM_TRUNK_NONE)
|
||||||
|
|
||||||
|
FTDM_ENUM_NAMES(TRUNK_MODE_NAMES, TRUNK_MODE_STRINGS)
|
||||||
|
FTDM_STR2ENUM(ftdm_str2ftdm_trunk_mode, ftdm_trunk_mode2str, ftdm_trunk_mode_t, TRUNK_MODE_NAMES, FTDM_TRUNK_MODE_INVALID)
|
||||||
|
|
||||||
FTDM_ENUM_NAMES(START_TYPE_NAMES, START_TYPE_STRINGS)
|
FTDM_ENUM_NAMES(START_TYPE_NAMES, START_TYPE_STRINGS)
|
||||||
FTDM_STR2ENUM(ftdm_str2ftdm_analog_start_type, ftdm_analog_start_type2str, ftdm_analog_start_type_t, START_TYPE_NAMES, FTDM_ANALOG_START_NA)
|
FTDM_STR2ENUM(ftdm_str2ftdm_analog_start_type, ftdm_analog_start_type2str, ftdm_analog_start_type_t, START_TYPE_NAMES, FTDM_ANALOG_START_NA)
|
||||||
|
|
||||||
|
@ -816,6 +819,7 @@ FT_DECLARE(ftdm_status_t) ftdm_span_create(const char *iotype, const char *name,
|
||||||
ftdm_copy_string(new_span->tone_map[FTDM_TONEMAP_BUSY], "%(500,500,480,620)", FTDM_TONEMAP_LEN);
|
ftdm_copy_string(new_span->tone_map[FTDM_TONEMAP_BUSY], "%(500,500,480,620)", FTDM_TONEMAP_LEN);
|
||||||
ftdm_copy_string(new_span->tone_map[FTDM_TONEMAP_ATTN], "%(100,100,1400,2060,2450,2600)", FTDM_TONEMAP_LEN);
|
ftdm_copy_string(new_span->tone_map[FTDM_TONEMAP_ATTN], "%(100,100,1400,2060,2450,2600)", FTDM_TONEMAP_LEN);
|
||||||
new_span->trunk_type = FTDM_TRUNK_NONE;
|
new_span->trunk_type = FTDM_TRUNK_NONE;
|
||||||
|
new_span->trunk_mode = FTDM_TRUNK_MODE_CPE;
|
||||||
new_span->data_type = FTDM_TYPE_SPAN;
|
new_span->data_type = FTDM_TYPE_SPAN;
|
||||||
|
|
||||||
ftdm_mutex_lock(globals.span_mutex);
|
ftdm_mutex_lock(globals.span_mutex);
|
||||||
|
@ -1994,6 +1998,21 @@ FT_DECLARE(const char *) ftdm_span_get_trunk_type_str(const ftdm_span_t *span)
|
||||||
return ftdm_trunk_type2str(span->trunk_type);
|
return ftdm_trunk_type2str(span->trunk_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FT_DECLARE(void) ftdm_span_set_trunk_mode(ftdm_span_t *span, ftdm_trunk_mode_t mode)
|
||||||
|
{
|
||||||
|
span->trunk_mode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
FT_DECLARE(ftdm_trunk_mode_t) ftdm_span_get_trunk_mode(const ftdm_span_t *span)
|
||||||
|
{
|
||||||
|
return span->trunk_mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
FT_DECLARE(const char *) ftdm_span_get_trunk_mode_str(const ftdm_span_t *span)
|
||||||
|
{
|
||||||
|
return ftdm_trunk_mode2str(span->trunk_mode);
|
||||||
|
}
|
||||||
|
|
||||||
FT_DECLARE(uint32_t) ftdm_span_get_id(const ftdm_span_t *span)
|
FT_DECLARE(uint32_t) ftdm_span_get_id(const ftdm_span_t *span)
|
||||||
{
|
{
|
||||||
return span->span_id;
|
return span->span_id;
|
||||||
|
@ -4706,6 +4725,10 @@ static ftdm_status_t load_config(void)
|
||||||
ftdm_trunk_type_t trtype = ftdm_str2ftdm_trunk_type(val);
|
ftdm_trunk_type_t trtype = ftdm_str2ftdm_trunk_type(val);
|
||||||
ftdm_span_set_trunk_type(span, trtype);
|
ftdm_span_set_trunk_type(span, trtype);
|
||||||
ftdm_log(FTDM_LOG_DEBUG, "setting trunk type to '%s'\n", ftdm_trunk_type2str(trtype));
|
ftdm_log(FTDM_LOG_DEBUG, "setting trunk type to '%s'\n", ftdm_trunk_type2str(trtype));
|
||||||
|
} else if (!strcasecmp(var, "trunk_mode")) {
|
||||||
|
ftdm_trunk_mode_t trmode = ftdm_str2ftdm_trunk_mode(val);
|
||||||
|
ftdm_span_set_trunk_mode(span, trmode);
|
||||||
|
ftdm_log(FTDM_LOG_DEBUG, "setting trunk mode to '%s'\n", ftdm_trunk_mode2str(trmode));
|
||||||
} else if (!strcasecmp(var, "name")) {
|
} else if (!strcasecmp(var, "name")) {
|
||||||
if (!strcasecmp(val, "undef")) {
|
if (!strcasecmp(val, "undef")) {
|
||||||
chan_config.name[0] = '\0';
|
chan_config.name[0] = '\0';
|
||||||
|
@ -4730,8 +4753,9 @@ static ftdm_status_t load_config(void)
|
||||||
} else if (!strcasecmp(var, "fxo-channel")) {
|
} else if (!strcasecmp(var, "fxo-channel")) {
|
||||||
if (span->trunk_type == FTDM_TRUNK_NONE) {
|
if (span->trunk_type == FTDM_TRUNK_NONE) {
|
||||||
span->trunk_type = FTDM_TRUNK_FXO;
|
span->trunk_type = FTDM_TRUNK_FXO;
|
||||||
ftdm_log(FTDM_LOG_DEBUG, "setting trunk type to '%s' start(%s)\n", ftdm_trunk_type2str(span->trunk_type),
|
span->trunk_mode = FTDM_TRUNK_MODE_CPE;
|
||||||
ftdm_analog_start_type2str(span->start_type));
|
ftdm_log(FTDM_LOG_DEBUG, "setting trunk type to '%s' start(%s), mode(%s)\n", ftdm_trunk_type2str(span->trunk_type),
|
||||||
|
ftdm_analog_start_type2str(span->start_type), ftdm_trunk_mode2str(span->trunk_mode));
|
||||||
}
|
}
|
||||||
if (span->trunk_type == FTDM_TRUNK_FXO) {
|
if (span->trunk_type == FTDM_TRUNK_FXO) {
|
||||||
unsigned chans_configured = 0;
|
unsigned chans_configured = 0;
|
||||||
|
@ -4745,8 +4769,9 @@ static ftdm_status_t load_config(void)
|
||||||
} else if (!strcasecmp(var, "fxs-channel")) {
|
} else if (!strcasecmp(var, "fxs-channel")) {
|
||||||
if (span->trunk_type == FTDM_TRUNK_NONE) {
|
if (span->trunk_type == FTDM_TRUNK_NONE) {
|
||||||
span->trunk_type = FTDM_TRUNK_FXS;
|
span->trunk_type = FTDM_TRUNK_FXS;
|
||||||
ftdm_log(FTDM_LOG_DEBUG, "setting trunk type to '%s' start(%s)\n", ftdm_trunk_type2str(span->trunk_type),
|
span->trunk_mode = FTDM_TRUNK_MODE_NET;
|
||||||
ftdm_analog_start_type2str(span->start_type));
|
ftdm_log(FTDM_LOG_DEBUG, "setting trunk type to '%s' start(%s), mode(%s)\n", ftdm_trunk_type2str(span->trunk_type),
|
||||||
|
ftdm_analog_start_type2str(span->start_type), ftdm_trunk_mode2str(span->trunk_mode));
|
||||||
}
|
}
|
||||||
if (span->trunk_type == FTDM_TRUNK_FXS) {
|
if (span->trunk_type == FTDM_TRUNK_FXS) {
|
||||||
unsigned chans_configured = 0;
|
unsigned chans_configured = 0;
|
||||||
|
@ -4760,8 +4785,9 @@ static ftdm_status_t load_config(void)
|
||||||
} else if (!strcasecmp(var, "em-channel")) {
|
} else if (!strcasecmp(var, "em-channel")) {
|
||||||
if (span->trunk_type == FTDM_TRUNK_NONE) {
|
if (span->trunk_type == FTDM_TRUNK_NONE) {
|
||||||
span->trunk_type = FTDM_TRUNK_EM;
|
span->trunk_type = FTDM_TRUNK_EM;
|
||||||
ftdm_log(FTDM_LOG_DEBUG, "setting trunk type to '%s' start(%s)\n", ftdm_trunk_type2str(span->trunk_type),
|
span->trunk_mode = FTDM_TRUNK_MODE_CPE;
|
||||||
ftdm_analog_start_type2str(span->start_type));
|
ftdm_log(FTDM_LOG_DEBUG, "setting trunk type to '%s' start(%s), mode(%s)\n", ftdm_trunk_type2str(span->trunk_type),
|
||||||
|
ftdm_analog_start_type2str(span->start_type), ftdm_trunk_mode2str(span->trunk_mode));
|
||||||
}
|
}
|
||||||
if (span->trunk_type == FTDM_TRUNK_EM) {
|
if (span->trunk_type == FTDM_TRUNK_EM) {
|
||||||
unsigned chans_configured = 0;
|
unsigned chans_configured = 0;
|
||||||
|
|
|
@ -2462,9 +2462,15 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_libpri_configure_span)
|
||||||
memset(isdn_data, 0, sizeof(*isdn_data));
|
memset(isdn_data, 0, sizeof(*isdn_data));
|
||||||
|
|
||||||
/* set some default values */
|
/* set some default values */
|
||||||
isdn_data->mode = PRI_CPE;
|
|
||||||
isdn_data->ton = PRI_UNKNOWN;
|
isdn_data->ton = PRI_UNKNOWN;
|
||||||
|
|
||||||
|
/* Use span's trunk_mode as a reference for the default libpri mode */
|
||||||
|
if (ftdm_span_get_trunk_mode(span) == FTDM_TRUNK_MODE_NET) {
|
||||||
|
isdn_data->mode = PRI_NETWORK;
|
||||||
|
} else {
|
||||||
|
isdn_data->mode = PRI_CPE;
|
||||||
|
}
|
||||||
|
|
||||||
switch (ftdm_span_get_trunk_type(span)) {
|
switch (ftdm_span_get_trunk_type(span)) {
|
||||||
case FTDM_TRUNK_BRI:
|
case FTDM_TRUNK_BRI:
|
||||||
case FTDM_TRUNK_BRI_PTMP:
|
case FTDM_TRUNK_BRI_PTMP:
|
||||||
|
@ -2516,8 +2522,8 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_libpri_configure_span)
|
||||||
|
|
||||||
if (!strcasecmp(var, "node") || !strcasecmp(var, "mode")) {
|
if (!strcasecmp(var, "node") || !strcasecmp(var, "mode")) {
|
||||||
if ((isdn_data->mode = parse_mode(val)) == -1) {
|
if ((isdn_data->mode = parse_mode(val)) == -1) {
|
||||||
ftdm_log(FTDM_LOG_ERROR, "Unknown node type '%s', defaulting to CPE mode\n", val);
|
ftdm_log(FTDM_LOG_ERROR, "Unknown node type '%s'\n", val);
|
||||||
isdn_data->mode = PRI_CPE;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!strcasecmp(var, "switch") || !strcasecmp(var, "dialect")) {
|
else if (!strcasecmp(var, "switch") || !strcasecmp(var, "dialect")) {
|
||||||
|
@ -2563,6 +2569,16 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_libpri_configure_span)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if modes match and log a message if they do not. Just to be on the safe side. */
|
||||||
|
if (isdn_data->mode == PRI_CPE && ftdm_span_get_trunk_mode(span) == FTDM_TRUNK_MODE_NET) {
|
||||||
|
ftdm_log(FTDM_LOG_WARNING, "Span '%s' signalling set up for TE/CPE/USER mode, while port is running in NT/NET mode. You may want to check your 'trunk_mode' settings.\n",
|
||||||
|
ftdm_span_get_name(span));
|
||||||
|
}
|
||||||
|
else if (isdn_data->mode == PRI_NETWORK && ftdm_span_get_trunk_mode(span) == FTDM_TRUNK_MODE_CPE) {
|
||||||
|
ftdm_log(FTDM_LOG_WARNING, "Span '%s' signalling set up for NT/NET mode, while port is running in TE/CPE/USER mode. You may want to check your 'trunk_mode' settings.\n",
|
||||||
|
ftdm_span_get_name(span));
|
||||||
|
}
|
||||||
|
|
||||||
span->start = ftdm_libpri_start;
|
span->start = ftdm_libpri_start;
|
||||||
span->stop = ftdm_libpri_stop;
|
span->stop = ftdm_libpri_stop;
|
||||||
span->signal_cb = sig_cb;
|
span->signal_cb = sig_cb;
|
||||||
|
|
|
@ -1432,12 +1432,12 @@ static ftdm_status_t misdn_open_range(ftdm_span_t *span, ftdm_chan_type_t type,
|
||||||
|
|
||||||
switch (ftdm_span_get_trunk_type(span)) {
|
switch (ftdm_span_get_trunk_type(span)) {
|
||||||
case FTDM_TRUNK_E1:
|
case FTDM_TRUNK_E1:
|
||||||
d_protocol = ISDN_P_TE_E1;
|
d_protocol = ftdm_span_get_trunk_mode(span) == FTDM_TRUNK_MODE_NET ? ISDN_P_NT_E1 : ISDN_P_TE_E1;
|
||||||
d_channel = 16;
|
d_channel = 16;
|
||||||
break;
|
break;
|
||||||
case FTDM_TRUNK_BRI:
|
case FTDM_TRUNK_BRI:
|
||||||
case FTDM_TRUNK_BRI_PTMP:
|
case FTDM_TRUNK_BRI_PTMP:
|
||||||
d_protocol = ISDN_P_TE_S0;
|
d_protocol = ftdm_span_get_trunk_mode(span) == FTDM_TRUNK_MODE_NET ? ISDN_P_NT_S0 : ISDN_P_TE_S0;
|
||||||
d_channel = 0;
|
d_channel = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -484,11 +484,23 @@ typedef enum {
|
||||||
FTDM_TRUNK_GSM,
|
FTDM_TRUNK_GSM,
|
||||||
FTDM_TRUNK_NONE
|
FTDM_TRUNK_NONE
|
||||||
} ftdm_trunk_type_t;
|
} ftdm_trunk_type_t;
|
||||||
#define TRUNK_STRINGS "E1", "T1", "J1", "BRI", "BRI_PTMP", "FXO", "FXS", "EM", "GSM", "NONE"
|
#define TRUNK_TYPE_STRINGS "E1", "T1", "J1", "BRI", "BRI_PTMP", "FXO", "FXS", "EM", "GSM", "NONE"
|
||||||
|
|
||||||
/*! \brief Move from string to ftdm_trunk_type_t and viceversa */
|
/*! \brief Move from string to ftdm_trunk_type_t and viceversa */
|
||||||
FTDM_STR2ENUM_P(ftdm_str2ftdm_trunk_type, ftdm_trunk_type2str, ftdm_trunk_type_t)
|
FTDM_STR2ENUM_P(ftdm_str2ftdm_trunk_type, ftdm_trunk_type2str, ftdm_trunk_type_t)
|
||||||
|
|
||||||
|
/*! \brief Span trunk modes */
|
||||||
|
typedef enum {
|
||||||
|
FTDM_TRUNK_MODE_CPE,
|
||||||
|
FTDM_TRUNK_MODE_NET,
|
||||||
|
FTDM_TRUNK_MODE_INVALID
|
||||||
|
} ftdm_trunk_mode_t;
|
||||||
|
#define TRUNK_MODE_STRINGS "CPE", "NET", "INVALID"
|
||||||
|
|
||||||
|
/*! \brief Move from string to ftdm_trunk_mode_t and viceversa */
|
||||||
|
FTDM_STR2ENUM_P(ftdm_str2ftdm_trunk_mode, ftdm_trunk_mode2str, ftdm_trunk_mode_t)
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Basic channel configuration provided to ftdm_configure_span_channels */
|
/*! \brief Basic channel configuration provided to ftdm_configure_span_channels */
|
||||||
typedef struct ftdm_channel_config {
|
typedef struct ftdm_channel_config {
|
||||||
char name[FTDM_MAX_NAME_STR_SZ];
|
char name[FTDM_MAX_NAME_STR_SZ];
|
||||||
|
@ -1744,6 +1756,28 @@ FT_DECLARE(ftdm_trunk_type_t) ftdm_span_get_trunk_type(const ftdm_span_t *span);
|
||||||
/*! \brief For display debugging purposes you can display this string which describes the trunk type of a span */
|
/*! \brief For display debugging purposes you can display this string which describes the trunk type of a span */
|
||||||
FT_DECLARE(const char *) ftdm_span_get_trunk_type_str(const ftdm_span_t *span);
|
FT_DECLARE(const char *) ftdm_span_get_trunk_type_str(const ftdm_span_t *span);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Set the trunk mode for a span
|
||||||
|
* \note This must be called before configuring any channels within the span!
|
||||||
|
* \param[in] span The span
|
||||||
|
* \param[in] type The trunk mode
|
||||||
|
*/
|
||||||
|
FT_DECLARE(void) ftdm_span_set_trunk_mode(ftdm_span_t *span, ftdm_trunk_mode_t mode);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Get the trunk mode for a span
|
||||||
|
* \param[in] span The span
|
||||||
|
* \return Span trunk mode
|
||||||
|
*/
|
||||||
|
FT_DECLARE(ftdm_trunk_mode_t) ftdm_span_get_trunk_mode(const ftdm_span_t *span);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Get the trunk mode of a span in textual form
|
||||||
|
* \param[in] span The span
|
||||||
|
* \return Span mode name as a string
|
||||||
|
*/
|
||||||
|
FT_DECLARE(const char *) ftdm_span_get_trunk_mode_str(const ftdm_span_t *span);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Return the channel identified by the provided id
|
* \brief Return the channel identified by the provided id
|
||||||
*
|
*
|
||||||
|
|
|
@ -485,6 +485,7 @@ struct ftdm_span {
|
||||||
fio_event_cb_t event_callback;
|
fio_event_cb_t event_callback;
|
||||||
ftdm_mutex_t *mutex;
|
ftdm_mutex_t *mutex;
|
||||||
ftdm_trunk_type_t trunk_type;
|
ftdm_trunk_type_t trunk_type;
|
||||||
|
ftdm_trunk_mode_t trunk_mode;
|
||||||
ftdm_analog_start_type_t start_type;
|
ftdm_analog_start_type_t start_type;
|
||||||
ftdm_signal_type_t signal_type;
|
ftdm_signal_type_t signal_type;
|
||||||
uint32_t last_used_index;
|
uint32_t last_used_index;
|
||||||
|
|
Loading…
Reference in New Issue