| 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 |
| |