From d1f8f7b9cad9fb82c7f65446885c36f6f70c0f44 Mon Sep 17 00:00:00 2001
From: Adam Wujek <adam.wujek@cern.ch>
Date: Thu, 26 Mar 2015 10:04:37 +0100
Subject: [PATCH] userspace/snmpd: move wrsDate.c to wrsCurrentTimeGroup.c

--Functionality is the same as in wrsDate.c, but it uses wrsGroupTemplate.h
--update MIB

Signed-off-by: Adam Wujek <adam.wujek@cern.ch>
---
 userspace/snmpd/Makefile              |   2 +-
 userspace/snmpd/WR-SWITCH-MIB.txt     |  16 +--
 userspace/snmpd/init.c                |   3 +-
 userspace/snmpd/wrsCurrentTimeGroup.c | 113 +++++++++++++++++++++
 userspace/snmpd/wrsCurrentTimeGroup.h |  16 +++
 userspace/snmpd/wrsDate.c             | 139 --------------------------
 userspace/snmpd/wrsSnmp.h             |   1 -
 7 files changed, 140 insertions(+), 150 deletions(-)
 create mode 100644 userspace/snmpd/wrsCurrentTimeGroup.c
 create mode 100644 userspace/snmpd/wrsCurrentTimeGroup.h
 delete mode 100644 userspace/snmpd/wrsDate.c

diff --git a/userspace/snmpd/Makefile b/userspace/snmpd/Makefile
index 40d74534e..f7f6ab1da 100644
--- a/userspace/snmpd/Makefile
+++ b/userspace/snmpd/Makefile
@@ -30,9 +30,9 @@ SOURCES = \
 	wrsScalar.c \
 	wrsPstatsTable.c \
 	wrsVersion.c \
-	wrsDate.c \
 	shmem.c \
 	wrsPtpDataTable.c \
+	wrsCurrentTimeGroup.c \
 	wrsTemperature.c \
 	wrsOSStatus.c \
 	wrsPortStatusTable.c
diff --git a/userspace/snmpd/WR-SWITCH-MIB.txt b/userspace/snmpd/WR-SWITCH-MIB.txt
index b56941f53..6e4d419f8 100644
--- a/userspace/snmpd/WR-SWITCH-MIB.txt
+++ b/userspace/snmpd/WR-SWITCH-MIB.txt
@@ -35,7 +35,7 @@ wrsScalar      OBJECT IDENTIFIER ::= { wrSwitchMIB 1 }
 --wrsPstatsTable OBJECT IDENTIFIER ::= { wrSwitchMIB 2 }  == obsolete
 --wrsPpsi        OBJECT IDENTIFIER ::= { wrSwitchMIB 3 }  == obsolete
 wrsVersion     OBJECT IDENTIFIER ::= { wrSwitchMIB 4 }  -- going to be obsolete
-wrsDate        OBJECT IDENTIFIER ::= { wrSwitchMIB 5 }  -- going to be obsolete
+--wrsDate        OBJECT IDENTIFIER ::= { wrSwitchMIB 5 }  == obsolete
 wrsExpertStatus       OBJECT IDENTIFIER ::= { wrSwitchMIB 6 }
 wrsStatus            OBJECT IDENTIFIER ::= { wrSwitchMIB 254 }
 
@@ -123,7 +123,10 @@ wrsScbVersion OBJECT-TYPE
         "The version of the SCB (motherboard)"
     ::= { wrsVersion 9 }
 
--- Date (5), to quickly check wr status
+wrsOperationStatus      OBJECT IDENTIFIER ::= { wrsExpertStatus 1 }
+
+-- wrsCurrentTimeGroup (.6.1.1)
+wrsCurrentTimeGroup     OBJECT IDENTIFIER ::= { wrsOperationStatus 1 }
 
 wrsDateTAI      OBJECT-TYPE
     SYNTAX      Counter64 -- actually integer, but it is unsigned so ok
@@ -131,19 +134,16 @@ wrsDateTAI      OBJECT-TYPE
     STATUS      current
     DESCRIPTION
         "The current time, in TAI seconds"
-    ::= { wrsDate 1 }
+    ::= { wrsCurrentTimeGroup 1 }
 
