From f9578dcb2deec8f1205ff4aea56d3859301f8a72 Mon Sep 17 00:00:00 2001
From: Adam Wujek <adam.wujek@cern.ch>
Date: Thu, 23 Apr 2015 16:54:09 +0200
Subject: [PATCH] userspace/snmpd: add wrsSlaveLinksStatus to
 wrsTimingStatusGroup

Additionally update MIB

Signed-off-by: Adam Wujek <adam.wujek@cern.ch>
---
 userspace/snmpd/WR-SWITCH-MIB.txt      | 15 ++++++++
 userspace/snmpd/wrsTimingStatusGroup.c | 49 +++++++++++++++++++++++++-
 userspace/snmpd/wrsTimingStatusGroup.h |  6 ++++
 3 files changed, 69 insertions(+), 1 deletion(-)

diff --git a/userspace/snmpd/WR-SWITCH-MIB.txt b/userspace/snmpd/WR-SWITCH-MIB.txt
index 2468d2e0f..d3d111b84 100644
--- a/userspace/snmpd/WR-SWITCH-MIB.txt
+++ b/userspace/snmpd/WR-SWITCH-MIB.txt
@@ -175,6 +175,21 @@ wrsSoftPLLStatus OBJECT-TYPE
             bug - bug in checking conditions of wrsSpllState, please report"
     ::= { wrsTimingStatusGroup 2 }
 
+wrsSlaveLinksStatus OBJECT-TYPE
+    SYNTAX         INTEGER {
+                        na(0),
+                        ok(1),
+                        error(2)
+    }
+    MAX-ACCESS     read-only
+    STATUS         current
+    DESCRIPTION
+            "Grouped status of slave link statuses
+            ok - when every slave port is up when switch is in slave mode
+                 and when every slave port is down when switch in master/grandmaster mode
+                 don't care about non-wr and auto ports"
+    ::= { wrsTimingStatusGroup 3 }
+
 -- wrsNetworkingStatusGroup (.6.1.3)
 wrsNetworkingStatusGroup   OBJECT IDENTIFIER ::= { wrsDetailedStatusesGroup 3 }
 
diff --git a/userspace/snmpd/wrsTimingStatusGroup.c b/userspace/snmpd/wrsTimingStatusGroup.c
index 5254ab8a7..8801d7dd5 100644
--- a/userspace/snmpd/wrsTimingStatusGroup.c
+++ b/userspace/snmpd/wrsTimingStatusGroup.c
@@ -1,5 +1,6 @@
 #include "wrsSnmp.h"
 #include "wrsSpllStatusGroup.h"
+#include "wrsPortStatusTable.h"
 #include "wrsTimingStatusGroup.h"
 
 static struct pickinfo wrsTimingStatus_pickinfo[] = {
@@ -15,11 +16,17 @@ time_t wrsTimingStatus_data_fill(void)
 {
 	static time_t time_update; /* time of last update */
 	time_t time_spll; /* time when softPLL data was updated */
+	time_t time_port_status; /* time when port status table was updated */
+	unsigned int port_status_nrows; /* number of rows in PortStatusTable */
+	int i;
 	struct wrsSpllStatus_s *s;
+	struct wrsPortStatusTable_s *p_a;
 
 	time_spll = wrsSpllStatus_data_fill();
+	time_port_status = wrsPortStatusTable_data_fill(&port_status_nrows);
 
-	if (time_spll <= time_update) {
+	if (time_spll <= time_update
+	    && time_port_status <= time_update) {
 		/* cache not updated, return last update time */
 		return time_update;
 	}
@@ -76,6 +83,46 @@ time_t wrsTimingStatus_data_fill(void)
 						WRS_SOFTPLL_STATUS_BUG;
 	}
 
+	/*********************************************************************\
+	|************************ wrsSlaveLinksStatus ************************|
+	\*********************************************************************/
+	/*
+	 * ok when every slave port is up when switch is in slave mode
+	 * and when every slave port is down when switch in master/grandmaster
+	 * mode. Don't care about non-wr and auto ports.
+	*/
+	p_a = wrsPortStatusTable_array;
+	wrsTimingStatus_s.wrsSlaveLinksStatus = WRS_SLAVE_LINK_STATUS_OK;
+	for (i = 0; i < port_status_nrows; i++) {
+		/* warning N/A */
+		if (s->wrsSpllMode == 0
+		    || p_a[i].port_mode == 0
+		    || p_a[i].link_up == 0){
+			wrsTimingStatus_s.wrsSlaveLinksStatus =
+					WRS_SLAVE_LINK_STATUS_WARNING_NA;
+		}
+		/* error when slave port is down when switch is in slave mode
+		   */
+		if (s->wrsSpllMode == WRS_SPLL_MODE_SLAVE
+		    && (p_a[i].port_mode == WRS_PORT_STATUS_CONFIGURED_MODE_SLAVE)
+		    && (p_a[i].link_up == WRS_PORT_STATUS_LINK_DOWN)) {
+			wrsTimingStatus_s.wrsSlaveLinksStatus =
+						WRS_SLAVE_LINK_STATUS_ERROR;
+			snmp_log(LOG_ERR, "SNMP: wrsSlaveLinksStatus (slave) "
+					  "failed for port %d\n", i);
+		}
+		/* error when slave port is up when switch is in master or
+		 * grandmaster mode */
+		if (((s->wrsSpllMode == WRS_SPLL_MODE_GRAND_MASTER) || (s->wrsSpllMode == WRS_SPLL_MODE_MASTER))
+		    && (p_a[i].port_mode == WRS_PORT_STATUS_CONFIGURED_MODE_SLAVE)
+		    && (p_a[i].link_up == WRS_PORT_STATUS_LINK_UP)) {
+			wrsTimingStatus_s.wrsSlaveLinksStatus =
+						WRS_SLAVE_LINK_STATUS_ERROR;
+			snmp_log(LOG_ERR, "SNMP: wrsSlaveLinksStatus (master) "
+					  "failed for port %d\n", i);
+		}
+	}
+
 	/* there was an update, return current time */
 	return time_update;
 }
diff --git a/userspace/snmpd/wrsTimingStatusGroup.h b/userspace/snmpd/wrsTimingStatusGroup.h
index 4dade0e04..b496c7343 100644
--- a/userspace/snmpd/wrsTimingStatusGroup.h
+++ b/userspace/snmpd/wrsTimingStatusGroup.h
@@ -11,6 +11,12 @@
 					  * normal operation */
 #define WRS_SOFTPLL_STATUS_BUG 5		/* warning */
 
+#define WRS_SLAVE_LINK_STATUS_OK 1		/* ok */
+#define WRS_SLAVE_LINK_STATUS_ERROR 2		/* error */
+#define WRS_SLAVE_LINK_STATUS_WARNING_NA 4 /* warning, at least one field is
+					  * equal to 0 (NA),shouldn't happen in
+					  * normal operation */
+
 struct wrsTimingStatus_s {
 	int wrsPTPStatus;
 	int wrsSoftPLLStatus;
-- 
GitLab