Add ability to ignore layer 1 alarms for BRI PTMP lines.

Several telcos bring the BRI PTMP layer 1 down when the line is idle.
When layer 1 goes down, Asterisk cannot make outgoing calls.  Incoming
calls could fail as well because the alarm processing is handled by a
different code path than the Q.931 messages.

* Add the layer1_presence configuration option to ignore layer 1 alarms
when the telco brings layer 1 down.  This option can be configured by span
while the similar DAHDI driver teignorered=1 option is system wide.  This
option unlike layer2_persistence does not require libpri v1.4.13 or newer.

Related to JIRA AST-598

JIRA ABE-2845
........

Merged revisions 362428 from http://svn.asterisk.org/svn/asterisk/branches/1.8


git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/10@362429 65c4cc65-6c06-0410-ace0-fbb531ad65f3
10
Richard Mudgett 13 years ago
parent 67752759c2
commit 4a95d80ab0

@ -3132,8 +3132,19 @@ static void my_handle_dchan_exception(struct sig_pri_span *pri, int index)
int x; int x;
ioctl(pri->fds[index], DAHDI_GETEVENT, &x); ioctl(pri->fds[index], DAHDI_GETEVENT, &x);
if (x) { switch (x) {
ast_log(LOG_NOTICE, "PRI got event: %s (%d) on D-channel of span %d\n", event2str(x), x, pri->span); case DAHDI_EVENT_NONE:
break;
case DAHDI_EVENT_ALARM:
case DAHDI_EVENT_NOALARM:
if (sig_pri_is_alarm_ignored(pri)) {
break;
}
/* Fall through */
default:
ast_log(LOG_NOTICE, "PRI got event: %s (%d) on D-channel of span %d\n",
event2str(x), x, pri->span);
break;
} }
/* Keep track of alarm state */ /* Keep track of alarm state */
switch (x) { switch (x) {
@ -3823,6 +3834,12 @@ static void dahdi_queue_frame(struct dahdi_pvt *p, struct ast_frame *f)
static void handle_clear_alarms(struct dahdi_pvt *p) static void handle_clear_alarms(struct dahdi_pvt *p)
{ {
#if defined(HAVE_PRI)
if (dahdi_sig_pri_lib_handles(p->sig) && sig_pri_is_alarm_ignored(p->pri)) {
return;
}
#endif /* defined(HAVE_PRI) */
if (report_alarms & REPORT_CHANNEL_ALARMS) { if (report_alarms & REPORT_CHANNEL_ALARMS) {
ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel); ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel);
manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", "Channel: %d\r\n", p->channel); manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", "Channel: %d\r\n", p->channel);
@ -7893,8 +7910,15 @@ static void dahdi_handle_dtmf(struct ast_channel *ast, int idx, struct ast_frame
static void handle_alarms(struct dahdi_pvt *p, int alms) static void handle_alarms(struct dahdi_pvt *p, int alms)
{ {
const char *alarm_str = alarm2str(alms); const char *alarm_str;
#if defined(HAVE_PRI)
if (dahdi_sig_pri_lib_handles(p->sig) && sig_pri_is_alarm_ignored(p->pri)) {
return;
}
#endif /* defined(HAVE_PRI) */
alarm_str = alarm2str(alms);
if (report_alarms & REPORT_CHANNEL_ALARMS) { if (report_alarms & REPORT_CHANNEL_ALARMS) {
ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", p->channel, alarm_str); ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", p->channel, alarm_str);
manager_event(EVENT_FLAG_SYSTEM, "Alarm", manager_event(EVENT_FLAG_SYSTEM, "Alarm",
@ -12670,6 +12694,12 @@ static struct dahdi_pvt *mkintf(int channel, const struct dahdi_chan_conf *conf,
pris[span].pri.aoc_passthrough_flag = conf->pri.pri.aoc_passthrough_flag; pris[span].pri.aoc_passthrough_flag = conf->pri.pri.aoc_passthrough_flag;
pris[span].pri.aoce_delayhangup = conf->pri.pri.aoce_delayhangup; pris[span].pri.aoce_delayhangup = conf->pri.pri.aoce_delayhangup;
#endif /* defined(HAVE_PRI_AOC_EVENTS) */ #endif /* defined(HAVE_PRI_AOC_EVENTS) */
if (chan_sig == SIG_BRI_PTMP) {
pris[span].pri.layer1_ignored = conf->pri.pri.layer1_ignored;
} else {
/* Option does not apply to this line type. */
pris[span].pri.layer1_ignored = 0;
}
pris[span].pri.append_msn_to_user_tag = conf->pri.pri.append_msn_to_user_tag; pris[span].pri.append_msn_to_user_tag = conf->pri.pri.append_msn_to_user_tag;
ast_copy_string(pris[span].pri.initial_user_tag, conf->chan.cid_tag, sizeof(pris[span].pri.initial_user_tag)); ast_copy_string(pris[span].pri.initial_user_tag, conf->chan.cid_tag, sizeof(pris[span].pri.initial_user_tag));
ast_copy_string(pris[span].pri.msn_list, conf->pri.pri.msn_list, sizeof(pris[span].pri.msn_list)); ast_copy_string(pris[span].pri.msn_list, conf->pri.pri.msn_list, sizeof(pris[span].pri.msn_list));
@ -17921,6 +17951,15 @@ static int process_dahdi(struct dahdi_chan_conf *confp, const char *cat, struct
} else if (!strcasecmp(v->name, "datetime_send")) { } else if (!strcasecmp(v->name, "datetime_send")) {
confp->pri.pri.datetime_send = dahdi_datetime_send_option(v->value); confp->pri.pri.datetime_send = dahdi_datetime_send_option(v->value);
#endif /* defined(HAVE_PRI_DATETIME_SEND) */ #endif /* defined(HAVE_PRI_DATETIME_SEND) */
} else if (!strcasecmp(v->name, "layer1_presence")) {
if (!strcasecmp(v->value, "required")) {
confp->pri.pri.layer1_ignored = 0;
} else if (!strcasecmp(v->value, "ignore")) {
confp->pri.pri.layer1_ignored = 1;
} else {
/* Default */
confp->pri.pri.layer1_ignored = 0;
}
#if defined(HAVE_PRI_L2_PERSISTENCE) #if defined(HAVE_PRI_L2_PERSISTENCE)
} else if (!strcasecmp(v->name, "layer2_persistence")) { } else if (!strcasecmp(v->name, "layer2_persistence")) {
if (!strcasecmp(v->value, "keep_up")) { if (!strcasecmp(v->value, "keep_up")) {

@ -190,6 +190,11 @@ static void sig_pri_set_outgoing(struct sig_pri_chan *p, int is_outgoing)
void sig_pri_set_alarm(struct sig_pri_chan *p, int in_alarm) void sig_pri_set_alarm(struct sig_pri_chan *p, int in_alarm)
{ {
if (sig_pri_is_alarm_ignored(p->pri)) {
/* Always set not in alarm */
in_alarm = 0;
}
/* /*
* Clear the channel restart flag when the channel alarm changes * Clear the channel restart flag when the channel alarm changes
* to prevent the flag from getting stuck when the link goes * to prevent the flag from getting stuck when the link goes
@ -8809,6 +8814,18 @@ void sig_pri_chan_alarm_notify(struct sig_pri_chan *p, int noalarm)
pri_rel(p->pri); pri_rel(p->pri);
} }
/*!
* \brief Determine if layer 1 alarms are ignored.
*
* \param p Channel private pointer.
*
* \return TRUE if the alarm is ignored.
*/
int sig_pri_is_alarm_ignored(struct sig_pri_span *pri)
{
return pri->layer1_ignored;
}
struct sig_pri_chan *sig_pri_chan_new(void *pvt_data, struct sig_pri_callback *callback, struct sig_pri_span *pri, int logicalspan, int channo, int trunkgroup) struct sig_pri_chan *sig_pri_chan_new(void *pvt_data, struct sig_pri_callback *callback, struct sig_pri_span *pri, int logicalspan, int channo, int trunkgroup)
{ {
struct sig_pri_chan *p; struct sig_pri_chan *p;

@ -442,6 +442,8 @@ struct sig_pri_span {
/*! \brief TRUE if we will allow incoming ISDN call waiting calls. */ /*! \brief TRUE if we will allow incoming ISDN call waiting calls. */
unsigned int allow_call_waiting_calls:1; unsigned int allow_call_waiting_calls:1;
#endif /* defined(HAVE_PRI_CALL_WAITING) */ #endif /* defined(HAVE_PRI_CALL_WAITING) */
/*! TRUE if layer 1 alarm status is ignored */
unsigned int layer1_ignored:1;
/*! /*!
* TRUE if a new call's sig_pri_chan.user_tag[] has the MSN * TRUE if a new call's sig_pri_chan.user_tag[] has the MSN
* appended to the initial_user_tag[]. * appended to the initial_user_tag[].
@ -619,8 +621,8 @@ int sig_pri_start_pri(struct sig_pri_span *pri);
void sig_pri_set_alarm(struct sig_pri_chan *p, int in_alarm); void sig_pri_set_alarm(struct sig_pri_chan *p, int in_alarm);
void sig_pri_chan_alarm_notify(struct sig_pri_chan *p, int noalarm); void sig_pri_chan_alarm_notify(struct sig_pri_chan *p, int noalarm);
int sig_pri_is_alarm_ignored(struct sig_pri_span *pri);
void pri_event_alarm(struct sig_pri_span *pri, int index, int before_start_pri); void pri_event_alarm(struct sig_pri_span *pri, int index, int before_start_pri);
void pri_event_noalarm(struct sig_pri_span *pri, int index, int before_start_pri); void pri_event_noalarm(struct sig_pri_span *pri, int index, int before_start_pri);
struct ast_channel *sig_pri_request(struct sig_pri_chan *p, enum sig_pri_law law, const struct ast_channel *requestor, int transfercapability); struct ast_channel *sig_pri_request(struct sig_pri_chan *p, enum sig_pri_law law, const struct ast_channel *requestor, int transfercapability);

@ -259,6 +259,18 @@
; The default is no. ; The default is no.
;hold_disconnect_transfer=yes ;hold_disconnect_transfer=yes
; BRI PTMP layer 1 presence.
; You should normally not need to set this option.
; You may need to set this option if your telco brings layer 1 down when
; the line is idle.
; required: Layer 1 presence required for outgoing calls. (default)
; ignore: Ignore alarms from DAHDI about this span.
; (Layer 1 and 2 will be brought back up for an outgoing call.)
; NOTE: You will not be able to detect physical line problems
; until an outgoing call is attempted and fails.
;
;layer1_presence=ignore
; BRI PTMP layer 2 persistence. ; BRI PTMP layer 2 persistence.
; You should normally not need to set this option. ; You should normally not need to set this option.
; You may need to set this option if your telco brings layer 1 down when ; You may need to set this option if your telco brings layer 1 down when

Loading…
Cancel
Save