-wrsDateString   OBJECT-TYPE
+wrsDateTAIString   OBJECT-TYPE
     SYNTAX      DisplayString (SIZE (0..32))
     MAX-ACCESS  read-only
     STATUS      current
     DESCRIPTION
         "The current TAI time, printed as %y-%m-%d-%H:%M:%S (no time zone)"
-    ::= { wrsDate 2 }
-
-wrsOperationStatus      OBJECT IDENTIFIER ::= { wrsExpertStatus 1 }
+    ::= { wrsCurrentTimeGroup 2 }
 
---wrsCurrentTimeGroup     OBJECT IDENTIFIER ::= { wrsOperationStatus 1 }
 --wrsBootStatusGroup      OBJECT IDENTIFIER ::= { wrsOperationStatus 2 }
 wrsTemperatureGroup     OBJECT IDENTIFIER ::= { wrsOperationStatus 3 }
 
diff --git a/userspace/snmpd/init.c b/userspace/snmpd/init.c
index 1919a5d70..ef27a809b 100644
--- a/userspace/snmpd/init.c
+++ b/userspace/snmpd/init.c
@@ -10,6 +10,7 @@
 #include "snmp_shmem.h"
 #include "wrsPstatsTable.h"
 #include "wrsPtpDataTable.h"
+#include "wrsCurrentTimeGroup.h"
 #include "wrsTemperature.h"
 #include "wrsOSStatus.h"
 #include "wrsPortStatusTable.h"
@@ -22,8 +23,8 @@ void init_wrsSnmp(void)
 	init_wrsScalar();
 	init_wrsPstatsTable();
 	init_wrsVersion();
-	init_wrsDate();
 	init_wrsPtpDataTable();
+	init_wrsCurrentTimeGroup();
 	init_wrsTemperature();
 	init_wrsOSStatus();
 	init_wrsPortStatusTable();
