freetdm: fix incorrect alarm reporting due to Wanpipe bug

proper alarm handling for R2 calls
This commit is contained in:
Moises Silva 2011-01-14 18:43:42 -05:00
parent 771caca78d
commit 04d5652819
5 changed files with 89 additions and 44 deletions

View File

@ -3763,9 +3763,7 @@ SWITCH_STANDARD_API(ft_function)
flags = "call swap";
}
fchan = ftdm_span_get_channel(SPAN_CONFIG[j].span, 1);
if (fchan) {
ftdm_channel_get_alarms(fchan, &alarmbits);
}
ftdm_channel_get_alarms(fchan, &alarmbits);
if ((FTDM_SUCCESS == ftdm_span_get_sig_status(SPAN_CONFIG[j].span, &sigstatus))) {
stream->write_function(stream,

View File

@ -682,43 +682,54 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_get_alarms(ftdm_channel_t *ftdmchan, ftdm
{
ftdm_status_t status = FTDM_FAIL;
ftdm_assert_return(alarmbits != NULL, FTDM_FAIL, "null argument\n");
ftdm_assert_return(alarmbits != NULL, FTDM_EINVAL, "null alarmbits argument\n");
ftdm_assert_return(ftdmchan != NULL, FTDM_EINVAL, "null channel argument\n");
ftdm_assert_return(ftdmchan->span != NULL, FTDM_EINVAL, "null span\n");
ftdm_assert_return(ftdmchan->span->fio != NULL, FTDM_EINVAL, "null io\n");
*alarmbits = FTDM_ALARM_NONE;
if (!ftdmchan->span->fio->get_alarms) {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "No get_alarms interface for this channel\n");
return FTDM_ENOSYS;
}
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_CONFIGURED)) {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Cannot get alarms from an unconfigured channel\n");
return FTDM_EINVAL;
}
ftdm_channel_lock(ftdmchan);
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_CONFIGURED)) {
if (ftdmchan->span->fio->get_alarms) {
if ((status = ftdmchan->span->fio->get_alarms(ftdmchan)) == FTDM_SUCCESS) {
*ftdmchan->last_error = '\0';
*alarmbits = ftdmchan->alarm_flags;
if (ftdm_test_alarm_flag(ftdmchan, FTDM_ALARM_RED)) {
snprintf(ftdmchan->last_error + strlen(ftdmchan->last_error), sizeof(ftdmchan->last_error) - strlen(ftdmchan->last_error), "RED/");
}
if (ftdm_test_alarm_flag(ftdmchan, FTDM_ALARM_YELLOW)) {
snprintf(ftdmchan->last_error + strlen(ftdmchan->last_error), sizeof(ftdmchan->last_error) - strlen(ftdmchan->last_error), "YELLOW/");
}
if (ftdm_test_alarm_flag(ftdmchan, FTDM_ALARM_RAI)) {
snprintf(ftdmchan->last_error + strlen(ftdmchan->last_error), sizeof(ftdmchan->last_error) - strlen(ftdmchan->last_error), "RAI/");
}
if (ftdm_test_alarm_flag(ftdmchan, FTDM_ALARM_BLUE)) {
snprintf(ftdmchan->last_error + strlen(ftdmchan->last_error), sizeof(ftdmchan->last_error) - strlen(ftdmchan->last_error), "BLUE/");
}
if (ftdm_test_alarm_flag(ftdmchan, FTDM_ALARM_AIS)) {
snprintf(ftdmchan->last_error + strlen(ftdmchan->last_error), sizeof(ftdmchan->last_error) - strlen(ftdmchan->last_error), "AIS/");
}
if (ftdm_test_alarm_flag(ftdmchan, FTDM_ALARM_GENERAL)) {
snprintf(ftdmchan->last_error + strlen(ftdmchan->last_error), sizeof(ftdmchan->last_error) - strlen(ftdmchan->last_error), "GENERAL");
}
*(ftdmchan->last_error + strlen(ftdmchan->last_error) - 1) = '\0';
}
} else {
status = FTDM_NOTIMPL;
}
if ((status = ftdmchan->span->fio->get_alarms(ftdmchan)) != FTDM_SUCCESS) {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to get alarms from channel\n");
goto done;
}
*ftdmchan->last_error = '\0';
*alarmbits = ftdmchan->alarm_flags;
if (ftdm_test_alarm_flag(ftdmchan, FTDM_ALARM_RED)) {
snprintf(ftdmchan->last_error + strlen(ftdmchan->last_error), sizeof(ftdmchan->last_error) - strlen(ftdmchan->last_error), "RED/");
}
if (ftdm_test_alarm_flag(ftdmchan, FTDM_ALARM_YELLOW)) {
snprintf(ftdmchan->last_error + strlen(ftdmchan->last_error), sizeof(ftdmchan->last_error) - strlen(ftdmchan->last_error), "YELLOW/");
}
if (ftdm_test_alarm_flag(ftdmchan, FTDM_ALARM_RAI)) {
snprintf(ftdmchan->last_error + strlen(ftdmchan->last_error), sizeof(ftdmchan->last_error) - strlen(ftdmchan->last_error), "RAI/");
}
if (ftdm_test_alarm_flag(ftdmchan, FTDM_ALARM_BLUE)) {
snprintf(ftdmchan->last_error + strlen(ftdmchan->last_error), sizeof(ftdmchan->last_error) - strlen(ftdmchan->last_error), "BLUE/");
}
if (ftdm_test_alarm_flag(ftdmchan, FTDM_ALARM_AIS)) {
snprintf(ftdmchan->last_error + strlen(ftdmchan->last_error), sizeof(ftdmchan->last_error) - strlen(ftdmchan->last_error), "AIS/");
}
if (ftdm_test_alarm_flag(ftdmchan, FTDM_ALARM_GENERAL)) {
snprintf(ftdmchan->last_error + strlen(ftdmchan->last_error), sizeof(ftdmchan->last_error) - strlen(ftdmchan->last_error), "GENERAL");
}
*(ftdmchan->last_error + strlen(ftdmchan->last_error) - 1) = '\0';
done:
ftdm_channel_unlock(ftdmchan);
return status;

View File

@ -820,8 +820,14 @@ static void ftdm_r2_on_call_read(openr2_chan_t *r2chan, const unsigned char *buf
static void ftdm_r2_on_hardware_alarm(openr2_chan_t *r2chan, int alarm)
{
ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan);
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Alarm notification: %d\n", alarm);
ftdm_channel_t *fchan = openr2_chan_get_client_data(r2chan);
ftdm_log_chan(fchan, FTDM_LOG_DEBUG, "Alarm notification %d when in state %s (sigstatus = %d)\n",
alarm, ftdm_channel_state2str(fchan->state), ftdm_test_flag(fchan, FTDM_CHANNEL_SIG_UP) ? 1 : 0);
if (alarm && ftdm_test_flag(fchan, FTDM_CHANNEL_SIG_UP)) {
ftdm_r2_set_chan_sig_status(fchan, FTDM_SIG_STATE_DOWN);
}
}
static void ftdm_r2_on_os_error(openr2_chan_t *r2chan, int errorcode)
@ -875,14 +881,18 @@ static void ftdm_r2_on_line_blocked(openr2_chan_t *r2chan)
{
ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan);
ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Far end blocked in state %s\n", ftdm_channel_state2str(ftdmchan->state));
ftdm_r2_set_chan_sig_status(ftdmchan, FTDM_SIG_STATE_SUSPENDED);
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) {
ftdm_r2_set_chan_sig_status(ftdmchan, FTDM_SIG_STATE_SUSPENDED);
}
}
static void ftdm_r2_on_line_idle(openr2_chan_t *r2chan)
{
ftdm_channel_t *ftdmchan = openr2_chan_get_client_data(r2chan);
ftdm_log_chan(ftdmchan, FTDM_LOG_NOTICE, "Far end unblocked in state %s\n", ftdm_channel_state2str(ftdmchan->state));
ftdm_r2_set_chan_sig_status(ftdmchan, FTDM_SIG_STATE_UP);
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP)) {
ftdm_r2_set_chan_sig_status(ftdmchan, FTDM_SIG_STATE_UP);
}
}
static void ftdm_r2_write_log(openr2_log_level_t level, const char *file, const char *function, int line, const char *message)
@ -914,7 +924,7 @@ static void ftdm_r2_write_log(openr2_log_level_t level, const char *file, const
static void ftdm_r2_on_context_log(openr2_context_t *r2context, const char *file, const char *function, unsigned int line,
openr2_log_level_t level, const char *fmt, va_list ap)
{
#define CONTEXT_TAG "Context -"
#define CONTEXT_TAG "Context - "
char logmsg[256];
char completemsg[sizeof(logmsg) + sizeof(CONTEXT_TAG) - 1];
vsnprintf(logmsg, sizeof(logmsg), fmt, ap);
@ -1191,6 +1201,14 @@ static int ftdm_r2_io_get_oob_event(openr2_chan_t *r2chan, openr2_oob_event_t *e
return 0;
}
static int ftdm_r2_io_get_alarm_state(openr2_chan_t *r2chan, int *alarm)
{
ftdm_channel_t *fchan = openr2_chan_get_fd(r2chan);
ftdm_assert_return(alarm, -1, "Alarm pointer is null\n");
*alarm = ftdm_test_flag(fchan, FTDM_CHANNEL_IN_ALARM) ? 1 : 0;
return 0;
}
static openr2_io_interface_t ftdm_r2_io_iface = {
/* .open */ ftdm_r2_io_open, /* never called */
/* .close */ ftdm_r2_io_close, /* never called */
@ -1201,7 +1219,8 @@ static openr2_io_interface_t ftdm_r2_io_iface = {
/* .read */ ftdm_r2_io_read,
/* .setup */ ftdm_r2_io_setup, /* never called */
/* .wait */ ftdm_r2_io_wait,
/* .get_oob_event */ ftdm_r2_io_get_oob_event /* never called */
/* .get_oob_event */ ftdm_r2_io_get_oob_event,
/* .get_alarm_state */ ftdm_r2_io_get_alarm_state
};
/* resolve a loglevel string, such as "debug,notice,warning", to an openr2 log level integer */

View File

@ -1179,7 +1179,7 @@ static FIO_GET_ALARMS_FUNCTION(wanpipe_get_alarms)
unsigned int alarms = 0;
int err;
memset(&tdm_api,0,sizeof(tdm_api));
memset(&tdm_api, 0, sizeof(tdm_api));
#ifdef LIBSANGOMA_VERSION
if ((err = sangoma_tdm_get_fe_alarms(ftdmchan->sockfd, &tdm_api, &alarms))) {
@ -1225,9 +1225,19 @@ static FIO_GET_ALARMS_FUNCTION(wanpipe_get_alarms)
alarms &= ~WAN_TE_BIT_ALARM_RAI;
}
if (!ftdmchan->alarm_flags) {
if (FTDM_IS_DIGITAL_CHANNEL(ftdmchan)) {
ftdm_channel_hw_link_status_t sangoma_status = 0;
/* there is a bug in wanpipe where alarms were not properly set when they should be
* on at application startup, until that is fixed we check the link status here too */
ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_LINK_STATUS, &sangoma_status);
ftdmchan->alarm_flags = sangoma_status == FTDM_HW_LINK_DISCONNECTED ? 1 : 0;
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Link status is %d\n", sangoma_status);
}
}
if (alarms) {
/* FIXME: investigate what else does the driver report */
ftdm_log(FTDM_LOG_DEBUG, "Unmapped wanpipe alarms: %d\n", alarms);
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Unmapped wanpipe alarms: %d\n", alarms);
}
return FTDM_SUCCESS;

View File

@ -168,10 +168,17 @@ typedef enum {
FTDM_STR2ENUM_P(ftdm_str2ftdm_chan_type, ftdm_chan_type2str, ftdm_chan_type_t)
/*! \brief Test if a channel is a voice channel */
#define FTDM_IS_VOICE_CHANNEL(ftdm_chan) ((ftdm_chan)->type != FTDM_CHAN_TYPE_DQ921 && (ftdm_chan)->type != FTDM_CHAN_TYPE_DQ931)
#define FTDM_IS_VOICE_CHANNEL(fchan) ((fchan)->type != FTDM_CHAN_TYPE_DQ921 && (fchan)->type != FTDM_CHAN_TYPE_DQ931)
/*! \brief Test if a channel is a D-channel */
#define FTDM_IS_DCHAN(ftdm_chan) ((ftdm_chan)->type == FTDM_CHAN_TYPE_DQ921 || (ftdm_chan)->type == FTDM_CHAN_TYPE_DQ931)
#define FTDM_IS_DCHAN(ftdm_chan) ((fchan)->type == FTDM_CHAN_TYPE_DQ921 || (fchan)->type == FTDM_CHAN_TYPE_DQ931)
/*! \brief Test if a channel is digital channel */
#define FTDM_IS_DIGITAL_CHANNEL(fchan) ((fchan)->span->trunk_type == FTDM_TRUNK_E1 || \
(fchan)->span->trunk_type == FTDM_TRUNK_T1 || \
(fchan)->span->trunk_type == FTDM_TRUNK_J1 || \
(fchan)->span->trunk_type == FTDM_TRUNK_BRI || \
(fchan)->span->trunk_type == FTDM_TRUNK_BRI_PTMP)
/*! \brief Logging function prototype to be used for all FreeTDM logs
* you should use ftdm_global_set_logger to set your own logger