All,
I have attached a TOB patch which enables the proper display of analog values
in
discrete sensors on HP platforms.
I was able to implement this without a new HP oem specific switch by modifying
each interface
open routine to read and cache the OEM manufacturer (via the Get Device ID
command) immediately
upon open and to reset the cached OEM manufacturer id to unknown upon interface
close. The cached
manufacturer value in the interface is then be used at run time to implement
the manufacturer
specific code.
A non threshold sensor has an analog value if it is defined as having analog
units and it has either valid
percentage or modifier units defined and the manufacturer is IPMI_OEM_HP. The
determination of whether
or not a given sensor has an analog value is contained in a single function
(sdr_sensor_has_analog_reading).
This patch also encapsulates the reading of all sensor values in ipmitool into
a a single ipmitool function,
ipmi_sdr_read_sensor_value. The prior independent sensor reading code paths
have been collapsed into one
sensor reading code path. This encapsulation enabled consistent validation of
all data returned by the IPMI
get sensor reading command. In implementing a single sensor value read
function, I resolved the
inconsistencies between what the "sensor" and "sdr" arguments displayed and I
also resolved numerous
cases where uninitialized information in the IPMI reply from get sensor reading
was being interpreted
and incorrectly displayed.
These changes have already been code reviewed and tested on a variety of HP
Proliant platforms and
one Dell platform using the lan, lanplus and the open ipmi interfaces. I
tested all variants of the sdr and sensor
commands and switches comparing a version of ipmitool with this patch and
without. Where inconsistencies
in output were seen, the current ipmitool was found to be producing invalid
information. In particular, there
existed code in the sdr print routine which would attempt to read sensor values
even if when a sensor
had scanning disabled. This code always led to incorrect values for sensors
on the platforms I tested on
so this code was removed.
I would appreciated if I could get someone on the list to code review these
changes for me. I would also
appreciated if someone could try out the patch to make sure it works on their
platforms. This patch
is the final step in cleaning up the ipmitool sensor reading logic and I think
this patch has value even without
the code which permits reading analog values in discrete sensors on HP
platforms.
--
-- Jim Mankovich |jm...@hp.com --
>From 0e1ef4157f946cd27cf2db4b7993977f1c0947bd Mon Sep 17 00:00:00 2001
From: Jim Mankovich <jm...@hp.com>
Date: Thu, 7 Jun 2012 11:35:35 -0600
Subject: [PATCH] support for analog values in discrete sensors
---
include/ipmitool/ipmi_intf.h | 1 +
include/ipmitool/ipmi_sdr.h | 31 ++-
lib/ipmi_event.c | 4 +-
lib/ipmi_sdr.c | 552 +++++++++++++++++++++++------------------
lib/ipmi_sel.c | 11 +-
lib/ipmi_sensor.c | 277 +++++++--------------
src/plugins/bmc/bmc.c | 2 +
src/plugins/free/free.c | 2 +
src/plugins/imb/imb.c | 2 +
src/plugins/lan/lan.c | 2 +
src/plugins/lanplus/lanplus.c | 3 +-
src/plugins/lipmi/lipmi.c | 2 +
src/plugins/open/open.c | 2 +
13 files changed, 448 insertions(+), 443 deletions(-)
diff --git a/include/ipmitool/ipmi_intf.h b/include/ipmitool/ipmi_intf.h
index 894d2a0..8b5b6f6 100644
--- a/include/ipmitool/ipmi_intf.h
+++ b/include/ipmitool/ipmi_intf.h
@@ -165,6 +165,7 @@ struct ipmi_intf {
int opened;
int abort;
int noanswer;
+ IPMI_OEM manufacturer_id;
struct ipmi_session * session;
struct ipmi_oem_handle * oem;
diff --git a/include/ipmitool/ipmi_sdr.h b/include/ipmitool/ipmi_sdr.h
index 5db1e75..3c88397 100644
--- a/include/ipmitool/ipmi_sdr.h
+++ b/include/ipmitool/ipmi_sdr.h
@@ -820,6 +820,22 @@ static const char *sensor_type_desc[] __attribute__ ((unused)) = {
"Management Subsystem Health", "Battery","Session Audit",
"Version Change","FRU State" };
+struct sensor_reading {
+ char s_id[17]; /* name of the sensor */
+ struct sdr_record_full_sensor *full;
+ struct sdr_record_compact_sensor *compact;
+ uint8_t s_reading_valid; /* read value valididity */
+ uint8_t s_scanning_disabled; /* read of value disabled */
+ uint8_t s_reading_unavailable; /* read value unavailable */
+ uint8_t s_reading; /* value which was read */
+ uint8_t s_data2; /* data2 value read */
+ uint8_t s_data3; /* data3 value read */
+ uint8_t s_has_analog_value; /* sensor has analog value */
+ double s_a_val; /* read value converted to analog */
+ char s_a_str[16]; /* analog value as a string */
+ const char *s_a_units; /* analog value units string */
+};
+
struct ipmi_sdr_iterator *ipmi_sdr_start(struct ipmi_intf *intf,
int use_builtin);
struct sdr_get_rs *ipmi_sdr_get_next_header(struct ipmi_intf *intf,
@@ -829,7 +845,7 @@ uint8_t *ipmi_sdr_get_record(struct ipmi_intf *intf, struct sdr_get_rs *header,
void ipmi_sdr_end(struct ipmi_intf *intf, struct ipmi_sdr_iterator *i);
int ipmi_sdr_print_sdr(struct ipmi_intf *intf, uint8_t type);
-int ipmi_sdr_print_name_from_rawentry(struct ipmi_intf *intf,uint16_t id,
+int ipmi_sdr_print_name_from_rawentry(struct ipmi_intf *intf,uint16_t id,
uint8_t type,uint8_t * raw);
int ipmi_sdr_print_rawentry(struct ipmi_intf *intf, uint8_t type, uint8_t * raw,
int len);
@@ -841,16 +857,17 @@ void ipmi_sdr_print_sensor_hysteresis(struct sdr_record_common_sensor *sensor,
const char *hdrstr);
const char *ipmi_sdr_get_unit_string(uint8_t pct, uint8_t type,
uint8_t base, uint8_t modifier);
-const char *ipmi_sdr_get_thresh_status(struct ipmi_rs *rsp,
- int validread, const char *invalidstr);
+struct sensor_reading *
+ipmi_sdr_read_sensor_value(struct ipmi_intf *intf,
+ struct sdr_record_common_sensor *sensor,
+ uint8_t sdr_record_type, int precision);
+const char *ipmi_sdr_get_thresh_status(struct sensor_reading *sr,
+ const char *invalidstr);
const char *ipmi_sdr_get_status(int, const char *, uint8_t stat);
double sdr_convert_sensor_tolerance(struct sdr_record_full_sensor *sensor,
uint8_t val);
double sdr_convert_sensor_reading(struct sdr_record_full_sensor *sensor,
uint8_t val);
-double sdr_convert_analog_reading(struct ipmi_intf *intf,
- struct sdr_record_full_sensor *sensor, uint8_t read,
- int *convert_success);
double sdr_convert_sensor_hysterisis(struct sdr_record_full_sensor *sensor,
uint8_t val);
uint8_t sdr_convert_sensor_value_to_raw(struct sdr_record_full_sensor *sensor,
@@ -901,7 +918,7 @@ int ipmi_sdr_print_info(struct ipmi_intf *intf);
void ipmi_sdr_print_discrete_state(const char *desc, uint8_t sensor_type,
uint8_t event_type, uint8_t state1,
uint8_t state2);
-void ipmi_sdr_print_discrete_state_mini(const char *separator,
+void ipmi_sdr_print_discrete_state_mini(const char *header, const char *separator,
uint8_t sensor_type, uint8_t event_type,
uint8_t state1, uint8_t state2);
int ipmi_sdr_print_sensor_event_status(struct ipmi_intf *intf,
diff --git a/lib/ipmi_event.c b/lib/ipmi_event.c
index 6580975..ef2d733 100644
--- a/lib/ipmi_event.c
+++ b/lib/ipmi_event.c
@@ -227,8 +227,8 @@ ipmi_event_find_offset(uint8_t code,
static void
print_sensor_states(uint8_t sensor_type, uint8_t event_type)
{
- printf("Sensor States: \n ");
- ipmi_sdr_print_discrete_state_mini("\n ", sensor_type,
+ ipmi_sdr_print_discrete_state_mini(
+ "Sensor States: \n ", "\n ", sensor_type,
event_type, 0xff, 0xff);
printf("\n");
}
diff --git a/lib/ipmi_sdr.c b/lib/ipmi_sdr.c
index 14951d8..9ea2526 100644
--- a/lib/ipmi_sdr.c
+++ b/lib/ipmi_sdr.c
@@ -1,4 +1,7 @@
/*
+ * Copyright (c) 2012 Hewlett-Packard Development Company, L.P.
+ *
+ * Based on code from
* Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -106,48 +109,67 @@ ipmi_sdr_get_unit_string(uint8_t pct, uint8_t type, uint8_t base, uint8_t modifi
}
break;
}
-
return unitstr;
}
-/* sdr_convert_analog_reading - convert raw sensor reading to analog
+/* sdr_sensor_has_analog_reading - Determine if sensor has an analog reading
*
- * @sensor: sensor record
- * @raed: raw sensor reading
- * @convert_success: raw sensor reading
- *
- *
- * returns floating-point sensor reading and conversion status
*/
-double
-sdr_convert_analog_reading(struct ipmi_intf *intf,
- struct sdr_record_full_sensor *full, uint8_t read,
- int *convert_success)
+static int
+sdr_sensor_has_analog_reading(struct ipmi_intf *intf,
+ struct sensor_reading *sr)
{
- /* Compact sensors can't return analog values so we return zero */
- if (!full) {
- return 0.0;
+ /* Compact sensors can't return analog values so we false */
+ if (!sr->full) {
+ return 0;
}
/*
- * Only Full Threshold sensors with analog readings can be converted.
- * If this not the case, we return zero
+ * Per the IPMI Specification:
+ * Only Full Threshold sensors are identified as providing
+ * analog readings.
+ *
+ * But... HP didn't interpret this as meaning that "Only Threshold
+ * Sensors" can provide analog readings. So, HP packed analog
+ * readings into some of their non-Threshold Sensor. There is
+ * nothing that explictly prohibits this in the spec, so if
+ * an Analog reading is available in a Non-Threshod sensor and
+ * there are units specified for identifying the reading then
+ * we do an analog conversion even though the sensor is
+ * non-Threshold. To be safe, we provide this extension for
+ * HP.
+ *
*/
- if ( !(IS_THRESHOLD_SENSOR(&full->cmn) &&
- !UNITS_ARE_DISCRETE(&full->cmn)) ) {
- return 0.0;
+ if ( UNITS_ARE_DISCRETE(&sr->full->cmn) ) {
+ return 0;/* Sensor specified as not having Analog Units */
+ }
+ if ( !IS_THRESHOLD_SENSOR(&sr->full->cmn) ) {
+ /* Non-Threshold Sensors are not defined as having analog */
+ /* But.. We have one with defined with Analog Units */
+ if ( (sr->full->cmn.unit.pct | sr->full->cmn.unit.modifier |
+ sr->full->cmn.unit.type.base |
+ sr->full->cmn.unit.type.modifier)) {
+ /* And it does have the necessary units specs */
+ if ( !(intf->manufacturer_id == IPMI_OEM_HP) ) {
+ /* But to be safe we only do this for HP */
+ return 0;
+ }
+ } else {
+ return 0;
+ }
}
/*
* If sensor has linearization, then we should be able to update the
* reading factors and if we cannot fail the conversion.
*/
- if (full->linearization >= SDR_SENSOR_L_NONLINEAR &&
- full->linearization <= 0x7F) {
- if (ipmi_sensor_get_sensor_reading_factors(intf, full, read) < 0){
- *convert_success = 0;
+ if (sr->full->linearization >= SDR_SENSOR_L_NONLINEAR &&
+ sr->full->linearization <= 0x7F) {
+ if (ipmi_sensor_get_sensor_reading_factors(intf, sr->full, sr->s_reading) < 0){
+ sr->s_reading_valid = 0;
+ return 0;
}
}
- return sdr_convert_sensor_reading(full, read);
+ return 1;
}
/* sdr_convert_sensor_reading - convert raw sensor reading
@@ -672,13 +694,13 @@ ipmi_sdr_get_sensor_type_desc(const uint8_t type)
* ns = not specified
*/
const char *
-ipmi_sdr_get_thresh_status(struct ipmi_rs *rsp, int validread, const char *invalidstr)
+ipmi_sdr_get_thresh_status(struct sensor_reading *sr, const char *invalidstr)
{
uint8_t stat;
- if (!validread) {
+ if (!sr->s_reading_valid) {
return invalidstr;
}
- stat = rsp->data[2];
+ stat = sr->s_data2;
if (stat & SDR_SENSOR_STAT_LO_NR) {
if (verbose)
return "Lower Non-Recoverable";
@@ -938,7 +960,7 @@ ipmi_sdr_print_sensor_event_status(struct ipmi_intf *intf,
sensor_num, val2str(rsp->ccode, completion_code_vals));
return -1;
}
-
+ /* There is an assumption here that data_len >= 1 */
if (IS_READING_UNAVAILABLE(rsp->data[0])) {
printf(" Event Status : Unavailable\n");
return 0;
@@ -1315,39 +1337,152 @@ print_sensor_min_max(struct sdr_record_full_sensor *full)
/* print_csv_discrete - print csv formatted discrete sensor
*
- * @rsp: response from Get Sensor Reading comand
* @sensor: common sensor structure
- * @validread: validity of get sensor read command data
+ * @sr: sensor reading
*
* returns void
*/
static void
-print_csv_discrete(struct ipmi_rs *rsp,
- struct sdr_record_common_sensor *sensor,
- int validread)
+print_csv_discrete(struct sdr_record_common_sensor *sensor,
+ const struct sensor_reading *sr)
{
- printf("%02Xh,", sensor->keys.sensor_num);
-
- if (validread == 0 || rsp->ccode != 0) {
- printf("ns,%d.%d,No Reading",
+ if (!sr->s_reading_valid || sr->s_reading_unavailable) {
+ printf("%02Xh,ns,%d.%d,No Reading",
+ sensor->keys.sensor_num,
sensor->entity.id,
sensor->entity.instance);
- } else if (rsp->ccode == 0) {
- if (IS_READING_UNAVAILABLE(rsp->data[1])) {
- printf("ns,%d.%d,No Reading",
- sensor->entity.id,
- sensor->entity.instance);
- } else {
- printf("ok,%d.%d,",
- sensor->entity.id,
- sensor->entity.instance);
- ipmi_sdr_print_discrete_state_mini(", ",
- sensor->sensor.type,
- sensor->event_type,
- rsp->data[2],
- rsp->data[3]);
+ return;
+ }
+
+ if (sr->s_has_analog_value) { /* Sensor has an analog value */
+ printf("%s,%s,", sr->s_a_str, sr->s_a_units);
+ } else { /* Sensor has a discrete value */
+ printf("%02Xh,", sensor->keys.sensor_num);
+ }
+ printf("ok,%d.%d,",
+ sensor->entity.id,
+ sensor->entity.instance);
+ ipmi_sdr_print_discrete_state_mini(NULL, ", ",
+ sensor->sensor.type,
+ sensor->event_type,
+ sr->s_data2,
+ sr->s_data3);
+}
+
+/* ipmi_sdr_read_sensor_value - read sensor value
+ *
+ * @intf Interface pointer
+ * @sensor Common sensor component pointer
+ * @sdr_record_type Type of sdr sensor record
+ * @precision decimal precision for analog format conversion
+ *
+ * returns a pointer to sensor value reading data structure
+ */
+struct sensor_reading *
+ipmi_sdr_read_sensor_value(struct ipmi_intf *intf,
+ struct sdr_record_common_sensor *sensor,
+ uint8_t sdr_record_type, int precision)
+{
+ static struct sensor_reading sr;
+
+ if (sensor == NULL)
+ return NULL;
+
+ /* Initialize to reading valid value of zero */
+ memset(&sr, 0, sizeof(sr));
+
+ switch (sdr_record_type) {
+ int idlen;
+ case (SDR_RECORD_TYPE_FULL_SENSOR):
+ sr.full = (struct sdr_record_full_sensor *)sensor;
+ idlen = sr.full->id_code & 0x1f;
+ idlen = idlen < sizeof(sr.s_id) ?
+ idlen : sizeof(sr.s_id) - 1;
+ memcpy(sr.s_id, sr.full->id_string, idlen);
+ break;
+ case SDR_RECORD_TYPE_COMPACT_SENSOR:
+ sr.compact = (struct sdr_record_compact_sensor *)sensor;
+ idlen = sr.compact->id_code & 0x1f;
+ idlen = idlen < sizeof(sr.s_id) ?
+ idlen : sizeof(sr.s_id) - 1;
+ memcpy(sr.s_id, sr.compact->id_string, idlen);
+ break;
+ default:
+ return NULL;
+ }
+
+ /*
+ * Get current reading via IPMI interface
+ */
+ struct ipmi_rs *rsp;
+ rsp = ipmi_sdr_get_sensor_reading_ipmb(intf,
+ sensor->keys.sensor_num,
+ sensor->keys.owner_id,
+ sensor->keys.lun,
+ sensor->keys.channel);
+ sr.s_a_val = 0.0; /* init analog value to a floating point 0 */
+ sr.s_a_str[0] = '\0'; /* no converted analog value string */
+ sr.s_a_units = ""; /* no converted analog units units */
+
+
+ if (rsp == NULL) {
+ lprintf(LOG_DEBUG, "Error reading sensor %s (#%02x)",
+ sr.s_id, sensor->keys.sensor_num);
+ return &sr;
+ }
+
+ if (rsp->ccode) {
+ if ( !((sr.full && rsp->ccode == 0xcb) ||
+ (sr.compact && rsp->ccode == 0xcd)) ) {
+ lprintf(LOG_DEBUG,
+ "Error reading sensor %s (#%02x): %s", sr.s_id,
+ sensor->keys.sensor_num,
+ val2str(rsp->ccode, completion_code_vals));
}
+ return &sr;
}
+
+ if (rsp->data_len < 2) {
+ /*
+ * We must be returned both a value (data[0]), and the validity
+ * of the value (data[1]), in order to correctly interpret
+ * the reading. If we don't have both of these we can't have
+ * a valid sensor reading.
+ */
+ lprintf(LOG_DEBUG, "Error reading sensor %s invalid len %d",
+ sr.s_id, rsp->data_len);
+ return &sr;
+ }
+
+
+ if (IS_READING_UNAVAILABLE(rsp->data[1]))
+ sr.s_reading_unavailable = 1;
+
+ if (IS_SCANNING_DISABLED(rsp->data[1])) {
+ sr.s_scanning_disabled = 1;
+ lprintf(LOG_DEBUG, "Sensor %s (#%02x) scanning disabled",
+ sr.s_id, sensor->keys.sensor_num);
+ return &sr;
+ }
+ sr.s_reading_valid = 1;
+ sr.s_reading = rsp->data[0];
+ if (rsp->data_len > 2)
+ sr.s_data2 = rsp->data[2];
+ if (rsp->data_len > 3)
+ sr.s_data3 = rsp->data[3];
+ if (sdr_sensor_has_analog_reading(intf, &sr)) {
+ sr.s_has_analog_value = 1;
+ sr.s_a_val = sdr_convert_sensor_reading(sr.full, sr.s_reading);
+ /* determine units string with possible modifiers */
+ sr.s_a_units = ipmi_sdr_get_unit_string(sr.full->cmn.unit.pct,
+ sr.full->cmn.unit.modifier,
+ sr.full->cmn.unit.type.base,
+ sr.full->cmn.unit.type.modifier);
+ snprintf(sr.s_a_str, sizeof(sr.s_a_str), "%.*f",
+ (sr.s_a_val == (int) sr.s_a_val) ? 0 :
+ precision, sr.s_a_val);
+ }
+ return &sr;
}
/* ipmi_sdr_print_sensor_fc - print full & compact SDR records
@@ -1364,88 +1499,21 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf,
struct sdr_record_common_sensor *sensor,
uint8_t sdr_record_type)
{
- const char *unitstr = NULL;
- char sval[16], desc[17];
- int i = 0, validread = 1;
- double val = 0.0;
- struct ipmi_rs *rsp;
+ char sval[16];
+ int i = 0;
uint8_t target, lun, channel;
- struct sdr_record_full_sensor *full = NULL;
- struct sdr_record_compact_sensor *compact = NULL;
+ struct sensor_reading *sr;
- if (sensor == NULL)
+
+ sr = ipmi_sdr_read_sensor_value(intf, sensor, sdr_record_type, 2);
+
+ if (sr == NULL)
return -1;
- switch (sdr_record_type) {
- case (SDR_RECORD_TYPE_FULL_SENSOR):
- full = (struct sdr_record_full_sensor *)sensor;
- break;
- case SDR_RECORD_TYPE_COMPACT_SENSOR:
- compact = (struct sdr_record_compact_sensor *)sensor;
- break;
- default:
- return -1;
- }
-
target = sensor->keys.owner_id;
lun = sensor->keys.lun;
channel = sensor->keys.channel;
- memset(desc, 0, sizeof (desc));
- if (full) {
- snprintf(desc, (full->id_code & 0x1f) + 1, "%s", full->id_string);
- } else {
- snprintf(desc, (compact->id_code & 0x1f) + 1, "%s", compact->id_string);
- }
- /* get sensor reading */
- rsp = ipmi_sdr_get_sensor_reading_ipmb(intf, sensor->keys.sensor_num,
- sensor->keys.owner_id, sensor->keys.lun, sensor->keys.channel);
- if (rsp == NULL) {
- lprintf(LOG_DEBUG, "Error reading sensor %s (#%02x)",
- desc, sensor->keys.sensor_num);
- validread = 0;
- }
- else if (rsp->ccode > 0) {
- validread = 0;
- if ( !((full && rsp->ccode == 0xcb) ||
- (compact && rsp->ccode == 0xcd)) ) {
- lprintf(LOG_DEBUG,
- "Error reading sensor %s (#%02x): %s", desc,
- sensor->keys.sensor_num,
- val2str(rsp->ccode, completion_code_vals));
- }
- } else {
- if (IS_READING_UNAVAILABLE(rsp->data[1])) {
- /* sensor reading unavailable */
- validread = 0;
- } else if (IS_SCANNING_DISABLED(rsp->data[1])) {
- validread = 0;
- /* Sensor Scanning Disabled */
- lprintf(LOG_DEBUG, "Sensor %s (#%02x) scanning disabled",
- desc, sensor->keys.sensor_num);
- /*
- * No scanning, but when we read we got something other than 0.
- * Alas, someone believes that this might mean there is more
- * interesting information yet to be gained, so the keep digging
- * the hole deeper. Beware of miss-information if you take
- * this path.
- */
- if (rsp->data[0] != 0) {
- val = sdr_convert_analog_reading(intf, full, rsp->data[0], &validread);
- if (val != 0.0) /* .. an 0.0 might as well be valid */
- validread = 1;
- }
- } else {
- val = sdr_convert_analog_reading(intf, full, rsp->data[0], &validread);
- }
- }
-
-
- /* determine units with possible modifiers */
- unitstr = ipmi_sdr_get_unit_string(sensor->unit.pct,
- sensor->unit.modifier,
- sensor->unit.type.base,
- sensor->unit.type.modifier);
/*
* CSV OUTPUT
*/
@@ -1454,22 +1522,24 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf,
/*
* print sensor name, reading, unit, state
*/
- printf("%s,", desc);
+ printf("%s,", sr->s_id);
if (!IS_THRESHOLD_SENSOR(sensor)) {
/* Discrete/Non-Threshold */
- print_csv_discrete(rsp, sensor, validread);
+ print_csv_discrete(sensor, sr);
printf("\n");
}
else {
/* Threshold Analog & Discrete*/
- if (validread) {
- if (full && !UNITS_ARE_DISCRETE(&full->cmn)) {
+ if (sr->s_reading_valid) {
+ if (sr->s_has_analog_value) {
/* Analog/Threshold */
- printf("%.*f,", (val == (int) val) ? 0 : 3, val);
- printf("%s,%s", unitstr,
- ipmi_sdr_get_thresh_status(rsp, validread, "ns"));
+ printf("%.*f,", (sr->s_a_val ==
+ (int) sr->s_a_val) ? 0 : 3,
+ sr->s_a_val);
+ printf("%s,%s", sr->s_a_units,
+ ipmi_sdr_get_thresh_status(sr, "ns"));
} else { /* Discrete/Threshold */
- print_csv_discrete(rsp, sensor, validread);
+ print_csv_discrete(sensor, sr);
}
} else {
printf(",,ns");
@@ -1482,35 +1552,35 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf,
ipmi_sdr_get_sensor_type_desc(sensor->sensor.
type));
- if (full) {
- SENSOR_PRINT_CSV(full, full->analog_flag.nominal_read,
- full->nominal_read);
- SENSOR_PRINT_CSV(full, full->analog_flag.normal_min,
- full->normal_min);
- SENSOR_PRINT_CSV(full, full->analog_flag.normal_max,
- full->normal_max);
- SENSOR_PRINT_CSV(full, sensor->mask.type.threshold.read.unr,
- full->threshold.upper.non_recover);
- SENSOR_PRINT_CSV(full, sensor->mask.type.threshold.read.ucr,
- full->threshold.upper.critical);
- SENSOR_PRINT_CSV(full, sensor->mask.type.threshold.read.unc,
- full->threshold.upper.non_critical);
- SENSOR_PRINT_CSV(full, sensor->mask.type.threshold.read.lnr,
- full->threshold.lower.non_recover);
- SENSOR_PRINT_CSV(full, sensor->mask.type.threshold.read.lcr,
- full->threshold.lower.critical);
- SENSOR_PRINT_CSV(full, sensor->mask.type.threshold.read.lnc,
- full->threshold.lower.non_critical);
+ if (sr->full) {
+ SENSOR_PRINT_CSV(sr->full, sr->full->analog_flag.nominal_read,
+ sr->full->nominal_read);
+ SENSOR_PRINT_CSV(sr->full, sr->full->analog_flag.normal_min,
+ sr->full->normal_min);
+ SENSOR_PRINT_CSV(sr->full, sr->full->analog_flag.normal_max,
+ sr->full->normal_max);
+ SENSOR_PRINT_CSV(sr->full, sensor->mask.type.threshold.read.unr,
+ sr->full->threshold.upper.non_recover);
+ SENSOR_PRINT_CSV(sr->full, sensor->mask.type.threshold.read.ucr,
+ sr->full->threshold.upper.critical);
+ SENSOR_PRINT_CSV(sr->full, sensor->mask.type.threshold.read.unc,
+ sr->full->threshold.upper.non_critical);
+ SENSOR_PRINT_CSV(sr->full, sensor->mask.type.threshold.read.lnr,
+ sr->full->threshold.lower.non_recover);
+ SENSOR_PRINT_CSV(sr->full, sensor->mask.type.threshold.read.lcr,
+ sr->full->threshold.lower.critical);
+ SENSOR_PRINT_CSV(sr->full, sensor->mask.type.threshold.read.lnc,
+ sr->full->threshold.lower.non_critical);
- if (UNITS_ARE_DISCRETE(&full->cmn)) {
- printf("0x%02X,0x%02X", full->sensor_min, full->sensor_max);
+ if (UNITS_ARE_DISCRETE(sensor)) {
+ printf("0x%02X,0x%02X", sr->full->sensor_min, sr->full->sensor_max);
}
else {
printf("%.3f,%.3f",
- sdr_convert_sensor_reading(full,
- full->sensor_min),
- sdr_convert_sensor_reading(full,
- full->sensor_max));
+ sdr_convert_sensor_reading(sr->full,
+ sr->full->sensor_min),
+ sdr_convert_sensor_reading(sr->full,
+ sr->full->sensor_max));
}
} else {
printf(",,,,,,,,,,");
@@ -1530,48 +1600,35 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf,
/*
* print sensor name, reading, state
*/
- printf("%-16s | ", desc);
+ printf("%-16s | ", sr->s_id);
- i = 0;
memset(sval, 0, sizeof (sval));
- if (validread) {
- if (IS_THRESHOLD_SENSOR(sensor)) {
- /* Threshold Analog & Discrete */
- if( full && (!UNITS_ARE_DISCRETE(sensor)) ) {
- i += snprintf(sval, sizeof (sval), "%.*f %s",
- (val == (int) val) ? 0 : 2, val,
- unitstr);
- } else /* Discrete */
- /*
- * N.B. data[0] is supposed to be ignored if not
- * an analog reading. Should this be data[2]
- * like the following non-threshold print?
- */
- i += snprintf(sval, sizeof (sval), "0x%02X", rsp->data[0]);
- }
- else {
- /* Discrete */
- i += snprintf(sval, sizeof (sval), "0x%02x", rsp->data[2]);
- }
+ if (sr->s_reading_valid) {
+ if( sr->s_has_analog_value ) {
+ snprintf(sval, sizeof (sval), "%s %s",
+ sr->s_a_str,
+ sr->s_a_units);
+ } else /* Discrete */
+ snprintf(sval, sizeof(sval),
+ "0x%02x", sr->s_reading);
}
- else if (rsp && (rsp->ccode == 0) && IS_SCANNING_DISABLED(rsp->data[1]))
- i += snprintf(sval, sizeof (sval), full ? "disabled " : "Not Readable ");
+ else if (sr->s_scanning_disabled)
+ snprintf(sval, sizeof (sval), sr->full ? "disabled" : "Not Readable");
else
- i += snprintf(sval, sizeof (sval), full ? "no reading " : "Not Readable ");
+ snprintf(sval, sizeof (sval), sr->full ? "no reading" : "Not Readable");
printf("%s", sval);
- i--;
- for (; i < sizeof (sval); i++)
+ for (i = strlen(sval); i <= sizeof (sval); i++)
printf(" ");
printf(" | ");
if (IS_THRESHOLD_SENSOR(sensor)) {
- printf("%s", ipmi_sdr_get_thresh_status(rsp, validread, "ns"));
+ printf("%s", ipmi_sdr_get_thresh_status(sr, "ns"));
}
else {
- printf("%s", validread ? "ok" : "ns");
+ printf("%s", sr->s_reading_valid ? "ok" : "ns");
}
printf("\n");
@@ -1582,44 +1639,48 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf,
* print sensor name, number, state, entity, reading
*/
printf("%-16s | %02Xh | ",
- desc, sensor->keys.sensor_num);
+ sr->s_id, sensor->keys.sensor_num);
if (IS_THRESHOLD_SENSOR(sensor)) {
/* Threshold Analog & Discrete */
printf("%-3s | %2d.%1d | ",
- ipmi_sdr_get_thresh_status(rsp, validread, "ns"),
+ ipmi_sdr_get_thresh_status(sr, "ns"),
sensor->entity.id, sensor->entity.instance);
}
else {
- /* Discrete */
+ /* Non Threshold Analog & Discrete */
printf("%-3s | %2d.%1d | ",
- (validread ? "ok" : "ns"),
+ (sr->s_reading_valid ? "ok" : "ns"),
sensor->entity.id, sensor->entity.instance);
}
- i = 0;
memset(sval, 0, sizeof (sval));
- if (validread) {
+ if (sr->s_reading_valid) {
if (IS_THRESHOLD_SENSOR(sensor) &&
- (full && !UNITS_ARE_DISCRETE(sensor)) ) {
+ sr->s_has_analog_value ) {
/* Threshold Analog */
- i += snprintf(sval, sizeof (sval), "%.*f %s",
- (val == (int) val) ? 0 : 2, val,
- unitstr);
+ snprintf(sval, sizeof (sval), "%s %s",
+ sr->s_a_str,
+ sr->s_a_units);
} else {
- /* Discrete & Threshold/Discrete */
- ipmi_sdr_print_discrete_state_mini(", ",
+ /* Analog & Discrete & Threshold/Discrete */
+ char *header = NULL;
+ if (sr->s_has_analog_value) { /* Sensor has an analog value */
+ printf("%s %s", sr->s_a_str, sr->s_a_units);
+ header = ", ";
+ }
+ ipmi_sdr_print_discrete_state_mini(header, ", ",
sensor->sensor.type,
sensor->event_type,
- rsp->data[2],
- rsp->data[3]);
+ sr->s_data2,
+ sr->s_data3);
}
}
- else if (rsp && (rsp->ccode == 0) && IS_SCANNING_DISABLED(rsp->data[1]))
- i += snprintf(sval, sizeof (sval), "Disabled");
+ else if (sr->s_scanning_disabled)
+ snprintf(sval, sizeof (sval), "Disabled");
else
- i += snprintf(sval, sizeof (sval), "No Reading");
+ snprintf(sval, sizeof (sval), "No Reading");
printf("%s\n", sval);
return 0; /* done */
@@ -1629,7 +1690,7 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf,
*/
printf("Sensor ID : %s (0x%x)\n",
- desc, sensor->keys.sensor_num);
+ sr->s_id, sensor->keys.sensor_num);
printf(" Entity ID : %d.%d (%s)\n",
sensor->entity.id, sensor->entity.instance,
val2str(sensor->entity.id, entity_id_vals));
@@ -1641,13 +1702,15 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf,
lprintf(LOG_DEBUG, " Event Type Code : 0x%02x",
sensor->event_type);
- if (compact && validread && verbose > 1)
- printbuf(rsp->data, rsp->data_len, "COMPACT SENSOR");
-
printf(" Sensor Reading : ");
- if (validread)
- printf("%xh\n", rsp ? rsp->data[0] : 0);
- else if (rsp && (rsp->ccode == 0) && IS_SCANNING_DISABLED(rsp->data[1]))
+ if (sr->s_reading_valid) {
+ if (sr->s_has_analog_value) { /* Sensor has an analog value */
+ printf("%s %s\n", sr->s_a_str, sr->s_a_units);
+ } else {
+ printf("%xh\n", sr->s_reading);
+ }
+ }
+ else if (sr->s_scanning_disabled)
printf("Disabled\n");
else
printf("Not Reading\n");
@@ -1671,8 +1734,8 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf,
ipmi_sdr_print_discrete_state("States Asserted",
sensor->sensor.type,
sensor->event_type,
- rsp ? rsp->data[2] : 0,
- rsp ? rsp->data[3] : 0);
+ sr->s_data2,
+ sr->s_data3);
ipmi_sdr_print_sensor_mask(&sensor->mask, sensor->sensor.type,
sensor->event_type, DISCRETE_SENSOR);
ipmi_sdr_print_sensor_event_status(intf,
@@ -1690,7 +1753,7 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf,
target,
lun, channel);
printf(" OEM : %X\n",
- full ? full->oem : compact->oem);
+ sr->full ? sr->full->oem : sr->compact->oem);
printf("\n");
return 0; /* done */
@@ -1699,48 +1762,50 @@ ipmi_sdr_print_sensor_fc(struct ipmi_intf *intf,
ipmi_sdr_get_sensor_type_desc(sensor->sensor.type));
printf(" Sensor Reading : ");
- if (validread) {
- if (full) {
- uint16_t raw_tol = __TO_TOL(full->mtol);
- if (UNITS_ARE_DISCRETE(&full->cmn)) {
- printf("0x%02X (+/- 0x%02X) %s\n", rsp->data[0], raw_tol, unitstr);
+ if (sr->s_reading_valid) {
+ if (sr->full) {
+ uint16_t raw_tol = __TO_TOL(sr->full->mtol);
+ if (UNITS_ARE_DISCRETE(sensor)) {
+ printf("0x%02X (+/- 0x%02X) %s\n",
+ sr->s_reading, raw_tol, sr->s_a_units);
}
else {
- double tol = sdr_convert_sensor_tolerance(full, raw_tol);
+ double tol = sdr_convert_sensor_tolerance(sr->full, raw_tol);
printf("%.*f (+/- %.*f) %s\n",
- (val == (int) val) ? 0 : 3,
- val, (tol == (int) tol) ? 0 : 3, tol, unitstr);
+ (sr->s_a_val == (int) sr->s_a_val) ? 0 : 3,
+ sr->s_a_val, (tol == (int) tol) ? 0 :
+ 3, tol, sr->s_a_units);
}
} else {
- printf("0x%02X %s\n", rsp->data[0], unitstr);
+ printf("0x%02X %s\n", sr->s_reading, sr->s_a_units);
}
- } else if (rsp && (rsp->ccode == 0) && IS_SCANNING_DISABLED(rsp->data[1]))
+ } else if (sr->s_scanning_disabled)
printf("Disabled\n");
else
printf("No Reading\n");
printf(" Status : %s\n",
- ipmi_sdr_get_thresh_status(rsp, validread, "Not Available"));
+ ipmi_sdr_get_thresh_status(sr, "Not Available"));
- if(full) {
- SENSOR_PRINT_NORMAL(full, "Nominal Reading", nominal_read);
- SENSOR_PRINT_NORMAL(full, "Normal Minimum", normal_min);
- SENSOR_PRINT_NORMAL(full, "Normal Maximum", normal_max);
+ if(sr->full) {
+ SENSOR_PRINT_NORMAL(sr->full, "Nominal Reading", nominal_read);
+ SENSOR_PRINT_NORMAL(sr->full, "Normal Minimum", normal_min);
+ SENSOR_PRINT_NORMAL(sr->full, "Normal Maximum", normal_max);
- SENSOR_PRINT_THRESH(full, "Upper non-recoverable", upper.non_recover, unr);
- SENSOR_PRINT_THRESH(full, "Upper critical", upper.critical, ucr);
- SENSOR_PRINT_THRESH(full, "Upper non-critical", upper.non_critical, unc);
- SENSOR_PRINT_THRESH(full, "Lower non-recoverable", lower.non_recover, lnr);
- SENSOR_PRINT_THRESH(full, "Lower critical", lower.critical, lcr);
- SENSOR_PRINT_THRESH(full, "Lower non-critical", lower.non_critical, lnc);
+ SENSOR_PRINT_THRESH(sr->full, "Upper non-recoverable", upper.non_recover, unr);
+ SENSOR_PRINT_THRESH(sr->full, "Upper critical", upper.critical, ucr);
+ SENSOR_PRINT_THRESH(sr->full, "Upper non-critical", upper.non_critical, unc);
+ SENSOR_PRINT_THRESH(sr->full, "Lower non-recoverable", lower.non_recover, lnr);
+ SENSOR_PRINT_THRESH(sr->full, "Lower critical", lower.critical, lcr);
+ SENSOR_PRINT_THRESH(sr->full, "Lower non-critical", lower.non_critical, lnc);
}
- ipmi_sdr_print_sensor_hysteresis(sensor, full,
- full->threshold.hysteresis.positive, "Positive Hysteresis");
+ ipmi_sdr_print_sensor_hysteresis(sensor, sr->full,
+ sr->full->threshold.hysteresis.positive, "Positive Hysteresis");
- ipmi_sdr_print_sensor_hysteresis(sensor, full,
- full->threshold.hysteresis.negative, "Negative Hysteresis");
+ ipmi_sdr_print_sensor_hysteresis(sensor, sr->full,
+ sr->full->threshold.hysteresis.negative, "Negative Hysteresis");
- print_sensor_min_max(full);
+ print_sensor_min_max(sr->full);
printf(" Event Message Control : ");
switch (sensor->sensor.capabilities.event_msg) {
@@ -1866,6 +1931,8 @@ get_offset(uint8_t x)
/* ipmi_sdr_print_discrete_state_mini - print list of asserted states
* for a discrete sensor
*
+ * @header : header string if necessary
+ * @separator : field separator string
* @sensor_type : sensor type code
* @event_type : event type code
* @state : mask of asserted states
@@ -1873,7 +1940,7 @@ get_offset(uint8_t x)
* no meaningful return value
*/
void
-ipmi_sdr_print_discrete_state_mini(const char *separator,
+ipmi_sdr_print_discrete_state_mini(const char *header, const char *separator,
uint8_t sensor_type, uint8_t event_type,
uint8_t state1, uint8_t state2)
{
@@ -1892,6 +1959,9 @@ ipmi_sdr_print_discrete_state_mini(const char *separator,
typ = event_type;
}
+ if (header)
+ printf("%s", header);
+
for (; evt->type != NULL; evt++) {
if ((evt->code != typ) ||
(evt->data != 0xFF))
diff --git a/lib/ipmi_sel.c b/lib/ipmi_sel.c
index 4f50c69..367232b 100644
--- a/lib/ipmi_sel.c
+++ b/lib/ipmi_sel.c
@@ -281,6 +281,15 @@ ipmi_get_oem(struct ipmi_intf * intf)
return IPMI_OEM_UNKNOWN;
}
+ /*
+ * Return the cached manufacturer id if the device is open and
+ * we got an identified OEM owner. Otherwise just attempt to read
+ * it.
+ */
+ if (intf->opened && intf->manufacturer_id != IPMI_OEM_UNKNOWN) {
+ return intf->manufacturer_id;
+ }
+
memset(&req, 0, sizeof(req));
req.msg.netfn = IPMI_NETFN_APP;
req.msg.cmd = BMC_GET_DEVICE_ID;
@@ -299,7 +308,7 @@ ipmi_get_oem(struct ipmi_intf * intf)
devid = (struct ipm_devid_rsp *) rsp->data;
- lprintf(LOG_DEBUG,"Iana: 0x%ul",
+ lprintf(LOG_DEBUG,"Iana: 0x%u",
IPM_DEV_MANUFACTURER_ID(devid->manufacturer_id));
return IPM_DEV_MANUFACTURER_ID(devid->manufacturer_id);
diff --git a/lib/ipmi_sensor.c b/lib/ipmi_sensor.c
index 95429e4..8d41de9 100644
--- a/lib/ipmi_sensor.c
+++ b/lib/ipmi_sensor.c
@@ -143,55 +143,13 @@ ipmi_sensor_print_fc_discrete(struct ipmi_intf *intf,
struct sdr_record_common_sensor *sensor,
uint8_t sdr_record_type)
{
- char id[17];
- char *unitstr = "discrete";
- int validread = 1;
- uint8_t val = 0;
- struct ipmi_rs *rsp;
- struct sdr_record_full_sensor *full = NULL;
- struct sdr_record_compact_sensor *compact = NULL;
+ const char *id;
+ struct sensor_reading *sr;
- if (sensor == NULL)
- return -1;
-
- switch (sdr_record_type) {
- case (SDR_RECORD_TYPE_FULL_SENSOR):
- full = (struct sdr_record_full_sensor *)sensor;
- break;
- case SDR_RECORD_TYPE_COMPACT_SENSOR:
- compact = (struct sdr_record_compact_sensor *)sensor;
- break;
- default:
- return -1;
- }
-
- memset(id, 0, sizeof (id));
- memcpy(id, full ? full->id_string : compact->id_string, 16);
+ sr = ipmi_sdr_read_sensor_value(intf, sensor, sdr_record_type, 3);
- /*
- * Get current reading
- */
- rsp = ipmi_sdr_get_sensor_reading_ipmb(intf,
- sensor->keys.sensor_num,
- sensor->keys.owner_id,
- sensor->keys.lun,
- sensor->keys.channel);
- if (rsp == NULL) {
- /*
- * Why can't we just set validread equal to zero and fall
- * though in the same way ipmi_sdr_print_sensor_fc does?
- * All the cases below correctly handle validread.
- */
- lprintf(LOG_ERR, "Error reading sensor %s (#%02x)",
- id, sensor->keys.sensor_num);
+ if (sr == NULL) {
return -1;
- } else if (rsp->ccode || IS_READING_UNAVAILABLE(rsp->data[1])) {
- validread = 0;
- } else if (IS_SCANNING_DISABLED(rsp->data[1])) {
- validread = 0;
- } else {
- /* convert RAW reading into units */
- val = rsp->data[0];
}
if (csv_output) {
@@ -201,14 +159,20 @@ ipmi_sensor_print_fc_discrete(struct ipmi_intf *intf,
/* output format
* id value units status thresholds....
*/
- printf("%-16s ", id);
- if (validread) {
- printf("| 0x%-8x | %-10s | 0x%02x%02x",
- val,
- unitstr, rsp->data[2], rsp->data[3]);
+ printf("%-16s ", sr->s_id);
+ if (sr->s_reading_valid) {
+ if (sr->s_has_analog_value) {
+ /* don't show discrete component */
+ printf("| %-10s | %-10s | %-6s",
+ sr->s_a_str, sr->s_a_units, "ok");
+ } else {
+ printf("| 0x%-8x | %-10s | 0x%02x%02x",
+ sr->s_reading, "discrete",
+ sr->s_data2, sr->s_data3);
+ }
} else {
printf("| %-10s | %-10s | %-6s",
- "na", unitstr, "na");
+ "na", "discrete", "na");
}
printf("| %-10s| %-10s| %-10s| %-10s| %-10s| %-10s",
"na", "na", "na", "na", "na", "na");
@@ -216,27 +180,22 @@ ipmi_sensor_print_fc_discrete(struct ipmi_intf *intf,
printf("\n");
} else {
printf("Sensor ID : %s (0x%x)\n",
- id, sensor->keys.sensor_num);
+ sr->s_id, sensor->keys.sensor_num);
printf(" Entity ID : %d.%d\n",
sensor->entity.id, sensor->entity.instance);
printf(" Sensor Type (Discrete): %s\n",
ipmi_sdr_get_sensor_type_desc(sensor->sensor.
type));
- if( validread )
+ if( sr->s_reading_valid )
{
+ if (sr->s_has_analog_value) {
+ printf(" Sensor Reading : %s %s\n", sr->s_a_str, sr->s_a_units);
+ }
ipmi_sdr_print_discrete_state("States Asserted",
sensor->sensor.type,
sensor->event_type,
- rsp->data[2],
- rsp->data[3]);
- if (compact) {
- printf(" Raw Data: %X", rsp->data[1]);
- if(rsp->data_len > 2)
- printf(" %X", rsp->data[2]);
- if(rsp->data_len > 3)
- printf(" %X", rsp->data[3]);
- printf("\n");
- }
+ sr->s_data2,
+ sr->s_data3);
printf("\n");
} else {
printf(" Unable to read sensor: Device Not Present\n\n");
@@ -244,7 +203,7 @@ ipmi_sensor_print_fc_discrete(struct ipmi_intf *intf,
}
}
- return (validread ? 0 : -1 );
+ return (sr->s_reading_valid ? 0 : -1 );
}
static void
@@ -272,100 +231,50 @@ ipmi_sensor_print_fc_threshold(struct ipmi_intf *intf,
struct sdr_record_common_sensor *sensor,
uint8_t sdr_record_type)
{
- const char *unitstr = NULL;
- char id[17];
- int validread = 1, thresh_available = 1;
- double val = 0.0; /* converted analog value if a valid read */
- uint8_t get_sens_read = 0;/* discrete value if a valid read*/
+ int thresh_available = 1;
struct ipmi_rs *rsp;
- const char *thresh_status = "";
- struct sdr_record_full_sensor *full = NULL;
- struct sdr_record_compact_sensor *compact = NULL;
+ struct sensor_reading *sr;
- if (sensor == NULL)
- return -1;
-
- switch (sdr_record_type) {
- case (SDR_RECORD_TYPE_FULL_SENSOR):
- full = (struct sdr_record_full_sensor *)sensor;
- break;
- case SDR_RECORD_TYPE_COMPACT_SENSOR:
- compact = (struct sdr_record_compact_sensor *)sensor;
- break;
- default:
- return -1;
- }
-
- memset(id, 0, sizeof (id));
- memcpy(id, full ? full->id_string : compact->id_string, 16);
+ sr = ipmi_sdr_read_sensor_value(intf, sensor, sdr_record_type, 3);
- /*
- * Get current reading
- */
- rsp = ipmi_sdr_get_sensor_reading_ipmb(intf,
- sensor->keys.sensor_num,
- sensor->keys.owner_id,
- sensor->keys.lun,
- sensor->keys.channel);
- if (rsp == NULL) {
- /*
- * Why can't we just set validread equal to zero and fall
- * though in the same way ipmi_sdr_print_sensor_fc does?
- * All the cases below correctly handle validread.
- */
- lprintf(LOG_ERR, "Error reading sensor %s (#%02x)",
- id, sensor->keys.sensor_num);
+ if (sr == NULL) {
return -1;
- } else if (rsp->ccode || IS_READING_UNAVAILABLE(rsp->data[1])) {
- validread = 0;
- } else if (IS_SCANNING_DISABLED(rsp->data[1])) {
- validread = 0;
- } else {
-
- /* Store off for use later */
- get_sens_read = rsp->data[0];
-
- val = sdr_convert_analog_reading(intf, full, get_sens_read, &validread);
- thresh_status = ipmi_sdr_get_thresh_status(rsp, validread, "ns");
}
+ const char *thresh_status = ipmi_sdr_get_thresh_status(sr, "ns");
+
/*
- * Figure out units
- */
- unitstr = ipmi_sdr_get_unit_string(sensor->unit.pct,
- sensor->unit.modifier,
- sensor->unit.type.base,
- sensor->unit.type.modifier);
- /*
* Get sensor thresholds
*/
- rsp = ipmi_sdr_get_sensor_thresholds(intf, sensor->keys.sensor_num,
- sensor->keys.owner_id, sensor->keys.lun, sensor->keys.channel);
- if ((rsp == NULL) || (rsp->ccode > 0))
+ rsp = ipmi_sdr_get_sensor_thresholds(intf,
+ sensor->keys.sensor_num, sensor->keys.owner_id,
+ sensor->keys.lun, sensor->keys.channel);
+
+ if ((rsp == NULL) || (rsp->ccode > 0) || (rsp->data_len == 0))
thresh_available = 0;
if (csv_output) {
- /* NOT IPMLEMENTED */
+ /* NOT IMPLEMENTED */
} else {
if (verbose == 0) {
/* output format
* id value units status thresholds....
*/
- printf("%-16s ", id);
- if (validread) {
- if (full && !UNITS_ARE_DISCRETE(sensor))
+ printf("%-16s ", sr->s_id);
+ if (sr->s_reading_valid) {
+ if (sr->s_has_analog_value)
printf("| %-10.3f | %-10s | %-6s",
- val, unitstr, thresh_status);
+ sr->s_a_val, sr->s_a_units, thresh_status);
else
printf("| 0x%-8x | %-10s | %-6s",
- get_sens_read, unitstr, thresh_status);
+ sr->s_reading, sr->s_a_units, thresh_status);
} else {
printf("| %-10s | %-10s | %-6s",
- "na", unitstr, "na");
+ "na", sr->s_a_units, "na");
}
- if (thresh_available && full) {
+ if (thresh_available && sr->full) {
#define PTS(bit, dataidx) { \
- print_thresh_setting(full, rsp->data[0] & (bit), \
+ print_thresh_setting(sr->full, rsp->data[0] & (bit), \
rsp->data[(dataidx)], "| ", "%-10.3f", "0x-8x", "%-10s"); \
}
PTS(LOWER_NON_RECOV_SPECIFIED, 3);
@@ -384,7 +293,7 @@ ipmi_sensor_print_fc_threshold(struct ipmi_intf *intf,
printf("\n");
} else {
printf("Sensor ID : %s (0x%x)\n",
- id, sensor->keys.sensor_num);
+ sr->s_id, sensor->keys.sensor_num);
printf(" Entity ID : %d.%d\n",
sensor->entity.id, sensor->entity.instance);
@@ -394,32 +303,35 @@ ipmi_sensor_print_fc_threshold(struct ipmi_intf *intf,
type));
printf(" Sensor Reading : ");
- if (validread) {
- if (full) {
- uint16_t raw_tol = __TO_TOL(full->mtol);
- if (!UNITS_ARE_DISCRETE(sensor)) {
+ if (sr->s_reading_valid) {
+ if (sr->full) {
+ uint16_t raw_tol = __TO_TOL(sr->full->mtol);
+ if (sr->s_has_analog_value) {
double tol =
- sdr_convert_sensor_tolerance(full,
+ sdr_convert_sensor_tolerance(sr->full,
raw_tol);
printf("%.*f (+/- %.*f) %s\n",
- (val == (int) val) ? 0 : 3, val,
+ (sr->s_a_val == (int)
+ sr->s_a_val) ? 0 : 3,
+ sr->s_a_val,
(tol == (int) tol) ? 0 : 3, tol,
- unitstr);
+ sr->s_a_units);
} else {
printf("0x%x (+/- 0x%x) %s\n",
- get_sens_read,
+ sr->s_reading,
raw_tol,
- unitstr);
+ sr->s_a_units);
}
} else {
- printf("0x%x %s\n", get_sens_read, unitstr);
+ printf("0x%x %s\n", sr->s_reading,
+ sr->s_a_units);
}
printf(" Status : %s\n", thresh_status);
if (thresh_available) {
- if (full) {
+ if (sr->full) {
#define PTS(bit, dataidx, str) { \
-print_thresh_setting(full, rsp->data[0] & (bit), \
+print_thresh_setting(sr->full, rsp->data[0] & (bit), \
rsp->data[(dataidx)], \
(str), "%.3f\n", "0x%x\n", "%s\n"); \
}
@@ -433,14 +345,14 @@ print_thresh_setting(full, rsp->data[0] & (bit), \
#undef PTS
}
- ipmi_sdr_print_sensor_hysteresis(sensor, full,
- full ? full->threshold.hysteresis.positive :
- compact->threshold.hysteresis.positive,
+ ipmi_sdr_print_sensor_hysteresis(sensor, sr->full,
+ sr->full ? sr->full->threshold.hysteresis.positive :
+ sr->compact->threshold.hysteresis.positive,
"Positive Hysteresis");
- ipmi_sdr_print_sensor_hysteresis(sensor, full,
- full ? full->threshold.hysteresis.negative :
- compact->threshold.hysteresis.negative,
+ ipmi_sdr_print_sensor_hysteresis(sensor, sr->full,
+ sr->full ? sr->full->threshold.hysteresis.negative :
+ sr->compact->threshold.hysteresis.negative,
"Negative Hysteresis");
} else {
printf(" Sensor Threshold Settings not available\n");
@@ -472,7 +384,7 @@ print_thresh_setting(full, rsp->data[0] & (bit), \
}
}
- return (validread ? 0 : -1 );
+ return (sr->s_reading_valid ? 0 : -1 );
}
int
@@ -502,7 +414,6 @@ ipmi_sensor_list(struct ipmi_intf *intf)
}
while ((header = ipmi_sdr_get_next_header(intf, itr)) != NULL) {
- int r = 0;
uint8_t *rec;
rec = ipmi_sdr_get_record(intf, header, itr);
@@ -514,7 +425,7 @@ ipmi_sensor_list(struct ipmi_intf *intf)
switch (header->type) {
case SDR_RECORD_TYPE_FULL_SENSOR:
case SDR_RECORD_TYPE_COMPACT_SENSOR:
- r = ipmi_sensor_print_fc(intf,
+ ipmi_sensor_print_fc(intf,
(struct
sdr_record_common_sensor *)
rec,
@@ -781,9 +692,7 @@ static int
ipmi_sensor_get_reading(struct ipmi_intf *intf, int argc, char **argv)
{
struct sdr_record_list *sdr;
- struct ipmi_rs *rsp;
int i, rc=0;
- double val = 0.0;
if (argc < 1 || strncmp(argv[0], "help", 4) == 0) {
lprintf(LOG_NOTICE, "sensor reading <id> ... [id]");
@@ -802,48 +711,34 @@ ipmi_sensor_get_reading(struct ipmi_intf *intf, int argc, char **argv)
switch (sdr->type) {
case SDR_RECORD_TYPE_FULL_SENSOR:
- /* Only Threshold can return an analog reading */
- if (!IS_THRESHOLD_SENSOR(sdr->record.common)) {
- lprintf(LOG_ERR, "Sensor \"%s\" is a discrete sensor!", argv[i]);
- continue;
- }
- if (sdr->record.full->linearization >= SDR_SENSOR_L_NONLINEAR) {
- lprintf(LOG_ERR, "Sensor \"%s\" non-linear!", argv[i]);
- continue;
- }
- rsp = ipmi_sdr_get_sensor_reading_ipmb(intf,
- sdr->record.common->keys.sensor_num,
- sdr->record.common->keys.owner_id,
- sdr->record.common->keys.lun,
- sdr->record.common->keys.channel);
- if (rsp == NULL) {
- lprintf(LOG_ERR, "Error reading sensor \"%s\"", argv[i]);
+ case SDR_RECORD_TYPE_COMPACT_SENSOR:
+ {
+ struct sensor_reading *sr;
+ struct sdr_record_common_sensor *sensor = sdr->record.common;
+ sr = ipmi_sdr_read_sensor_value(intf, sensor, sdr->type, 3);
+
+ if (sr == NULL) {
rc = -1;
continue;
- } else if (rsp->ccode > 0) {
+ }
+
+ if (!sr->full)
continue;
- } else if (IS_READING_UNAVAILABLE(rsp->data[1])) {
+
+ if (!sr->s_reading_valid)
continue;
- } else if (IS_SCANNING_DISABLED(rsp->data[1])) {
+
+ if (!sr->s_has_analog_value) {
+ lprintf(LOG_ERR, "Sensor \"%s\" is a discrete sensor!", argv[i]);
continue;
- } else if (rsp->data[0] > 0) {
- /* convert RAW reading into units */
- val = sdr_convert_sensor_reading(sdr->record.full, rsp->data[0]);
- } else {
- val = 0.0;
}
-
if (csv_output)
- printf("%s,%.*f\n", argv[i],
- (val == (int)val) ? 0 : 3, val);
+ printf("%s,%s\n", argv[i], sr->s_a_str);
else
- printf("%-16s | %.*f\n", argv[i],
- (val == (int)val) ? 0 : 3, val);
+ printf("%-16s | %s\n", argv[i], sr->s_a_str);
break;
-
- case SDR_RECORD_TYPE_COMPACT_SENSOR:
- break;
+ }
default:
continue;
}
diff --git a/src/plugins/bmc/bmc.c b/src/plugins/bmc/bmc.c
index 9650cbe..0260980 100644
--- a/src/plugins/bmc/bmc.c
+++ b/src/plugins/bmc/bmc.c
@@ -81,6 +81,7 @@ ipmi_bmc_close(struct ipmi_intf *intf)
close(intf->fd);
intf->opened = 0;
+ intf->manufacturer_id = IPMI_OEM_UNKNOWN;
intf->fd = -1;
}
@@ -111,6 +112,7 @@ ipmi_bmc_open(struct ipmi_intf *intf)
sendrecv_fn = (method == BMC_PUTMSG_METHOD) ?
ipmi_bmc_send_cmd_putmsg : ipmi_bmc_send_cmd_ioctl;
+ intf->manufacturer_id = ipmi_get_oem(intf);
return (intf->fd);
}
diff --git a/src/plugins/free/free.c b/src/plugins/free/free.c
index d1bb47a..f89925d 100644
--- a/src/plugins/free/free.c
+++ b/src/plugins/free/free.c
@@ -167,6 +167,7 @@ static int ipmi_free_open(struct ipmi_intf * intf)
#endif
intf->opened = 1;
+ intf->manufacturer_id = ipmi_get_oem(intf);
return 0;
cleanup:
if (dev) {
@@ -197,6 +198,7 @@ static void ipmi_free_close(struct ipmi_intf * intf)
#endif
}
intf->opened = 0;
+ intf->manufacturer_id = IPMI_OEM_UNKNOWN;
}
static struct ipmi_rs * ipmi_free_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
diff --git a/src/plugins/imb/imb.c b/src/plugins/imb/imb.c
index 2ebc492..cb97e81 100644
--- a/src/plugins/imb/imb.c
+++ b/src/plugins/imb/imb.c
@@ -63,6 +63,7 @@ static int ipmi_imb_open(struct ipmi_intf * intf)
}
intf->opened = 1;
+ intf->manufacturer_id = ipmi_get_oem(intf);
return 0;
}
@@ -70,6 +71,7 @@ static int ipmi_imb_open(struct ipmi_intf * intf)
static void ipmi_imb_close(struct ipmi_intf * intf)
{
intf->opened = 0;
+ intf->manufacturer_id = IPMI_OEM_UNKNOWN;
}
static struct ipmi_rs * ipmi_imb_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
diff --git a/src/plugins/lan/lan.c b/src/plugins/lan/lan.c
index 5782843..9752985 100644
--- a/src/plugins/lan/lan.c
+++ b/src/plugins/lan/lan.c
@@ -1981,6 +1981,7 @@ ipmi_lan_close(struct ipmi_intf * intf)
}
intf->opened = 0;
+ intf->manufacturer_id = IPMI_OEM_UNKNOWN;
intf = NULL;
}
@@ -2057,6 +2058,7 @@ ipmi_lan_open(struct ipmi_intf * intf)
return -1;
}
+ intf->manufacturer_id = ipmi_get_oem(intf);
return intf->fd;
}
diff --git a/src/plugins/lanplus/lanplus.c b/src/plugins/lanplus/lanplus.c
index e65db87..a90062f 100644
--- a/src/plugins/lanplus/lanplus.c
+++ b/src/plugins/lanplus/lanplus.c
@@ -3247,6 +3247,7 @@ ipmi_lanplus_close(struct ipmi_intf * intf)
intf->session = NULL;
intf->opened = 0;
+ intf->manufacturer_id = IPMI_OEM_UNKNOWN;
intf = NULL;
}
@@ -3383,7 +3384,6 @@ ipmi_lanplus_open(struct ipmi_intf * intf)
intf->opened = 1;
-
/*
*
* Make sure the BMC supports IPMI v2 / RMCP+
@@ -3441,6 +3441,7 @@ ipmi_lanplus_open(struct ipmi_intf * intf)
if (rc < 0)
goto fail;
+ intf->manufacturer_id = ipmi_get_oem(intf);
return intf->fd;
fail:
diff --git a/src/plugins/lipmi/lipmi.c b/src/plugins/lipmi/lipmi.c
index c9b950c..fa7845d 100644
--- a/src/plugins/lipmi/lipmi.c
+++ b/src/plugins/lipmi/lipmi.c
@@ -57,6 +57,7 @@ static int ipmi_lipmi_open(struct ipmi_intf * intf)
return -1;
}
intf->opened = 1;
+ intf->manufacturer_id = ipmi_get_oem(intf);
return intf->fd;
}
@@ -66,6 +67,7 @@ static void ipmi_lipmi_close(struct ipmi_intf * intf)
close(intf->fd);
intf->fd = -1;
intf->opened = 0;
+ intf->manufacturer_id = IPMI_OEM_UNKNOWN;
}
static struct ipmi_rs * ipmi_lipmi_send_cmd(struct ipmi_intf * intf, struct ipmi_rq * req)
diff --git a/src/plugins/open/open.c b/src/plugins/open/open.c
index e40476c..1c06612 100644
--- a/src/plugins/open/open.c
+++ b/src/plugins/open/open.c
@@ -113,6 +113,7 @@ ipmi_openipmi_open(struct ipmi_intf * intf)
intf->my_addr );
}
+ intf->manufacturer_id = ipmi_get_oem(intf);
return intf->fd;
}
@@ -125,6 +126,7 @@ ipmi_openipmi_close(struct ipmi_intf * intf)
}
intf->opened = 0;
+ intf->manufacturer_id = IPMI_OEM_UNKNOWN;
}
static struct ipmi_rs *
--
1.7.9.5
------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and
threat landscape has changed and how IT managers can respond. Discussions
will include endpoint security, mobile security and the latest in malware
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Ipmitool-devel mailing list
Ipmitool-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ipmitool-devel