diff --git a/userspace/snmpd/wrsCurrentTimeGroup.c b/userspace/snmpd/wrsCurrentTimeGroup.c
new file mode 100644
index 000000000..6fcacc31e
--- /dev/null
+++ b/userspace/snmpd/wrsCurrentTimeGroup.c
@@ -0,0 +1,113 @@
+#include "wrsSnmp.h"
+#include "wrsCurrentTimeGroup.h"
+
+
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+/* defines for nic-hardware.h */
+#define WR_SWITCH
+#define WR_IS_NODE 0
+#define WR_IS_SWITCH 1
+#include "../../kernel/wr_nic/nic-hardware.h"
+#include "../../kernel/wbgen-regs/ppsg-regs.h"
+
+static struct PPSG_WB *pps;
+
+static struct pickinfo wrsCurrentTime_pickinfo[] = {
+	FIELD(wrsCurrentTime_s, ASN_COUNTER64, wrsDateTAI),
+	FIELD(wrsCurrentTime_s, ASN_OCTET_STR, wrsDateTAIString),
+};
+
+struct wrsCurrentTime_s wrsCurrentTime_s;
+
+/* FIXME: this is copied from wr_date, should be librarized */
+static void *create_map(unsigned long address, unsigned long size)
+{
+	unsigned long ps = getpagesize();
+	unsigned long offset, fragment, len;
+	void *mapaddr;
+	int fd;
+
+	fd = open("/dev/mem", O_RDWR | O_SYNC);
+	if (fd < 0)
+		return NULL;
+
+	offset = address & ~(ps - 1);
+	fragment = address & (ps - 1);
+	len = address + size - offset;
+
+	mapaddr = mmap(0, len, PROT_READ | PROT_WRITE,
+		       MAP_SHARED, fd, offset);
+	close(fd);
+	if (mapaddr == MAP_FAILED)
+		return NULL;
+	return mapaddr + fragment;
+}
+
+time_t wrsCurrentTime_data_fill(void)
+{
+	static time_t time_update;
+	time_t time_cur;
+	unsigned long utch, utcl, tmp1, tmp2;
+	time_t t;
+	struct tm tm;
+	uint64_t wrs_d_current_64;
+
+	time_cur = time(NULL);
+	if (time_update
+	    && time_cur - time_update < WRSCURRENTTIME_CACHE_TIMEOUT) {
+		/* cache not updated, return last update time */
+		return time_update;
+	}
+	time_update = time_cur;
+
+	memset(&wrsCurrentTime_s, 0, sizeof(wrsCurrentTime_s));
+
+	/* get TAI time from FPGA */
+
+	if (!pps) /* first time, map the fpga space */
+		pps = create_map(FPGA_BASE_PPSG, sizeof(*pps));
+	if (!pps) {
+		wrs_d_current_64 = 0;
+		strcpy(wrsCurrentTime_s.wrsDateTAIString,
+		       "0000-00-00-00:00:00 (failed)");
+		return time_update;
+	}
+
+	do {
+		utch = pps->CNTR_UTCHI;
+		utcl = pps->CNTR_UTCLO;
+		tmp1 = pps->CNTR_UTCHI;
+		tmp2 = pps->CNTR_UTCLO;
+	} while ((tmp1 != utch) || (tmp2 != utcl));
+
+	wrs_d_current_64 = (uint64_t)(utch) << 32 | utcl;
+	/*
+	  * WARNING: the current snmpd is bugged: it has
+	  * endianness problems with 64 bit, and the two
+	  * halves are swapped. So pre-swap them here
+	  */
+	wrsCurrentTime_s.wrsDateTAI =
+		(wrs_d_current_64 << 32) | (wrs_d_current_64 >> 32);
+
+	t = wrs_d_current_64;
+	localtime_r(&t, &tm);
+	strftime(wrsCurrentTime_s.wrsDateTAIString,
+		 sizeof(wrsCurrentTime_s.wrsDateTAIString),
+		 "%Y-%m-%d-%H:%M:%S", &tm);
+
+	/* there was an update, return current time */
+	return time_update;
+}
+
+#define GT_OID WRSCURRENTTIME_OID
+#define GT_PICKINFO wrsCurrentTime_pickinfo
+#define GT_DATA_FILL_FUNC wrsCurrentTime_data_fill
+#define GT_DATA_STRUCT wrsCurrentTime_s
+#define GT_GROUP_NAME "wrsCurrentTime"
+#define GT_INIT_FUNC init_wrsCurrentTimeGroup
+
+#include "wrsGroupTemplate.h"
diff --git a/userspace/snmpd/wrsCurrentTimeGroup.h b/userspace/snmpd/wrsCurrentTimeGroup.h
new file mode 100644
index 000000000..a2a3337f8
--- /dev/null
+++ b/userspace/snmpd/wrsCurrentTimeGroup.h
@@ -0,0 +1,16 @@
+#ifndef WRS_CURRENT_TIME_GROUP_H
+#define WRS_CURRENT_TIME_GROUP_H
+
+#define WRSCURRENTTIME_CACHE_TIMEOUT 5
+#define WRSCURRENTTIME_OID WRS_OID, 6, 1, 1
+
+struct wrsCurrentTime_s {
+	uint64_t wrsDateTAI;		/* current time in TAI */
+	char wrsDateTAIString[32];	/* current time in TAI as string */
+};
+
+extern struct wrsCurrentTime_s wrsCurrentTime_s;
+time_t wrsCurrentTime_data_fill(void);
+
+void init_wrsCurrentTimeGroup(void);
+#endif /* WRS_CURRENT_TIME_GROUP_H */
diff --git a/userspace/snmpd/wrsDate.c b/userspace/snmpd/wrsDate.c
deleted file mode 100644
index a839b6563..000000000
--- a/userspace/snmpd/wrsDate.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- *  White Rabbit Switch date.  This is two changing values
- *
- *  Alessandro Rubini for CERN, 2014
- */
-#include <net-snmp/net-snmp-config.h>
-#include <net-snmp/net-snmp-includes.h>
-#include <net-snmp/agent/net-snmp-agent-includes.h>
-#include <net-snmp/agent/auto_nlist.h>
-
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "wrsSnmp.h"
-/* defines for nic-hardware.h */
-#define WR_SWITCH
-#define WR_IS_NODE 0
-#define WR_IS_SWITCH 1
-#include "../../kernel/wr_nic/nic-hardware.h"
-#include "../../kernel/wbgen-regs/ppsg-regs.h"
-
-static struct PPSG_WB *pps;
-static uint64_t wrs_d_current_64;
-static char wrs_d_current_string[32];
-
-/* FIXME: this is copied from wr_date, should be librarized */
-void *create_map(unsigned long address, unsigned long size)
-{
-	unsigned long ps = getpagesize();
-	unsigned long offset, fragment, len;
-	void *mapaddr;
-	int fd;
-
-	fd = open("/dev/mem", O_RDWR | O_SYNC);
-	if (fd < 0)
-		return NULL;
-
-	offset = address & ~(ps - 1);
-	fragment = address & (ps - 1);
-	len = address + size - offset;
-
-	mapaddr = mmap(0, len, PROT_READ | PROT_WRITE,
-		       MAP_SHARED, fd, offset);
-	close(fd);
-	if (mapaddr == MAP_FAILED)
-		return NULL;
-	return mapaddr + fragment;
-}
-
-static void wrs_d_get(void)
-{
-	unsigned long utch, utcl, tmp1, tmp2;
-	time_t t;
-	struct tm tm;
-
-	if (!pps) /* first time, map the fpga space */
-		pps = create_map(FPGA_BASE_PPSG, sizeof(*pps));
-	if (!pps) {
-		wrs_d_current_64 = 0;
-		strcpy(wrs_d_current_string, "0000-00-00-00:00:00 (failed)");
-		return;
-	}
-
-	do {
-		utch = pps->CNTR_UTCHI;
-		utcl = pps->CNTR_UTCLO;
-		tmp1 = pps->CNTR_UTCHI;
-		tmp2 = pps->CNTR_UTCLO;
-	} while ((tmp1 != utch) || (tmp2 != utcl));
-
-	wrs_d_current_64 = (uint64_t)(utch) << 32 | utcl;
-	t = wrs_d_current_64;
-	localtime_r(&t, &tm);
-	strftime(wrs_d_current_string,
-		 sizeof(wrs_d_current_string), "%Y-%m-%d-%H:%M:%S", &tm);
-}
-
-static int date_group(netsnmp_mib_handler          *handler,
-			 netsnmp_handler_registration *reginfo,
-			 netsnmp_agent_request_info   *reqinfo,
-			 netsnmp_request_info         *requests)
-{
-	oid obj; /* actually, an integer, i.e. the final index */
-
-	switch (reqinfo->mode) {
-	case MODE_GET:
-
-		wrs_d_get();
-
-		/*
-		 * WARNING: the current snmpd is bugged: it has
-		 * endianness problems with 64 bit, and the two
-		 * halves are swapped. So pre-swap them here
-		 */
-		wrs_d_current_64 =
-			(wrs_d_current_64 << 32) | (wrs_d_current_64 >> 32);
-
-		/* "- 2" because last is 0 for all scalars, I suppose */
-		obj = requests->requestvb->name[
-			requests->requestvb->name_length - 2
-			];
-
-		if (obj == 1) /* number */
-			snmp_set_var_typed_value(requests->requestvb,
-						 ASN_COUNTER64,
-						 &wrs_d_current_64,
-						 sizeof(wrs_d_current_64));
-		else /* string */
-			snmp_set_var_typed_value(requests->requestvb,
-						 ASN_OCTET_STR,
-						 wrs_d_current_string,
-						 strlen(wrs_d_current_string));
-		break;
-	default:
-		snmp_log(LOG_ERR, "unknown mode (%d) in wrs date group\n",
-			 reqinfo->mode);
-		return SNMP_ERR_GENERR;
-	}
-	return SNMP_ERR_NOERROR;
-}
-
-
-void
-init_wrsDate(void)
-{
-
-	const oid wrsDate_oid[] = {  WRS_OID, 5 };
-	netsnmp_handler_registration *hreg;
-
-	/* do the registration */
-	hreg = netsnmp_create_handler_registration(
-		"wrsDate", date_group,
-		wrsDate_oid, OID_LENGTH(wrsDate_oid),
-		HANDLER_CAN_RONLY);
-	netsnmp_register_scalar_group(
-		hreg, 1 /* min */, 2 /* max */);
-}
diff --git a/userspace/snmpd/wrsSnmp.h b/userspace/snmpd/wrsSnmp.h
index fa8f4c7b8..25d90c003 100644
--- a/userspace/snmpd/wrsSnmp.h
+++ b/userspace/snmpd/wrsSnmp.h
@@ -103,7 +103,6 @@ extern void init_wrsScalar(void);
 
 /* Real stuff follows */
 extern void init_wrsVersion(void);
-extern void init_wrsDate(void);
 
 #define WRS_OID 1, 3, 6, 1, 4, 1, 96, 100
 
-- 
GitLab