[svn-commits] jpeeler: branch jpeeler/bug16709 r245686 - /team/jpeeler/bug16709/channels/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Tue Feb 9 10:54:01 CST 2010


Author: jpeeler
Date: Tue Feb  9 10:53:57 2010
New Revision: 245686

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=245686
Log:
Commit current work based on reporter's patch. So far changes have been made
to accomodate the case where an interface is destroyed as well as query DAHDI
for span status instead of assuming the state of one channel is an accurate
representation of the current span. I believe there probably is a better place
to set the manage_span_alarms flag as it sets the same flag on an interface
multiple times. However, I'm going to focus next on figuring out a good way
to make testing alarms unit testable.

Modified:
    team/jpeeler/bug16709/channels/chan_dahdi.c

Modified: team/jpeeler/bug16709/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/team/jpeeler/bug16709/channels/chan_dahdi.c?view=diff&rev=245686&r1=245685&r2=245686
==============================================================================
--- team/jpeeler/bug16709/channels/chan_dahdi.c (original)
+++ team/jpeeler/bug16709/channels/chan_dahdi.c Tue Feb  9 10:53:57 2010
@@ -416,6 +416,10 @@
 
 static int mwilevel = 512;
 static int dtmfcid_level = 256;
+
+#define REPORT_CHANNEL_ALARMS 1
+#define REPORT_SPAN_ALARMS    2 
+static int report_alarms = REPORT_CHANNEL_ALARMS;
 
 #ifdef HAVE_PRI
 #ifdef PRI_GETSET_TIMERS
@@ -965,6 +969,12 @@
 	 * \note Applies to SS7 and MFCR2 channels.
 	 */
 	unsigned int remotelyblocked:1;
+	/*!
+	 * \brief TRUE if the channel alarms will be managed also as Span ones
+	 * \note Applies to all channels
+	 */
+	unsigned int manages_span_alarms:1;
+
 #if defined(HAVE_PRI)
 	struct sig_pri_pri *pri;
 	int prioffset;
@@ -3112,8 +3122,14 @@
 		res = get_alarms(p);
 		handle_alarms(p, res);
 	} else {
-		ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel);
-		manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", "Channel: %d\r\n", p->channel);
+		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);
+		}
+		if(report_alarms & REPORT_SPAN_ALARMS && p->manages_span_alarms) {
+			ast_log(LOG_NOTICE, "Alarm cleared on span %d\n", p->span);
+			manager_event(EVENT_FLAG_SYSTEM, "SpanAlarmClear", "Span: %d\r\n", p->span);
+		}
 	}
 	ast_mutex_unlock(&p->lock);
 }
@@ -5042,9 +5058,27 @@
 }
 #endif	/* defined(HAVE_PRI) */
 
+static struct dahdi_pvt *find_next_iface_in_span(struct dahdi_pvt *cur)
+{
+	if (cur->next && cur->next->span == cur->span) {
+		return cur->next;
+	} else if (cur->prev && cur->prev->span == cur->span) {
+		return cur->prev;
+	}
+
+	return NULL;
+}
+
 static void destroy_dahdi_pvt(struct dahdi_pvt *pvt)
 {
 	struct dahdi_pvt *p = pvt;
+
+	if (p->manages_span_alarms) {
+		struct dahdi_pvt *next = find_next_iface_in_span(p);
+		if (next) {
+			next->manages_span_alarms = 1;
+		}
+	}
 
 	/* Remove channel from the list */
 #if defined(HAVE_PRI)
@@ -6951,13 +6985,34 @@
 
 static void handle_alarms(struct dahdi_pvt *p, int alms)
 {
+	struct dahdi_spaninfo di;
+	int res;
 	const char *alarm_str = alarm2str(alms);
 
-	ast_log(LOG_WARNING, "Detected alarm on channel %d: %s\n", p->channel, alarm_str);
-	manager_event(EVENT_FLAG_SYSTEM, "Alarm",
-		"Alarm: %s\r\n"
-		"Channel: %d\r\n",
-		alarm_str, p->channel);
+	memset(&di, 0, sizeof(di));
+	di.spanno = p->span;
+
+	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",
+					  "Alarm: %s\r\n"
+					  "Channel: %d\r\n",
+					  alarm_str, p->channel);
+	}
+
+	if(report_alarms & REPORT_SPAN_ALARMS && p->manages_span_alarms) {
+		if ((res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SPANSTAT, &di)) >= 0) {
+			if (di.alarms != DAHDI_ALARM_NONE) {
+				ast_log(LOG_WARNING, "Detected alarm on span %d: %s\n", p->span, alarm_str);
+				manager_event(EVENT_FLAG_SYSTEM, "SpanAlarm",
+							  "Alarm: %s\r\n"
+							  "Span: %d\r\n",
+							  alarm_str, p->span);
+			}
+		} else {
+			ast_log(LOG_WARNING, "Unable to determine alarm on channel %d: %s\n", p->channel, strerror(errno));
+		}
+	}
 }
 
 static struct ast_frame *dahdi_handle_event(struct ast_channel *ast)
