blob: 6d13f9297f7ee02b12f71f76319135ea5f0b07a7 [file] [log] [blame]
From 8ce91a760fca8c945540679c92770f841629e179 Mon Sep 17 00:00:00 2001
From: Tony Lee <tony.lee@quantatw.com>
Date: Thu, 31 Oct 2019 17:24:16 +0800
Subject: [PATCH] Fix issues and support signed sensor values
Sensor will get "disable" when the command "ipmitool sdr elist" is
executed that if sensorReadingType is 0x6F.
sensor_units_1 is always set to 0 currently. To support the display of
signed sensor values, we add the attribute "sensorUnits1" to the sensor
mapping yaml. This attribute can be used to determine whether the
sensor is signed.
It were making negative values 0 in get::readingData(). Fix the issue
by using a int32_t and add an overflow check.
Change-Id: I705defcf18805db9ada7d0de0738a59aedab61df
Signed-off-by: Tony Lee <tony.lee@quantatw.com>
---
include/ipmid/types.hpp | 2 ++
scripts/sensor-example.yaml | 2 ++
scripts/writesensor.mako.cpp | 2 ++
sensordatahandler.cpp | 2 --
sensordatahandler.hpp | 31 ++++++++++++++++++++++++++++---
sensorhandler.cpp | 5 ++---
6 files changed, 36 insertions(+), 8 deletions(-)
diff --git a/include/ipmid/types.hpp b/include/ipmid/types.hpp
index e62c8192..bd1fac2b 100644
--- a/include/ipmid/types.hpp
+++ b/include/ipmid/types.hpp
@@ -133,6 +133,7 @@ using Unit = std::string;
using EntityType = uint8_t;
using EntityInst = uint8_t;
using SensorName = std::string;
+using SensorUnits1 = uint8_t;
enum class Mutability
{
@@ -167,6 +168,7 @@ struct Info
Exponent exponentR;
bool hasScale;
Scale scale;
+ SensorUnits1 sensorUnits1;
Unit unit;
std::function<uint8_t(SetSensorReadingReq&, const Info&)> updateFunc;
std::function<GetSensorResponse(const Info&)> getFunc;
diff --git a/scripts/sensor-example.yaml b/scripts/sensor-example.yaml
index 9760cd01..bddd2e6d 100644
--- a/scripts/sensor-example.yaml
+++ b/scripts/sensor-example.yaml
@@ -112,6 +112,8 @@
# Applies for analog sensors, the actual reading value for the sensor is
# Value * 10^N
scale: -3
+ # Indicate Analog Data Format, Rate unit, Modifier unit and Percentage
+ sensorUnits1 : 0x80
mutability: Mutability::Write|Mutability::Read
serviceInterface: org.freedesktop.DBus.Properties
readingType: readingData
diff --git a/scripts/writesensor.mako.cpp b/scripts/writesensor.mako.cpp
index 8b268052..813f9404 100644
--- a/scripts/writesensor.mako.cpp
+++ b/scripts/writesensor.mako.cpp
@@ -49,6 +49,7 @@ extern const IdInfoMap sensors = {
offsetB = sensor.get("offsetB", 0)
bExp = sensor.get("bExp", 0)
rExp = sensor.get("rExp", 0)
+ sensorUnits1 = sensor.get("sensorUnits1", 0)
unit = sensor.get("unit", "")
scale = sensor.get("scale", 0)
hasScale = "true" if "scale" in sensor.keys() else "false"
@@ -91,6 +92,7 @@ extern const IdInfoMap sensors = {
.exponentR = ${rExp},
.hasScale = ${hasScale},
.scale = ${scale},
+ .sensorUnits1 = ${sensorUnits1},
.unit = "${unit}",
.updateFunc = ${updateFunc},
.getFunc = ${getFunc},
diff --git a/sensordatahandler.cpp b/sensordatahandler.cpp
index 06f5f429..fc74b8f8 100644
--- a/sensordatahandler.cpp
+++ b/sensordatahandler.cpp
@@ -7,8 +7,6 @@
#include <ipmid/types.hpp>
#include <ipmid/utils.hpp>
#include <optional>
-#include <phosphor-logging/elog-errors.hpp>
-#include <phosphor-logging/log.hpp>
#include <sdbusplus/message/types.hpp>
#include <xyz/openbmc_project/Common/error.hpp>
diff --git a/sensordatahandler.hpp b/sensordatahandler.hpp
index 5cad58c5..c48140a3 100644
--- a/sensordatahandler.hpp
+++ b/sensordatahandler.hpp
@@ -8,6 +8,8 @@
#include <ipmid/api.hpp>
#include <ipmid/types.hpp>
#include <ipmid/utils.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/log.hpp>
#include <sdbusplus/message/types.hpp>
namespace ipmi
@@ -28,6 +30,7 @@ using ServicePath = std::pair<Path, Service>;
using Interfaces = std::vector<Interface>;
using MapperResponseType = std::map<Path, std::map<Service, Interfaces>>;
+using namespace phosphor::logging;
/** @brief get the D-Bus service and service path
* @param[in] bus - The Dbus bus object
@@ -225,10 +228,32 @@ GetSensorResponse readingData(const Info& sensorInfo)
double value = std::get<T>(propValue) *
std::pow(10, sensorInfo.scale - sensorInfo.exponentR);
+ int32_t rawData =
+ (value - sensorInfo.scaledOffset) / sensorInfo.coefficientM;
- auto rawData = static_cast<uint8_t>((value - sensorInfo.scaledOffset) /
- sensorInfo.coefficientM);
- setReading(rawData, &response);
+ constexpr uint8_t sensorUnitsSignedBits = 2 << 6;
+ constexpr uint8_t signedDataFormat = 0x80;
+ // if sensorUnits1 [7:6] = 10b, sensor is signed
+ if ((sensorInfo.sensorUnits1 & sensorUnitsSignedBits) == signedDataFormat)
+ {
+ if (rawData > std::numeric_limits<int8_t>::max() ||
+ rawData < std::numeric_limits<int8_t>::lowest())
+ {
+ log<level::ERR>("Value out of range");
+ throw std::out_of_range("Value out of range");
+ }
+ setReading(static_cast<int8_t>(rawData), &response);
+ }
+ else
+ {
+ if (rawData > std::numeric_limits<uint8_t>::max() ||
+ rawData < std::numeric_limits<uint8_t>::lowest())
+ {
+ log<level::ERR>("Value out of range");
+ throw std::out_of_range("Value out of range");
+ }
+ setReading(static_cast<uint8_t>(rawData), &response);
+ }
return response;
}
diff --git a/sensorhandler.cpp b/sensorhandler.cpp
index 36998715..260331a0 100644
--- a/sensorhandler.cpp
+++ b/sensorhandler.cpp
@@ -700,9 +700,8 @@ ipmi_ret_t populate_record_from_dbus(get_sdr::SensorDataFullRecordBody* body,
/* Functional sensor case */
if (isAnalogSensor(info->propertyInterfaces.begin()->first))
{
-
- body->sensor_units_1 = 0; // unsigned, no rate, no modifier, not a %
-
+ body->sensor_units_1 = info->sensorUnits1; // default is 0. unsigned, no
+ // rate, no modifier, not a %
/* Unit info */
setUnitFieldsForObject(info, body);
--
2.21.0