]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Add ability to ignore layer 1 alarms for BRI PTMP lines.
authorRichard Mudgett <rmudgett@digium.com>
Wed, 18 Apr 2012 16:20:14 +0000 (16:20 +0000)
committerRichard Mudgett <rmudgett@digium.com>
Wed, 18 Apr 2012 16:20:14 +0000 (16:20 +0000)
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

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@362428 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_dahdi.c
channels/sig_pri.c
channels/sig_pri.h
configs/chan_dahdi.conf.sample

index 2d119a66b68af450ee9bd4f1d82331492bc3b566..6737462738e2e3cd779f201103c56335f2a48d64 100644 (file)
@@ -3095,8 +3095,19 @@ static void my_handle_dchan_exception(struct sig_pri_span *pri, int index)
        int x;
 
        ioctl(pri->fds[index], DAHDI_GETEVENT, &x);
-       if (x) {
-               ast_log(LOG_NOTICE, "PRI got event: %s (%d) on D-channel of span %d\n", event2str(x), x, pri->span);
+       switch (x) {
+       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 */
        switch (x) {
@@ -3784,6 +3795,12 @@ static void dahdi_queue_frame(struct dahdi_pvt *p, struct ast_frame *f)
 
 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) {
                ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel);
                manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", "Channel: %d\r\n", p->channel);
@@ -7810,8 +7827,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)
 {
-       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) {
                ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", p->channel, alarm_str);
                manager_event(EVENT_FLAG_SYSTEM, "Alarm",
@@ -12576,6 +12600,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.aoce_delayhangup = conf->pri.pri.aoce_delayhangup;
 #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;
                                                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));
@@ -17577,6 +17607,15 @@ static int process_dahdi(struct dahdi_chan_conf *confp, const char *cat, struct
 #endif /* defined(HAVE_PRI_MWI) */
                        } else if (!strcasecmp(v->name, "append_msn_to_cid_tag")) {
                                confp->pri.pri.append_msn_to_user_tag = ast_true(v->value);
+                       } 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)
                        } else if (!strcasecmp(v->name, "layer2_persistence")) {
                                if (!strcasecmp(v->value, "keep_up")) {
index 2fc0316ce53a5521656509c3e7bb29573e6a91c3..bccb62764ac8a7bf8641d19172acc453dfe6679d 100644 (file)
@@ -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)
 {
+       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
         * to prevent the flag from getting stuck when the link goes
@@ -7791,6 +7796,18 @@ void sig_pri_chan_alarm_notify(struct sig_pri_chan *p, int noalarm)
        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 *p;
index a29233a40894b3aae255b673719a7436f155082f..0802eddeec3bd50270ddf620cff6e5a5287258e2 100644 (file)
@@ -364,6 +364,8 @@ struct sig_pri_span {
        /*! \brief TRUE if we will allow incoming ISDN call waiting calls. */
        unsigned int allow_call_waiting_calls:1;
 #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
         * appended to the initial_user_tag[].
@@ -521,8 +523,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_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_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);
index f11f619a2671db624f4f51796e0656ad448d21ed..7ef1e4c19adae39990a3ae76ad57eb9a7801bb97 100644 (file)
 ; The default is no.
 ;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.
 ; You should normally not need to set this option.
 ; You may need to set this option if your telco brings layer 1 down when