FWIW (I was interested so put something together), here's a sample diff
on top with one method of printing alarms. (I went for the < > checks
rather than table 3.18 flag bits, mostly because I didn't fancy the
"check again after 100ms" that the latter wanted).
--- sff.c.orig Mon Apr 8 22:27:45 2019
+++ sff.c Mon Apr 8 22:46:34 2019
@@ -202,6 +202,10 @@ static const char *sff8024_con_names[] = {
#define SFF8472_DDM_TEC 108 /* Measured TEC current */
/* optional */
+#define ALRM_LOW_OFFSET 2
+#define WARN_HIGH_OFFSET 4
+#define WARN_LOW_OFFSET 6
+
#define SFF_TEMP_FACTOR 256.0
#define SFF_VCC_FACTOR 10000.0
#define SFF_BIAS_FACTOR 500.0
@@ -380,6 +384,27 @@ if_sff_power2dbm(uint16_t power)
return (10.0 * log10f((float)power / 10000.0));
}
+static const char *
+if_sff_alarm(struct if_sffpage *ddm, size_t value)
+{
+ /* SFF-8472 table 3.15 */
+ size_t alrm_high = (value-96) * 4;
+ size_t alrm_low = alrm_high + ALRM_LOW_OFFSET;
+ size_t warn_high = alrm_high + WARN_HIGH_OFFSET;
+ size_t warn_low = alrm_high + WARN_LOW_OFFSET;
+
+ if(if_sff_int(ddm, value) > if_sff_int(ddm, alrm_high))
+ return " (HIGH ALARM)";
+ else if(if_sff_int(ddm, value) < if_sff_int(ddm, alrm_low))
+ return " (LOW ALARM)";
+ else if(if_sff_int(ddm, value) > if_sff_int(ddm, warn_high))
+ return " (HIGH WARNING)";
+ else if(if_sff_int(ddm, value) < if_sff_int(ddm, warn_low))
+ return " (LOW WARNING)";
+
+ return "";
+}
+
static int
if_sff8472(int s, const char *ifname, int dump, const struct if_sffpage *pg0)
{
@@ -416,17 +441,22 @@ if_sff8472(int s, const char *ifname, int dump, const
"(WARNING: needs more code)\n");
}
- printf("\ttemperature: %.02f C\n",
- if_sff_int(&ddm, SFF8472_DDM_TEMP) / SFF_TEMP_FACTOR);
- printf("\tvcc: %.02f V\n",
- if_sff_uint(&ddm, SFF8472_DDM_VCC) / SFF_VCC_FACTOR);
- printf("\ttx-bias: %.02f mA\n",
- if_sff_uint(&ddm, SFF8472_DDM_TX_BIAS) / SFF_BIAS_FACTOR);
- printf("\ttx-power: %.02f dBm\n",
- if_sff_power2dbm(if_sff_uint(&ddm, SFF8472_DDM_TX_POWER)));
- printf("\trx-power: %.02f dBm %s\n",
+ printf("\ttemperature: %.02f C%s\n",
+ if_sff_int(&ddm, SFF8472_DDM_TEMP) / SFF_TEMP_FACTOR,
+ if_sff_alarm(&ddm, SFF8472_DDM_TEMP));
+ printf("\tvcc: %.02f V%s\n",
+ if_sff_uint(&ddm, SFF8472_DDM_VCC) / SFF_VCC_FACTOR,
+ if_sff_alarm(&ddm, SFF8472_DDM_VCC));
+ printf("\ttx-bias: %.02f mA%s\n",
+ if_sff_uint(&ddm, SFF8472_DDM_TX_BIAS) / SFF_BIAS_FACTOR,
+ if_sff_alarm(&ddm, SFF8472_DDM_TX_BIAS));
+ printf("\ttx-power: %.02f dBm%s\n",
+ if_sff_power2dbm(if_sff_uint(&ddm, SFF8472_DDM_TX_POWER)),
+ if_sff_alarm(&ddm, SFF8472_DDM_TX_BIAS));
+ printf("\trx-power: %.02f dBm %s%s\n",
if_sff_power2dbm(if_sff_uint(&ddm, SFF8472_DDM_RX_POWER)),
- ISSET(ddm_types, SFF8472_DDM_TYPE_AVG_POWER) ? "average" : "OMA");
+ ISSET(ddm_types, SFF8472_DDM_TYPE_AVG_POWER) ? "average" : "OMA",
+ if_sff_alarm(&ddm, SFF8472_DDM_RX_POWER));
return (0);
}