Commit 25e1d52d authored by Adam Wujek's avatar Adam Wujek 💬

userspace/snmpd: convert wrsPtpData into table wrsPtpDataTable

When switchover is implemented we may have multiple servo instances
--update MIB
--add ppsi headers to wrsSnmp.h
--update Makefile
--update init.c
Signed-off-by: Adam Wujek's avatarAdam Wujek <adam.wujek@cern.ch>
parent 32166f3e
......@@ -32,7 +32,7 @@ SOURCES = \
wrsVersion.c \
wrsDate.c \
shmem.c \
wrsPtpData.c \
wrsPtpDataTable.c \
wrsTemperature.c \
wrsOSStatus.c \
wrsPortStatusTable.c
......
......@@ -8,7 +8,7 @@ WR-SWITCH-MIB DEFINITIONS ::= BEGIN
-- IMPORTS: Include definitions from other mibs here
IMPORTS
OBJECT-TYPE, Integer32, Counter32, Counter64,
OBJECT-TYPE, Integer32, Unsigned32, Counter32, Counter64,
MODULE-IDENTITY, enterprises FROM SNMPv2-SMI
DisplayString FROM SNMPv2-TC;
......@@ -579,7 +579,216 @@ wrsTempThresholdPSR OBJECT-TYPE
--wrsRestartCntGroup OBJECT IDENTIFIER ::= { wrsExpertStatus 2 }
--wrsSpllState OBJECT IDENTIFIER ::= { wrsExpertStatus 3 }
--wrsPstatsTable OBJECT IDENTIFIER ::= { wrsExpertStatus 4 }
--wrsPtpDataTable OBJECT IDENTIFIER ::= { wrsExpertStatus 5 }
-- wrsPtpDataTable (.6.1.5)
wrsPtpDataTable OBJECT-TYPE
SYNTAX SEQUENCE OF WrsPtpDataEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"Information for each ptp servo"
::= { wrsExpertStatus 5 }
wrsPtpDataEntry OBJECT-TYPE
SYNTAX WrsPtpDataEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"An entry containing ptp servo statuses"
INDEX { wrsPtpDataIndex }
::= { wrsPtpDataTable 1 }
WrsPtpDataEntry ::=
SEQUENCE {
wrsPtpDataIndex Unsigned32,
wrsPtpPortName DisplayString,
wrsPtpGrandmasterID OCTET STRING,
wrsPtpOwnID OCTET STRING,
wrsPtpMode INTEGER,
wrsPtpServoState DisplayString,
wrsPtpServoStateN INTEGER,
wrsPtpPhaseTracking INTEGER,
wrsPtpSyncSource DisplayString,
wrsPtpClockOffsetPs Counter64,
wrsPtpClockOffsetPsHR Integer32,
wrsPtpSkew Integer32,
wrsPtpRTT Counter64,
wrsPtpLinkLength Unsigned32,
wrsPtpServoUpdates Counter32,
wrsPtpDeltaTxM Integer32,
wrsPtpDeltaRxM Integer32,
wrsPtpDeltaTxS Integer32,
wrsPtpDeltaRxS Integer32
}
wrsPtpDataIndex OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION
"Index for wrsPtpDataTable"
::= { wrsPtpDataEntry 1 }
wrsPtpPortName OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..12))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Port name on which servo instance is running"
::= { wrsPtpDataEntry 2 }
wrsPtpGrandmasterID OBJECT-TYPE
SYNTAX OCTET STRING (SIZE(8))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The ClockID of the current grandmaster"
::= { wrsPtpDataEntry 3 }
wrsPtpOwnID OBJECT-TYPE
SYNTAX OCTET STRING (SIZE(8))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The ClockID of this WR device"
::= { wrsPtpDataEntry 4 }
wrsPtpMode OBJECT-TYPE
SYNTAX INTEGER {
unknown(0), -- same as WRC_MODE macros
grandmaster(1),
master(2),
slave(3)
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The mode of this clock"
::= { wrsPtpDataEntry 5 }
wrsPtpServoState OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..32))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The servo state if slave"
::= { wrsPtpDataEntry 6 }
wrsPtpServoStateN OBJECT-TYPE
SYNTAX INTEGER {
uninitialized(0),
syncNsec(1),
syncSec(2),
syncPhase(3),
trackPhase(4),
waitSyncIdle(5),
waitOffsetStable(6)
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Numeric representation of servo state"
::= { wrsPtpDataEntry 7 }
wrsPtpPhaseTracking OBJECT-TYPE
SYNTAX INTEGER {
na(0),
notTracking(1),
tracking(2)
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Whether phase tracking is enabled in the servo"
::= { wrsPtpDataEntry 8 }
wrsPtpSyncSource OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..32))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The port name that is currently the synchronization source"
::= { wrsPtpDataEntry 9 }
wrsPtpClockOffsetPs OBJECT-TYPE
SYNTAX Counter64 -- integer64
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Current clock offset from master, in picoseconds"
::= { wrsPtpDataEntry 10 }
wrsPtpClockOffsetPsHR OBJECT-TYPE
SYNTAX Integer32 -- should be something like gauge32, but with int range
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Human Readable current clock offset from master, in picoseconds with saturation to integer"
::= { wrsPtpDataEntry 11 }
wrsPtpSkew OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The estimated change of master-to-slave delay, in picoseconds"
::= { wrsPtpDataEntry 12 }
wrsPtpRTT OBJECT-TYPE
SYNTAX Counter64 -- unsigned64
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The round-trip-time, from master, in picoseconds"
::= { wrsPtpDataEntry 13 }
wrsPtpLinkLength OBJECT-TYPE
SYNTAX Unsigned32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Estimated fiber length, from master-to-slave delay, in meters"
::= { wrsPtpDataEntry 14 }
wrsPtpServoUpdates OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"How many time did the servo run"
::= { wrsPtpDataEntry 15 }
wrsPtpDeltaTxM OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Fixed Tx latency on Master side"
::= { wrsPtpDataEntry 16 }
wrsPtpDeltaRxM OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Fixed Rx latency on Master side"
::= { wrsPtpDataEntry 17 }
wrsPtpDeltaTxS OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Fixed Tx latency on Slave side"
::= { wrsPtpDataEntry 18 }
wrsPtpDeltaRxS OBJECT-TYPE
SYNTAX Integer32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Fixed Rx latency on Slave side"
::= { wrsPtpDataEntry 19 }
-- per-port (.6.1.6)
wrsPortStatusTable OBJECT-TYPE
SYNTAX SEQUENCE OF WrsPortStatusEntry
......
......@@ -7,6 +7,7 @@
/* The sub-init functions */
#include "wrsSnmp.h"
#include "wrsPtpDataTable.h"
#include "wrsTemperature.h"
#include "wrsOSStatus.h"
#include "wrsPortStatusTable.h"
......@@ -20,7 +21,7 @@ void init_wrsSnmp(void)
init_wrsPpsi();
init_wrsVersion();
init_wrsDate();
init_wrsPtpData();
init_wrsPtpDataTable();
init_wrsTemperature();
init_wrsOSStatus();
init_wrsPortStatusTable();
......
#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>
/* Crap! -- everybody makes them different, and even ppsi::ieee wants them */
#undef FALSE
#undef TRUE
/* conflict between definition in net-snmp-agent-includes.h (which include
* snmp_vars.h) and ppsi.h where INST is defined as a inline function */
#undef INST
#include <ppsi/ieee1588_types.h> /* for ClockIdentity */
#include <libwr/shmem.h>
#include <ppsi/ppsi.h>
#include <libwr/hal_shmem.h>
#include <stdio.h>
#include "wrsSnmp.h"
extern struct wrs_shm_head *ppsi_head;
extern struct wr_servo_state_t *ppsi_servo;
#define WRSPTPDATA_CACHE_TIMEOUT 5
/* Our data: globals */
static struct wrsPtpData_s {
ClockIdentity gm_id; /* FIXME: not implemented */
ClockIdentity my_id; /* FIXME: not implemented */
int ppsi_mode; /* FIXME: not implemented */
char servo_state_name[32]; /* State as string */
int servo_state; /* state number */
int tracking_enabled;
char sync_source[32]; /* FIXME: not implemented */
int64_t clock_offset;
int32_t clock_offsetHR; /* Human readable version of clock_offset,
* saturated to int limits */
int32_t skew;
int64_t rtt;
uint32_t llength;
uint32_t servo_updates;
int32_t delta_tx_m;
int32_t delta_rx_m;
int32_t delta_tx_s;
int32_t delta_rx_s;
} wrsPtpData_s;
static struct pickinfo wrsPtpData_pickinfo[] = {
/* Warning: strings are a special case for snmp format */
FIELD(wrsPtpData_s, ASN_OCTET_STR, gm_id),
FIELD(wrsPtpData_s, ASN_OCTET_STR, my_id),
FIELD(wrsPtpData_s, ASN_INTEGER, ppsi_mode),
FIELD(wrsPtpData_s, ASN_OCTET_STR, servo_state_name),
FIELD(wrsPtpData_s, ASN_INTEGER, servo_state),
FIELD(wrsPtpData_s, ASN_INTEGER, tracking_enabled),
FIELD(wrsPtpData_s, ASN_OCTET_STR, sync_source),
FIELD(wrsPtpData_s, ASN_COUNTER64, clock_offset),
FIELD(wrsPtpData_s, ASN_INTEGER, clock_offsetHR),
FIELD(wrsPtpData_s, ASN_INTEGER, skew),
FIELD(wrsPtpData_s, ASN_COUNTER64, rtt),
FIELD(wrsPtpData_s, ASN_UNSIGNED, llength),
FIELD(wrsPtpData_s, ASN_UNSIGNED, servo_updates),
FIELD(wrsPtpData_s, ASN_INTEGER, delta_tx_m),
FIELD(wrsPtpData_s, ASN_INTEGER, delta_rx_m),
FIELD(wrsPtpData_s, ASN_INTEGER, delta_tx_s),
FIELD(wrsPtpData_s, ASN_INTEGER, delta_rx_s),
};
static int32_t int_saturate(int64_t value)
{
if (value >= INT32_MAX)
return INT32_MAX;
else if (value <= INT32_MIN)
return INT32_MIN;
return value;
}
time_t wrsPtpData_data_fill(void)
{
unsigned ii;
unsigned retries = 0;
static time_t time_update;
time_t time_cur;
time_cur = time(NULL);
if (time_update
&& time_cur - time_update < WRSPTPDATA_CACHE_TIMEOUT) {
/* cache not updated, return last update time */
return time_update;
}
time_update = time_cur;
memset(&wrsPtpData_s, 0, sizeof(wrsPtpData_s));
while (1) {
ii = wrs_shm_seqbegin(ppsi_head);
strncpy(wrsPtpData_s.servo_state_name,
ppsi_servo->servo_state_name,
sizeof(ppsi_servo->servo_state_name));
wrsPtpData_s.servo_state = ppsi_servo->state;
/* Keep value 0 for Not available */
wrsPtpData_s.tracking_enabled =
1 + ppsi_servo->tracking_enabled;
/*
* WARNING: the current snmpd is bugged: it has
* endianness problems with 64 bit, and the two
* halves are swapped. So pre-swap them here
*/
wrsPtpData_s.rtt = (ppsi_servo->picos_mu << 32)
| (ppsi_servo->picos_mu >> 32);
wrsPtpData_s.clock_offset = (ppsi_servo->offset << 32)
| (ppsi_servo->offset >> 32);
wrsPtpData_s.clock_offsetHR =
int_saturate(ppsi_servo->offset);
wrsPtpData_s.skew = ppsi_servo->skew;
wrsPtpData_s.llength = (uint32_t)(ppsi_servo->delta_ms/1e12 *
300e6 / 1.55);
wrsPtpData_s.servo_updates = ppsi_servo->update_count;
wrsPtpData_s.delta_tx_m = ppsi_servo->delta_tx_m;
wrsPtpData_s.delta_rx_m = ppsi_servo->delta_rx_m;
wrsPtpData_s.delta_tx_s = ppsi_servo->delta_tx_s;
wrsPtpData_s.delta_rx_s = ppsi_servo->delta_rx_s;
retries++;
if (retries > 100) {
snmp_log(LOG_ERR, "%s: too many retries to read PPSI\n",
__func__);
retries = 0;
}
if (!wrs_shm_seqretry(ppsi_head, ii))
break; /* consistent read */
usleep(1000);
}
/* there was an update, return current time */
return time_update;
}
#define GT_OID WRS_OID, 6, 1
#define GT_PICKINFO wrsPtpData_pickinfo
#define GT_DATA_FILL_FUNC wrsPtpData_data_fill
#define GT_DATA_STRUCT wrsPtpData_s
#define GT_GROUP_NAME "wrsPtpData"
#define GT_INIT_FUNC init_wrsPtpData
#include "wrsGroupTemplate.h"
#include "wrsSnmp.h"
#include "wrsPtpDataTable.h"
struct wrsPtpDataTable_s wrsPtpDataTable_array[WRS_MAX_N_SERVO_INSTANCES];
static struct pickinfo wrsPtpDataTable_pickinfo[] = {
/* Warning: strings are a special case for snmp format */
FIELD(wrsPtpDataTable_s, ASN_UNSIGNED, index), /* not reported */
FIELD(wrsPtpDataTable_s, ASN_OCTET_STR, port_name),
FIELD(wrsPtpDataTable_s, ASN_OCTET_STR, gm_id),
FIELD(wrsPtpDataTable_s, ASN_OCTET_STR, my_id),
FIELD(wrsPtpDataTable_s, ASN_INTEGER, ppsi_mode),
FIELD(wrsPtpDataTable_s, ASN_OCTET_STR, servo_state_name),
FIELD(wrsPtpDataTable_s, ASN_INTEGER, servo_state),
FIELD(wrsPtpDataTable_s, ASN_INTEGER, tracking_enabled),
FIELD(wrsPtpDataTable_s, ASN_OCTET_STR, sync_source),
FIELD(wrsPtpDataTable_s, ASN_COUNTER64, clock_offset),
FIELD(wrsPtpDataTable_s, ASN_INTEGER, clock_offsetHR),
FIELD(wrsPtpDataTable_s, ASN_INTEGER, skew),
FIELD(wrsPtpDataTable_s, ASN_COUNTER64, rtt),
FIELD(wrsPtpDataTable_s, ASN_UNSIGNED, llength),
FIELD(wrsPtpDataTable_s, ASN_COUNTER, servo_updates),
FIELD(wrsPtpDataTable_s, ASN_INTEGER, delta_tx_m),
FIELD(wrsPtpDataTable_s, ASN_INTEGER, delta_rx_m),
FIELD(wrsPtpDataTable_s, ASN_INTEGER, delta_tx_s),
FIELD(wrsPtpDataTable_s, ASN_INTEGER, delta_rx_s),
};
static int32_t int_saturate(int64_t value)
{
if (value >= INT32_MAX)
return INT32_MAX;
else if (value <= INT32_MIN)
return INT32_MIN;
return value;
}
time_t wrsPtpDataTable_data_fill(unsigned int *n_rows)
{
unsigned ii;
unsigned retries = 0;
static time_t time_update;
time_t time_cur;
/* number of rows does not change for wrsPortStatusTable */
if (n_rows)
*n_rows = WRS_MAX_N_SERVO_INSTANCES;
time_cur = time(NULL);
if (time_update
&& time_cur - time_update < WRSPTPDATATABLE_CACHE_TIMEOUT) {
/* cache not updated, return last update time */
return time_update;
}
time_update = time_cur;
memset(&wrsPtpDataTable_array, 0, sizeof(wrsPtpDataTable_array));
/* assume that there is only one servo, will change when switchover is
* implemented */
while (1) {
ii = wrs_shm_seqbegin(ppsi_head);
strncpy(wrsPtpDataTable_array[0].servo_state_name,
ppsi_servo->servo_state_name,
sizeof(ppsi_servo->servo_state_name));
wrsPtpDataTable_array[0].servo_state = ppsi_servo->state;
/* Keep value 0 for Not available */
wrsPtpDataTable_array[0].tracking_enabled =
1 + ppsi_servo->tracking_enabled;
/*
* WARNING: the current snmpd is bugged: it has
* endianness problems with 64 bit, and the two
* halves are swapped. So pre-swap them here
*/
wrsPtpDataTable_array[0].rtt = (ppsi_servo->picos_mu << 32)
| (ppsi_servo->picos_mu >> 32);
wrsPtpDataTable_array[0].clock_offset =
(ppsi_servo->offset << 32)
| (ppsi_servo->offset >> 32);
wrsPtpDataTable_array[0].clock_offsetHR =
int_saturate(ppsi_servo->offset);
wrsPtpDataTable_array[0].skew = ppsi_servo->skew;
wrsPtpDataTable_array[0].llength =
(uint32_t)(ppsi_servo->delta_ms/1e12 * 300e6 / 1.55);
wrsPtpDataTable_array[0].servo_updates =
ppsi_servo->update_count;
wrsPtpDataTable_array[0].delta_tx_m = ppsi_servo->delta_tx_m;
wrsPtpDataTable_array[0].delta_rx_m = ppsi_servo->delta_rx_m;
wrsPtpDataTable_array[0].delta_tx_s = ppsi_servo->delta_tx_s;
wrsPtpDataTable_array[0].delta_rx_s = ppsi_servo->delta_rx_s;
retries++;
if (retries > 100) {
snmp_log(LOG_ERR, "%s: too many retries to read PPSI\n",
__func__);
retries = 0;
}
if (!wrs_shm_seqretry(ppsi_head, ii))
break; /* consistent read */
usleep(1000);
}
/* there was an update, return current time */
return time_update;
}
#define TT_OID WRSPTPDATATABLE_OID
#define TT_PICKINFO wrsPtpDataTable_pickinfo
#define TT_DATA_FILL_FUNC wrsPtpDataTable_data_fill
#define TT_DATA_ARRAY wrsPtpDataTable_array
#define TT_GROUP_NAME "wrsPtpDataTable"
#define TT_INIT_FUNC init_wrsPtpDataTable
#define TT_CACHE_TIMEOUT WRSPTPDATATABLE_CACHE_TIMEOUT
#include "wrsTableTemplate.h"
#ifndef WRS_PTP_DATA_TABLE_H
#define WRS_PTP_DATA_TABLE_H
#define WRSPTPDATATABLE_CACHE_TIMEOUT 5
#define WRSPTPDATATABLE_OID WRS_OID, 6, 5
/* Right now we allow only one servo instance, it will change in the future
* when switchover is implemented */
#define WRS_MAX_N_SERVO_INSTANCES 1
struct wrsPtpDataTable_s {
uint32_t index; /* not reported, index fields has to be marked
* as not-accessible in MIB */
char port_name[12]; /* port name on which ptp servo instance in
* running FIXME: not implemented */
ClockIdentity gm_id; /* FIXME: not implemented */
ClockIdentity my_id; /* FIXME: not implemented */
int ppsi_mode; /* FIXME: not implemented */
char servo_state_name[32]; /* State as string */
int servo_state; /* state number */
int tracking_enabled;
char sync_source[32]; /* FIXME: not implemented */
int64_t clock_offset;
int32_t clock_offsetHR; /* Human readable version of clock_offset,
* saturated to int limits */
int32_t skew;
int64_t rtt;
uint32_t llength;
uint32_t servo_updates;
int32_t delta_tx_m;
int32_t delta_rx_m;
int32_t delta_tx_s;
int32_t delta_rx_s;
};
time_t wrsPtpDataTable_data_fill(unsigned int *rows);
void init_wrsPtpDataTable(void);
#endif /* WRS_PTP_DATA_TABLE_H */
......@@ -16,11 +16,15 @@
#include <libwr/shmem.h>
#include <libwr/hal_shmem.h>
#include <ppsi/ppsi.h>
#include <libwr/hal_shmem.h>
extern struct wrs_shm_head *hal_head;
extern struct hal_shmem_header *hal_shmem;
extern struct hal_port_state *hal_ports;
extern int hal_nports_local;
extern struct wrs_shm_head *ppsi_head;
extern struct wr_servo_state_t *ppsi_servo;
/*
* local hack: besides the file pointer, that is there anyways,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment