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); }