diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c index 6c52a05613..6f229b7f9c 100644 --- a/channels/chan_dahdi.c +++ b/channels/chan_dahdi.c @@ -3132,8 +3132,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) { @@ -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) { +#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); @@ -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) { - 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", @@ -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.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)); @@ -17921,6 +17951,15 @@ static int process_dahdi(struct dahdi_chan_conf *confp, const char *cat, struct } else if (!strcasecmp(v->name, "datetime_send")) { confp->pri.pri.datetime_send = dahdi_datetime_send_option(v->value); #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) } else if (!strcasecmp(v->name, "layer2_persistence")) { if (!strcasecmp(v->value, "keep_up")) { diff --git a/channels/sig_pri.c b/channels/sig_pri.c index 2628163849..e75a9f7aca 100644 --- a/channels/sig_pri.c +++ b/channels/sig_pri.c @@ -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 @@ -8809,6 +8814,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; diff --git a/channels/sig_pri.h b/channels/sig_pri.h index 02e7ce5a95..793ec9869f 100644 --- a/channels/sig_pri.h +++ b/channels/sig_pri.h @@ -442,6 +442,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[]. @@ -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_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); diff --git a/configs/chan_dahdi.conf.sample b/configs/chan_dahdi.conf.sample index 841787c4c5..c633b4510c 100644 --- a/configs/chan_dahdi.conf.sample +++ b/configs/chan_dahdi.conf.sample @@ -259,6 +259,18 @@ ; 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