@@ -7464,9 +7519,15 @@
 		}
 #endif
 		p->inalarm = 0;
-		ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel);
-		manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
-							"Channel: %d\r\n", p->channel);
+		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);
+		}
+		if(report_alarms & REPORT_SPAN_ALARMS && p->manages_span_alarms) {
+			ast_log(LOG_NOTICE, "Alarm cleared on span %d\n", p->span);
+			manager_event(EVENT_FLAG_SYSTEM, "SpanAlarmClear", "Span: %d\r\n", p->span);
+		}
 		break;
 	case DAHDI_EVENT_WINKFLASH:
 		if (p->inalarm) break;
@@ -9974,9 +10035,15 @@
 				break;
 			case DAHDI_EVENT_NOALARM:
 				mtd->pvt->inalarm = 0;
-				ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", mtd->pvt->channel);
-				manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
-					"Channel: %d\r\n", mtd->pvt->channel);
+				if(report_alarms & REPORT_CHANNEL_ALARMS) {
+					ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", mtd->pvt->channel);
+					manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
+								  "Channel: %d\r\n", mtd->pvt->channel);
+				}
+				if(report_alarms & REPORT_SPAN_ALARMS && mtd->pvt->manages_span_alarms) {
+					ast_log(LOG_NOTICE, "Alarm cleared on span %d\n", mtd->pvt->span);
+					manager_event(EVENT_FLAG_SYSTEM, "SpanAlarmClear", "Span: %d\r\n", mtd->pvt->span);
+				}
 				break;
 			case DAHDI_EVENT_ALARM:
 				mtd->pvt->inalarm = 1;
@@ -10390,9 +10457,17 @@
 		break;
 	case DAHDI_EVENT_NOALARM:
 		i->inalarm = 0;
-		ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel);
-		manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
-			"Channel: %d\r\n", i->channel);
+		if(report_alarms & REPORT_CHANNEL_ALARMS) {
+			ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", i->channel);
+			manager_event(EVENT_FLAG_SYSTEM, "AlarmClear",
+						  "Channel: %d\r\n", i->channel);
+		}
+                
+		if(report_alarms & REPORT_SPAN_ALARMS && i->manages_span_alarms) {
+			ast_log(LOG_NOTICE, "Alarm cleared on span %d\n", i->span);
+			manager_event(EVENT_FLAG_SYSTEM, "SpanAlarmClear",
+						  "Span: %d\r\n", i->span);
+		}
 		break;
 	case DAHDI_EVENT_ALARM:
 		i->inalarm = 1;
@@ -15688,6 +15763,16 @@
 					(reload == 1) ? "reconfigure" : "register", value);
 				return -1;
 			}
+		}
+	}
+
+	/* Mark the first channels of each Span to watch for their Span alarms */
+	for (tmp = iflist, x=-1; tmp; tmp = tmp->next) {
+		if (!tmp->destroy && tmp->span != x) {
+			tmp->manages_span_alarms = 1;
+			x = tmp->span; 
+		} else {
+			tmp->manages_span_alarms = 0;
 		}
 	}
 
@@ -16691,7 +16776,16 @@
 				mwilevel = atoi(v->value);
 			} else if (!strcasecmp(v->name, "dtmfcidlevel")) {
 				dtmfcid_level = atoi(v->value);
-			}
+			} else if (!strcasecmp(v->name, "reportalarms")) {
+				if (!strcasecmp(v->value, "all"))
+					report_alarms = REPORT_CHANNEL_ALARMS | REPORT_SPAN_ALARMS;
+				if (!strcasecmp(v->value, "none"))
+					report_alarms = 0;
+				else if (!strcasecmp(v->value, "channels"))
+					report_alarms = REPORT_CHANNEL_ALARMS;
+			   else if (!strcasecmp(v->value, "spans"))
+					report_alarms = REPORT_SPAN_ALARMS;
+			 }
 		} else if (!(options & PROC_DAHDI_OPT_NOWARN) )
 			ast_log(LOG_WARNING, "Ignoring any changes to '%s' (on reload) at line %d.\n", v->name, v->lineno);
 	}




More information about the svn-commits mailing list