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;
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;
}
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";
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;
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");
}
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");
}
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");
}
} 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);
}
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;
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
*/
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;
}
* \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;
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);