xref: /openbmc/phosphor-host-ipmid/sensordatahandler.hpp (revision 1318a5ed36cfd41335e687b54db1c17c0dde8f45)
11bb0d387SDeepak Kodihalli #pragma once
21bb0d387SDeepak Kodihalli 
39cf85627SBrandon Kim #include "config.h"
49cf85627SBrandon Kim 
546470a38SPatrick Venture #include "sensorhandler.hpp"
60b02be92SPatrick Venture 
7e08fbffcSVernon Mauery #include <ipmid/api.hpp>
833250240SVernon Mauery #include <ipmid/types.hpp>
96a98fe7fSVernon Mauery #include <ipmid/utils.hpp>
10c5324251STony Lee #include <phosphor-logging/elog-errors.hpp>
119b745a81SGeorge Liu #include <phosphor-logging/lg2.hpp>
124c008028SWilliam A. Kennington III #include <sdbusplus/message/types.hpp>
130b02be92SPatrick Venture 
14fbc6c9d7SPatrick Williams #include <cmath>
15fbc6c9d7SPatrick Williams 
169714050fSLei YU #ifdef FEATURE_SENSORS_CACHE
17a55e9ea1SLei YU 
189714050fSLei YU extern ipmi::sensor::SensorCacheMap sensorCacheMap;
19a55e9ea1SLei YU 
20a55e9ea1SLei YU // The signal's message type is 0x04 from DBus spec:
21a55e9ea1SLei YU // https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages
22a55e9ea1SLei YU static constexpr auto msgTypeSignal = 0x04;
23a55e9ea1SLei YU 
249714050fSLei YU #endif
259714050fSLei YU 
26e0af7209SDhruvaraj Subhashchandran namespace ipmi
27e0af7209SDhruvaraj Subhashchandran {
28e0af7209SDhruvaraj Subhashchandran namespace sensor
29e0af7209SDhruvaraj Subhashchandran {
30e0af7209SDhruvaraj Subhashchandran 
31e0af7209SDhruvaraj Subhashchandran using Assertion = uint16_t;
32e0af7209SDhruvaraj Subhashchandran using Deassertion = uint16_t;
33e0af7209SDhruvaraj Subhashchandran using AssertionSet = std::pair<Assertion, Deassertion>;
34e0af7209SDhruvaraj Subhashchandran using Service = std::string;
35e0af7209SDhruvaraj Subhashchandran using Path = std::string;
36e0af7209SDhruvaraj Subhashchandran using Interface = std::string;
37e0af7209SDhruvaraj Subhashchandran using ServicePath = std::pair<Path, Service>;
38e0af7209SDhruvaraj Subhashchandran using Interfaces = std::vector<Interface>;
39e0af7209SDhruvaraj Subhashchandran using MapperResponseType = std::map<Path, std::map<Service, Interfaces>>;
408e8152c5SLei YU using PropertyMap = ipmi::PropertyMap;
418e8152c5SLei YU 
42c5324251STony Lee using namespace phosphor::logging;
43e0af7209SDhruvaraj Subhashchandran 
44e0af7209SDhruvaraj Subhashchandran /** @brief Make assertion set from input data
45e0af7209SDhruvaraj Subhashchandran  *  @param[in] cmdData - Input sensor data
46e0af7209SDhruvaraj Subhashchandran  *  @return pair of assertion and deassertion set
47e0af7209SDhruvaraj Subhashchandran  */
48e0af7209SDhruvaraj Subhashchandran AssertionSet getAssertionSet(const SetSensorReadingReq& cmdData);
49e0af7209SDhruvaraj Subhashchandran 
50e0af7209SDhruvaraj Subhashchandran /** @brief send the message to DBus
51e0af7209SDhruvaraj Subhashchandran  *  @param[in] msg - message to send
52e0af7209SDhruvaraj Subhashchandran  *  @return failure status in IPMI error code
53e0af7209SDhruvaraj Subhashchandran  */
542a444d0eSDhruvaraj Subhashchandran ipmi_ret_t updateToDbus(IpmiUpdateData& msg);
55e0af7209SDhruvaraj Subhashchandran 
56816e92b5STom Joseph namespace get
57816e92b5STom Joseph {
58816e92b5STom Joseph 
59b0adbcddSTom Joseph /** @brief Populate sensor name from the D-Bus property associated with the
60b0adbcddSTom Joseph  *         sensor. In the example entry from the yaml, the name of the D-bus
61b0adbcddSTom Joseph  *         property "AttemptsLeft" is the sensor name.
62b0adbcddSTom Joseph  *
63b0adbcddSTom Joseph  *         0x07:
64b0adbcddSTom Joseph  *            sensorType: 195
65b0adbcddSTom Joseph  *            path: /xyz/openbmc_project/state/host0
66b0adbcddSTom Joseph  *            sensorReadingType: 0x6F
67b0adbcddSTom Joseph  *            serviceInterface: org.freedesktop.DBus.Properties
68b0adbcddSTom Joseph  *            readingType: readingAssertion
69b0adbcddSTom Joseph  *            sensorNamePattern: nameProperty
70b0adbcddSTom Joseph  *            interfaces:
71b0adbcddSTom Joseph  *              xyz.openbmc_project.Control.Boot.RebootAttempts:
72b0adbcddSTom Joseph  *                AttemptsLeft:
73b0adbcddSTom Joseph  *                    Offsets:
74b0adbcddSTom Joseph  *                        0xFF:
75b0adbcddSTom Joseph  *                          type: uint32_t
76b0adbcddSTom Joseph  *
77b0adbcddSTom Joseph  *
78b0adbcddSTom Joseph  *  @param[in] sensorInfo - Dbus info related to sensor.
79b0adbcddSTom Joseph  *
80b0adbcddSTom Joseph  *  @return On success return the sensor name for the sensor.
81b0adbcddSTom Joseph  */
nameProperty(const Info & sensorInfo)82b0adbcddSTom Joseph inline SensorName nameProperty(const Info& sensorInfo)
83b0adbcddSTom Joseph {
84b0adbcddSTom Joseph     return sensorInfo.propertyInterfaces.begin()->second.begin()->first;
85b0adbcddSTom Joseph }
86b0adbcddSTom Joseph 
87b0adbcddSTom Joseph /** @brief Populate sensor name from the D-Bus object associated with the
88b0adbcddSTom Joseph  *         sensor. If the object path is /system/chassis/motherboard/dimm0 then
89b0adbcddSTom Joseph  *         the leaf dimm0 is considered as the sensor name.
90b0adbcddSTom Joseph  *
91b0adbcddSTom Joseph  *  @param[in] sensorInfo - Dbus info related to sensor.
92b0adbcddSTom Joseph  *
93b0adbcddSTom Joseph  *  @return On success return the sensor name for the sensor.
94b0adbcddSTom Joseph  */
nameLeaf(const Info & sensorInfo)95b0adbcddSTom Joseph inline SensorName nameLeaf(const Info& sensorInfo)
96b0adbcddSTom Joseph {
97b0adbcddSTom Joseph     return sensorInfo.sensorPath.substr(
98b0adbcddSTom Joseph         sensorInfo.sensorPath.find_last_of('/') + 1,
99b0adbcddSTom Joseph         sensorInfo.sensorPath.length());
100b0adbcddSTom Joseph }
101b0adbcddSTom Joseph 
102b0adbcddSTom Joseph /** @brief Populate sensor name from the D-Bus object associated with the
1032101a447SLotus Xu  *         sensor and the property.
1042101a447SLotus Xu  *         If the object path is /xyz/openbmc_project/inventory/Fan0 and
1052101a447SLotus Xu  *         the property is Present, the leaf Fan0 and the Property is
1062101a447SLotus Xu  *         joined to Fan0_Present as the sensor name.
1072101a447SLotus Xu  *
1082101a447SLotus Xu  *  @param[in] sensorInfo - Dbus info related to sensor.
1092101a447SLotus Xu  *
1102101a447SLotus Xu  *  @return On success return the sensor name for the sensor.
1112101a447SLotus Xu  */
nameLeafProperty(const Info & sensorInfo)1122101a447SLotus Xu inline SensorName nameLeafProperty(const Info& sensorInfo)
1132101a447SLotus Xu {
1142101a447SLotus Xu     return nameLeaf(sensorInfo) + "_" + nameProperty(sensorInfo);
1152101a447SLotus Xu }
1162101a447SLotus Xu 
1172101a447SLotus Xu /** @brief Populate sensor name from the D-Bus object associated with the
118b0adbcddSTom Joseph  *         sensor. If the object path is /system/chassis/motherboard/cpu0/core0
119b0adbcddSTom Joseph  *         then the sensor name is cpu0_core0. The leaf and the parent is put
120b0adbcddSTom Joseph  *         together to get the sensor name.
121b0adbcddSTom Joseph  *
122b0adbcddSTom Joseph  *  @param[in] sensorInfo - Dbus info related to sensor.
123b0adbcddSTom Joseph  *
124b0adbcddSTom Joseph  *  @return On success return the sensor name for the sensor.
125b0adbcddSTom Joseph  */
126b0adbcddSTom Joseph SensorName nameParentLeaf(const Info& sensorInfo);
127b0adbcddSTom Joseph 
128816e92b5STom Joseph /**
129816e92b5STom Joseph  *  @brief Helper function to map the dbus info to sensor's assertion status
130816e92b5STom Joseph  *         for the get sensor reading command.
131816e92b5STom Joseph  *
132816e92b5STom Joseph  *  @param[in] sensorInfo - Dbus info related to sensor.
133816e92b5STom Joseph  *  @param[in] path - Dbus object path.
134816e92b5STom Joseph  *  @param[in] interface - Dbus interface.
135816e92b5STom Joseph  *
136816e92b5STom Joseph  *  @return Response for get sensor reading command.
137816e92b5STom Joseph  */
138816e92b5STom Joseph GetSensorResponse mapDbusToAssertion(const Info& sensorInfo,
139816e92b5STom Joseph                                      const InstancePath& path,
140816e92b5STom Joseph                                      const DbusInterface& interface);
141816e92b5STom Joseph 
1428c2c048eSLei YU #ifndef FEATURE_SENSORS_CACHE
143816e92b5STom Joseph /**
144816e92b5STom Joseph  *  @brief Map the Dbus info to sensor's assertion status in the Get sensor
145816e92b5STom Joseph  *         reading command response.
146816e92b5STom Joseph  *
147816e92b5STom Joseph  *  @param[in] sensorInfo - Dbus info related to sensor.
148816e92b5STom Joseph  *
149816e92b5STom Joseph  *  @return Response for get sensor reading command.
150816e92b5STom Joseph  */
151816e92b5STom Joseph GetSensorResponse assertion(const Info& sensorInfo);
152816e92b5STom Joseph 
153e4014fcaSTom Joseph /**
154e4014fcaSTom Joseph  *  @brief Maps the Dbus info to the reading field in the Get sensor reading
155e4014fcaSTom Joseph  *         command response.
156e4014fcaSTom Joseph  *
157e4014fcaSTom Joseph  *  @param[in] sensorInfo - Dbus info related to sensor.
158e4014fcaSTom Joseph  *
159e4014fcaSTom Joseph  *  @return Response for get sensor reading command.
160e4014fcaSTom Joseph  */
161e4014fcaSTom Joseph GetSensorResponse eventdata2(const Info& sensorInfo);
162e4014fcaSTom Joseph 
163295f17e5STom Joseph /**
164295f17e5STom Joseph  *  @brief readingAssertion is a case where the entire assertion state field
165295f17e5STom Joseph  *         serves as the sensor value.
166295f17e5STom Joseph  *
167295f17e5STom Joseph  *  @tparam T - type of the dbus property related to sensor.
168295f17e5STom Joseph  *  @param[in] sensorInfo - Dbus info related to sensor.
169295f17e5STom Joseph  *
170295f17e5STom Joseph  *  @return Response for get sensor reading command.
171295f17e5STom Joseph  */
172295f17e5STom Joseph template <typename T>
readingAssertion(const Info & sensorInfo)173295f17e5STom Joseph GetSensorResponse readingAssertion(const Info& sensorInfo)
174295f17e5STom Joseph {
1755d82f474SPatrick Williams     sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
176295f17e5STom Joseph     GetSensorResponse response{};
177295f17e5STom Joseph 
1783dc35589SJeremy Kerr     enableScanning(&response);
1793dc35589SJeremy Kerr 
1800b02be92SPatrick Venture     auto service = ipmi::getService(bus, sensorInfo.sensorInterface,
181295f17e5STom Joseph                                     sensorInfo.sensorPath);
182295f17e5STom Joseph 
183295f17e5STom Joseph     auto propValue = ipmi::getDbusProperty(
1840b02be92SPatrick Venture         bus, service, sensorInfo.sensorPath,
185295f17e5STom Joseph         sensorInfo.propertyInterfaces.begin()->first,
186295f17e5STom Joseph         sensorInfo.propertyInterfaces.begin()->second.begin()->first);
187295f17e5STom Joseph 
1884cc42556SSui Chen     setAssertionBytes(static_cast<uint16_t>(std::get<T>(propValue)), &response);
189295f17e5STom Joseph 
190295f17e5STom Joseph     return response;
191295f17e5STom Joseph }
192295f17e5STom Joseph 
193e05b292bSTom Joseph /** @brief Map the Dbus info to the reading field in the Get sensor reading
194e05b292bSTom Joseph  *         command response
195e05b292bSTom Joseph  *
196e05b292bSTom Joseph  *  @tparam T - type of the dbus property related to sensor.
197e05b292bSTom Joseph  *  @param[in] sensorInfo - Dbus info related to sensor.
198e05b292bSTom Joseph  *
199e05b292bSTom Joseph  *  @return Response for get sensor reading command.
200e05b292bSTom Joseph  */
201e05b292bSTom Joseph template <typename T>
readingData(const Info & sensorInfo)202e05b292bSTom Joseph GetSensorResponse readingData(const Info& sensorInfo)
203e05b292bSTom Joseph {
2045d82f474SPatrick Williams     sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
205e05b292bSTom Joseph 
2064cc42556SSui Chen     GetSensorResponse response{};
2074cc42556SSui Chen 
2084cc42556SSui Chen     enableScanning(&response);
209e05b292bSTom Joseph 
2100b02be92SPatrick Venture     auto service = ipmi::getService(bus, sensorInfo.sensorInterface,
211e05b292bSTom Joseph                                     sensorInfo.sensorPath);
212e05b292bSTom Joseph 
2139cf85627SBrandon Kim #ifdef UPDATE_FUNCTIONAL_ON_FAIL
2149cf85627SBrandon Kim     // Check the OperationalStatus interface for functional property
2159cf85627SBrandon Kim     if (sensorInfo.propertyInterfaces.begin()->first ==
2169cf85627SBrandon Kim         "xyz.openbmc_project.Sensor.Value")
2179cf85627SBrandon Kim     {
2189cf85627SBrandon Kim         bool functional = true;
2199cf85627SBrandon Kim         try
2209cf85627SBrandon Kim         {
2219cf85627SBrandon Kim             auto funcValue = ipmi::getDbusProperty(
2229cf85627SBrandon Kim                 bus, service, sensorInfo.sensorPath,
2239cf85627SBrandon Kim                 "xyz.openbmc_project.State.Decorator.OperationalStatus",
2249cf85627SBrandon Kim                 "Functional");
2259cf85627SBrandon Kim             functional = std::get<bool>(funcValue);
2269cf85627SBrandon Kim         }
2279cf85627SBrandon Kim         catch (...)
2289cf85627SBrandon Kim         {
2299cf85627SBrandon Kim             // No-op if Functional property could not be found since this
2309cf85627SBrandon Kim             // check is only valid for Sensor.Value read for hwmonio
2319cf85627SBrandon Kim         }
2329cf85627SBrandon Kim         if (!functional)
2339cf85627SBrandon Kim         {
2349cf85627SBrandon Kim             throw SensorFunctionalError();
2359cf85627SBrandon Kim         }
2369cf85627SBrandon Kim     }
2379cf85627SBrandon Kim #endif
2389cf85627SBrandon Kim 
239e05b292bSTom Joseph     auto propValue = ipmi::getDbusProperty(
2400b02be92SPatrick Venture         bus, service, sensorInfo.sensorPath,
241e05b292bSTom Joseph         sensorInfo.propertyInterfaces.begin()->first,
242e05b292bSTom Joseph         sensorInfo.propertyInterfaces.begin()->second.begin()->first);
243e05b292bSTom Joseph 
244f442e119SVernon Mauery     double value = std::get<T>(propValue) *
245586d35b4SPatrick Venture                    std::pow(10, sensorInfo.scale - sensorInfo.exponentR);
246*1318a5edSPatrick Williams     int32_t rawData =
247*1318a5edSPatrick Williams         (value - sensorInfo.scaledOffset) / sensorInfo.coefficientM;
248e05b292bSTom Joseph 
249c5324251STony Lee     constexpr uint8_t sensorUnitsSignedBits = 2 << 6;
250c5324251STony Lee     constexpr uint8_t signedDataFormat = 0x80;
251c5324251STony Lee     // if sensorUnits1 [7:6] = 10b, sensor is signed
2529154caabSWilly Tu     int32_t minClamp;
2539154caabSWilly Tu     int32_t maxClamp;
254c5324251STony Lee     if ((sensorInfo.sensorUnits1 & sensorUnitsSignedBits) == signedDataFormat)
255c5324251STony Lee     {
2569154caabSWilly Tu         minClamp = std::numeric_limits<int8_t>::lowest();
2579154caabSWilly Tu         maxClamp = std::numeric_limits<int8_t>::max();
258c5324251STony Lee     }
259c5324251STony Lee     else
260c5324251STony Lee     {
2619154caabSWilly Tu         minClamp = std::numeric_limits<uint8_t>::lowest();
2629154caabSWilly Tu         maxClamp = std::numeric_limits<uint8_t>::max();
263c5324251STony Lee     }
2649154caabSWilly Tu     setReading(static_cast<uint8_t>(std::clamp(rawData, minClamp, maxClamp)),
2659154caabSWilly Tu                &response);
266e05b292bSTom Joseph 
267f93b29c5SKonstantin Aladyshev     if (!std::isfinite(value))
268f93b29c5SKonstantin Aladyshev     {
269f93b29c5SKonstantin Aladyshev         response.readingOrStateUnavailable = 1;
270f93b29c5SKonstantin Aladyshev     }
271f93b29c5SKonstantin Aladyshev 
272778f6597SKonstantin Aladyshev     bool critAlarmHigh;
273778f6597SKonstantin Aladyshev     try
274778f6597SKonstantin Aladyshev     {
275778f6597SKonstantin Aladyshev         critAlarmHigh = std::get<bool>(ipmi::getDbusProperty(
276778f6597SKonstantin Aladyshev             bus, service, sensorInfo.sensorPath,
277778f6597SKonstantin Aladyshev             "xyz.openbmc_project.Sensor.Threshold.Critical",
278778f6597SKonstantin Aladyshev             "CriticalAlarmHigh"));
279778f6597SKonstantin Aladyshev     }
280778f6597SKonstantin Aladyshev     catch (const std::exception& e)
281778f6597SKonstantin Aladyshev     {
282778f6597SKonstantin Aladyshev         critAlarmHigh = false;
283778f6597SKonstantin Aladyshev     }
284778f6597SKonstantin Aladyshev     bool critAlarmLow;
285778f6597SKonstantin Aladyshev     try
286778f6597SKonstantin Aladyshev     {
287778f6597SKonstantin Aladyshev         critAlarmLow = std::get<bool>(ipmi::getDbusProperty(
288778f6597SKonstantin Aladyshev             bus, service, sensorInfo.sensorPath,
289778f6597SKonstantin Aladyshev             "xyz.openbmc_project.Sensor.Threshold.Critical",
290778f6597SKonstantin Aladyshev             "CriticalAlarmLow"));
291778f6597SKonstantin Aladyshev     }
292778f6597SKonstantin Aladyshev     catch (const std::exception& e)
293778f6597SKonstantin Aladyshev     {
294778f6597SKonstantin Aladyshev         critAlarmLow = false;
295778f6597SKonstantin Aladyshev     }
296778f6597SKonstantin Aladyshev     bool warningAlarmHigh;
297778f6597SKonstantin Aladyshev     try
298778f6597SKonstantin Aladyshev     {
299778f6597SKonstantin Aladyshev         warningAlarmHigh = std::get<bool>(ipmi::getDbusProperty(
300778f6597SKonstantin Aladyshev             bus, service, sensorInfo.sensorPath,
301778f6597SKonstantin Aladyshev             "xyz.openbmc_project.Sensor.Threshold.Warning",
302778f6597SKonstantin Aladyshev             "WarningAlarmHigh"));
303778f6597SKonstantin Aladyshev     }
304778f6597SKonstantin Aladyshev     catch (const std::exception& e)
305778f6597SKonstantin Aladyshev     {
306778f6597SKonstantin Aladyshev         warningAlarmHigh = false;
307778f6597SKonstantin Aladyshev     }
308778f6597SKonstantin Aladyshev     bool warningAlarmLow;
309778f6597SKonstantin Aladyshev     try
310778f6597SKonstantin Aladyshev     {
311778f6597SKonstantin Aladyshev         warningAlarmLow = std::get<bool>(ipmi::getDbusProperty(
312778f6597SKonstantin Aladyshev             bus, service, sensorInfo.sensorPath,
313d09db492STim Lee             "xyz.openbmc_project.Sensor.Threshold.Warning", "WarningAlarmLow"));
314778f6597SKonstantin Aladyshev     }
315778f6597SKonstantin Aladyshev     catch (const std::exception& e)
316778f6597SKonstantin Aladyshev     {
317778f6597SKonstantin Aladyshev         warningAlarmLow = false;
318778f6597SKonstantin Aladyshev     }
319778f6597SKonstantin Aladyshev     response.thresholdLevelsStates =
32033d90e18SGeorge Liu         (static_cast<uint8_t>(critAlarmHigh) << 3) |
32133d90e18SGeorge Liu         (static_cast<uint8_t>(critAlarmLow) << 2) |
32233d90e18SGeorge Liu         (static_cast<uint8_t>(warningAlarmHigh) << 1) |
32333d90e18SGeorge Liu         (static_cast<uint8_t>(warningAlarmLow));
324778f6597SKonstantin Aladyshev 
325e05b292bSTom Joseph     return response;
326e05b292bSTom Joseph }
327e05b292bSTom Joseph 
3288c2c048eSLei YU #else
3298c2c048eSLei YU 
3308c2c048eSLei YU /**
3318c2c048eSLei YU  *  @brief Map the Dbus info to sensor's assertion status in the Get sensor
3328c2c048eSLei YU  *         reading command response.
3338c2c048eSLei YU  *
3348c2c048eSLei YU  *  @param[in] id - The sensor id
3358c2c048eSLei YU  *  @param[in] sensorInfo - Dbus info related to sensor.
3368c2c048eSLei YU  *  @param[in] msg - Dbus message from match callback.
3378c2c048eSLei YU  *
3388c2c048eSLei YU  *  @return Response for get sensor reading command.
3398c2c048eSLei YU  */
3408c2c048eSLei YU std::optional<GetSensorResponse> assertion(uint8_t id, const Info& sensorInfo,
3418e8152c5SLei YU                                            const PropertyMap& properties);
3428c2c048eSLei YU 
3438c2c048eSLei YU /**
3448c2c048eSLei YU  *  @brief Maps the Dbus info to the reading field in the Get sensor reading
3458c2c048eSLei YU  *         command response.
3468c2c048eSLei YU  *
3478c2c048eSLei YU  *  @param[in] id - The sensor id
3488c2c048eSLei YU  *  @param[in] sensorInfo - Dbus info related to sensor.
3498c2c048eSLei YU  *  @param[in] msg - Dbus message from match callback.
3508c2c048eSLei YU  *
3518c2c048eSLei YU  *  @return Response for get sensor reading command.
3528c2c048eSLei YU  */
3538c2c048eSLei YU std::optional<GetSensorResponse> eventdata2(uint8_t id, const Info& sensorInfo,
3548e8152c5SLei YU                                             const PropertyMap& properties);
3558c2c048eSLei YU 
3568c2c048eSLei YU /**
3578c2c048eSLei YU  *  @brief readingAssertion is a case where the entire assertion state field
3588c2c048eSLei YU  *         serves as the sensor value.
3598c2c048eSLei YU  *
3608c2c048eSLei YU  *  @tparam T - type of the dbus property related to sensor.
3618c2c048eSLei YU  *  @param[in] id - The sensor id
3628c2c048eSLei YU  *  @param[in] sensorInfo - Dbus info related to sensor.
3638c2c048eSLei YU  *  @param[in] msg - Dbus message from match callback.
3648c2c048eSLei YU  *
3658c2c048eSLei YU  *  @return Response for get sensor reading command.
3668c2c048eSLei YU  */
3678c2c048eSLei YU template <typename T>
readingAssertion(uint8_t id,const Info & sensorInfo,const PropertyMap & properties)368*1318a5edSPatrick Williams std::optional<GetSensorResponse> readingAssertion(
369*1318a5edSPatrick Williams     uint8_t id, const Info& sensorInfo, const PropertyMap& properties)
3708c2c048eSLei YU {
3717d72034bSLei YU     GetSensorResponse response{};
3727d72034bSLei YU     enableScanning(&response);
3737d72034bSLei YU 
3747d72034bSLei YU     auto iter = properties.find(
3757d72034bSLei YU         sensorInfo.propertyInterfaces.begin()->second.begin()->first);
3767d72034bSLei YU     if (iter == properties.end())
3777d72034bSLei YU     {
3787d72034bSLei YU         return {};
3797d72034bSLei YU     }
3807d72034bSLei YU 
3817d72034bSLei YU     setAssertionBytes(static_cast<uint16_t>(std::get<T>(iter->second)),
3827d72034bSLei YU                       &response);
3837d72034bSLei YU 
3847d72034bSLei YU     if (!sensorCacheMap[id].has_value())
3857d72034bSLei YU     {
3867d72034bSLei YU         sensorCacheMap[id] = SensorData{};
3877d72034bSLei YU     }
3887d72034bSLei YU     sensorCacheMap[id]->response = response;
3897d72034bSLei YU     return response;
3907d72034bSLei YU }
3918c2c048eSLei YU 
3928c2c048eSLei YU /** @brief Get sensor reading from the dbus message from match
3938c2c048eSLei YU  *
3948c2c048eSLei YU  *  @tparam T - type of the dbus property related to sensor.
3958c2c048eSLei YU  *  @param[in] id - The sensor id
3968c2c048eSLei YU  *  @param[in] sensorInfo - Dbus info related to sensor.
3978c2c048eSLei YU  *  @param[in] msg - Dbus message from match callback.
3988c2c048eSLei YU  *
3998c2c048eSLei YU  *  @return Response for get sensor reading command.
4008c2c048eSLei YU  */
4018c2c048eSLei YU template <typename T>
readingData(uint8_t id,const Info & sensorInfo,const PropertyMap & properties)4028c2c048eSLei YU std::optional<GetSensorResponse> readingData(uint8_t id, const Info& sensorInfo,
4038e8152c5SLei YU                                              const PropertyMap& properties)
4048c2c048eSLei YU {
4058e8152c5SLei YU     auto iter = properties.find("Functional");
4068e8152c5SLei YU     if (iter != properties.end())
407a55e9ea1SLei YU     {
4088e8152c5SLei YU         sensorCacheMap[id]->functional = std::get<bool>(iter->second);
4099714050fSLei YU     }
4108e8152c5SLei YU     iter = properties.find("Available");
4118e8152c5SLei YU     if (iter != properties.end())
4129714050fSLei YU     {
4138e8152c5SLei YU         sensorCacheMap[id]->available = std::get<bool>(iter->second);
4149714050fSLei YU     }
4159714050fSLei YU #ifdef UPDATE_FUNCTIONAL_ON_FAIL
4169714050fSLei YU     if (sensorCacheMap[id])
4179714050fSLei YU     {
4189714050fSLei YU         if (!sensorCacheMap[id]->functional)
4199714050fSLei YU         {
4209714050fSLei YU             throw SensorFunctionalError();
4219714050fSLei YU         }
4229714050fSLei YU     }
4239714050fSLei YU #endif
4249714050fSLei YU 
4259714050fSLei YU     GetSensorResponse response{};
4269714050fSLei YU 
4279714050fSLei YU     enableScanning(&response);
4289714050fSLei YU 
4298e8152c5SLei YU     iter = properties.find(
4309714050fSLei YU         sensorInfo.propertyInterfaces.begin()->second.begin()->first);
4319714050fSLei YU     if (iter == properties.end())
4329714050fSLei YU     {
4339714050fSLei YU         return {};
4349714050fSLei YU     }
4359714050fSLei YU 
4369714050fSLei YU     double value = std::get<T>(iter->second) *
4379714050fSLei YU                    std::pow(10, sensorInfo.scale - sensorInfo.exponentR);
438*1318a5edSPatrick Williams     int32_t rawData =
439*1318a5edSPatrick Williams         (value - sensorInfo.scaledOffset) / sensorInfo.coefficientM;
4409714050fSLei YU 
4419714050fSLei YU     constexpr uint8_t sensorUnitsSignedBits = 2 << 6;
4429714050fSLei YU     constexpr uint8_t signedDataFormat = 0x80;
4439714050fSLei YU     // if sensorUnits1 [7:6] = 10b, sensor is signed
4449714050fSLei YU     if ((sensorInfo.sensorUnits1 & sensorUnitsSignedBits) == signedDataFormat)
4459714050fSLei YU     {
4469714050fSLei YU         if (rawData > std::numeric_limits<int8_t>::max() ||
4479714050fSLei YU             rawData < std::numeric_limits<int8_t>::lowest())
4489714050fSLei YU         {
4499b745a81SGeorge Liu             lg2::error("Value out of range");
4509714050fSLei YU             throw std::out_of_range("Value out of range");
4519714050fSLei YU         }
4529714050fSLei YU         setReading(static_cast<int8_t>(rawData), &response);
4539714050fSLei YU     }
4549714050fSLei YU     else
4559714050fSLei YU     {
4569714050fSLei YU         if (rawData > std::numeric_limits<uint8_t>::max() ||
4579714050fSLei YU             rawData < std::numeric_limits<uint8_t>::lowest())
4589714050fSLei YU         {
4599b745a81SGeorge Liu             lg2::error("Value out of range");
4609714050fSLei YU             throw std::out_of_range("Value out of range");
4619714050fSLei YU         }
4629714050fSLei YU         setReading(static_cast<uint8_t>(rawData), &response);
4639714050fSLei YU     }
4649714050fSLei YU 
4659714050fSLei YU     if (!std::isfinite(value))
4669714050fSLei YU     {
4679714050fSLei YU         response.readingOrStateUnavailable = 1;
4689714050fSLei YU     }
4699714050fSLei YU 
4709714050fSLei YU     if (!sensorCacheMap[id].has_value())
4719714050fSLei YU     {
4729714050fSLei YU         sensorCacheMap[id] = SensorData{};
4739714050fSLei YU     }
4749714050fSLei YU     sensorCacheMap[id]->response = response;
4759714050fSLei YU 
4769714050fSLei YU     return response;
4779714050fSLei YU }
4788c2c048eSLei YU 
4798c2c048eSLei YU #endif // FEATURE_SENSORS_CACHE
4808c2c048eSLei YU 
481816e92b5STom Joseph } // namespace get
482816e92b5STom Joseph 
483e0af7209SDhruvaraj Subhashchandran namespace set
484e0af7209SDhruvaraj Subhashchandran {
485e0af7209SDhruvaraj Subhashchandran 
486e0af7209SDhruvaraj Subhashchandran /** @brief Make a DBus message for a Dbus call
487e0af7209SDhruvaraj Subhashchandran  *  @param[in] updateInterface - Interface name
488e0af7209SDhruvaraj Subhashchandran  *  @param[in] sensorPath - Path of the sensor
489e0af7209SDhruvaraj Subhashchandran  *  @param[in] command - command to be executed
490e0af7209SDhruvaraj Subhashchandran  *  @param[in] sensorInterface - DBus interface of sensor
491e0af7209SDhruvaraj Subhashchandran  *  @return a dbus message
492e0af7209SDhruvaraj Subhashchandran  */
493e0af7209SDhruvaraj Subhashchandran IpmiUpdateData makeDbusMsg(const std::string& updateInterface,
494e0af7209SDhruvaraj Subhashchandran                            const std::string& sensorPath,
495e0af7209SDhruvaraj Subhashchandran                            const std::string& command,
496e0af7209SDhruvaraj Subhashchandran                            const std::string& sensorInterface);
497e0af7209SDhruvaraj Subhashchandran 
4981bb0d387SDeepak Kodihalli /** @brief Update d-bus based on assertion type sensor data
499e0af7209SDhruvaraj Subhashchandran  *  @param[in] cmdData - input sensor data
5001bb0d387SDeepak Kodihalli  *  @param[in] sensorInfo - sensor d-bus info
501e0af7209SDhruvaraj Subhashchandran  *  @return a IPMI error code
502e0af7209SDhruvaraj Subhashchandran  */
5031bb0d387SDeepak Kodihalli ipmi_ret_t assertion(const SetSensorReadingReq& cmdData,
5041bb0d387SDeepak Kodihalli                      const Info& sensorInfo);
505e0af7209SDhruvaraj Subhashchandran 
5061bb0d387SDeepak Kodihalli /** @brief Update d-bus based on a reading assertion
5071bb0d387SDeepak Kodihalli  *  @tparam T - type of d-bus property mapping this sensor
5081bb0d387SDeepak Kodihalli  *  @param[in] cmdData - input sensor data
5091bb0d387SDeepak Kodihalli  *  @param[in] sensorInfo - sensor d-bus info
510e0af7209SDhruvaraj Subhashchandran  *  @return a IPMI error code
511e0af7209SDhruvaraj Subhashchandran  */
5121bb0d387SDeepak Kodihalli template <typename T>
readingAssertion(const SetSensorReadingReq & cmdData,const Info & sensorInfo)5131bb0d387SDeepak Kodihalli ipmi_ret_t readingAssertion(const SetSensorReadingReq& cmdData,
5141bb0d387SDeepak Kodihalli                             const Info& sensorInfo)
5151bb0d387SDeepak Kodihalli {
516*1318a5edSPatrick Williams     auto msg =
517*1318a5edSPatrick Williams         makeDbusMsg("org.freedesktop.DBus.Properties", sensorInfo.sensorPath,
518*1318a5edSPatrick Williams                     "Set", sensorInfo.sensorInterface);
5191bb0d387SDeepak Kodihalli 
5201bb0d387SDeepak Kodihalli     const auto& interface = sensorInfo.propertyInterfaces.begin();
5211bb0d387SDeepak Kodihalli     msg.append(interface->first);
5221bb0d387SDeepak Kodihalli     for (const auto& property : interface->second)
5231bb0d387SDeepak Kodihalli     {
5241bb0d387SDeepak Kodihalli         msg.append(property.first);
525*1318a5edSPatrick Williams         std::variant<T> value = static_cast<T>(
526*1318a5edSPatrick Williams             (cmdData.assertOffset8_14 << 8) | cmdData.assertOffset0_7);
5271bb0d387SDeepak Kodihalli         msg.append(value);
5281bb0d387SDeepak Kodihalli     }
5291bb0d387SDeepak Kodihalli     return updateToDbus(msg);
5301bb0d387SDeepak Kodihalli }
5311bb0d387SDeepak Kodihalli 
532cc941e15SEmily Shaffer /** @brief Update d-bus based on a discrete reading
533cc941e15SEmily Shaffer  *  @param[in] cmdData - input sensor data
534cc941e15SEmily Shaffer  *  @param[in] sensorInfo - sensor d-bus info
535cc941e15SEmily Shaffer  *  @return an IPMI error code
536cc941e15SEmily Shaffer  */
537cc941e15SEmily Shaffer template <typename T>
readingData(const SetSensorReadingReq & cmdData,const Info & sensorInfo)538cc941e15SEmily Shaffer ipmi_ret_t readingData(const SetSensorReadingReq& cmdData,
539cc941e15SEmily Shaffer                        const Info& sensorInfo)
540cc941e15SEmily Shaffer {
541fbc6c9d7SPatrick Williams     T raw_value = (sensorInfo.coefficientM * cmdData.reading) +
542fbc6c9d7SPatrick Williams                   sensorInfo.scaledOffset;
54322102153STom Joseph 
544586d35b4SPatrick Venture     raw_value *= std::pow(10, sensorInfo.exponentR - sensorInfo.scale);
54522102153STom Joseph 
546*1318a5edSPatrick Williams     auto msg =
547*1318a5edSPatrick Williams         makeDbusMsg("org.freedesktop.DBus.Properties", sensorInfo.sensorPath,
548*1318a5edSPatrick Williams                     "Set", sensorInfo.sensorInterface);
549cc941e15SEmily Shaffer 
550cc941e15SEmily Shaffer     const auto& interface = sensorInfo.propertyInterfaces.begin();
551cc941e15SEmily Shaffer     msg.append(interface->first);
552cc941e15SEmily Shaffer 
553cc941e15SEmily Shaffer     for (const auto& property : interface->second)
554cc941e15SEmily Shaffer     {
555cc941e15SEmily Shaffer         msg.append(property.first);
55616b8693dSVernon Mauery         std::variant<T> value = raw_value;
557cc941e15SEmily Shaffer         msg.append(value);
558cc941e15SEmily Shaffer     }
559cc941e15SEmily Shaffer     return updateToDbus(msg);
560cc941e15SEmily Shaffer }
5611bb0d387SDeepak Kodihalli 
5621bb0d387SDeepak Kodihalli /** @brief Update d-bus based on eventdata type sensor data
5631bb0d387SDeepak Kodihalli  *  @param[in] cmdData - input sensor data
5641bb0d387SDeepak Kodihalli  *  @param[in] sensorInfo - sensor d-bus info
5651bb0d387SDeepak Kodihalli  *  @return a IPMI error code
5661bb0d387SDeepak Kodihalli  */
5670b02be92SPatrick Venture ipmi_ret_t eventdata(const SetSensorReadingReq& cmdData, const Info& sensorInfo,
568e0af7209SDhruvaraj Subhashchandran                      uint8_t data);
569e0af7209SDhruvaraj Subhashchandran 
5701bb0d387SDeepak Kodihalli /** @brief Update d-bus based on eventdata1 type sensor data
5711bb0d387SDeepak Kodihalli  *  @param[in] cmdData - input sensor data
5721bb0d387SDeepak Kodihalli  *  @param[in] sensorInfo - sensor d-bus info
573e0af7209SDhruvaraj Subhashchandran  *  @return a IPMI error code
574e0af7209SDhruvaraj Subhashchandran  */
eventdata1(const SetSensorReadingReq & cmdData,const Info & sensorInfo)5751bb0d387SDeepak Kodihalli inline ipmi_ret_t eventdata1(const SetSensorReadingReq& cmdData,
5761bb0d387SDeepak Kodihalli                              const Info& sensorInfo)
5771bb0d387SDeepak Kodihalli {
5781bb0d387SDeepak Kodihalli     return eventdata(cmdData, sensorInfo, cmdData.eventData1);
5791bb0d387SDeepak Kodihalli }
5801bb0d387SDeepak Kodihalli 
5811bb0d387SDeepak Kodihalli /** @brief Update d-bus based on eventdata2 type sensor data
5821bb0d387SDeepak Kodihalli  *  @param[in] cmdData - input sensor data
5831bb0d387SDeepak Kodihalli  *  @param[in] sensorInfo - sensor d-bus info
5841bb0d387SDeepak Kodihalli  *  @return a IPMI error code
5851bb0d387SDeepak Kodihalli  */
eventdata2(const SetSensorReadingReq & cmdData,const Info & sensorInfo)5861bb0d387SDeepak Kodihalli inline ipmi_ret_t eventdata2(const SetSensorReadingReq& cmdData,
5871bb0d387SDeepak Kodihalli                              const Info& sensorInfo)
5881bb0d387SDeepak Kodihalli {
5891bb0d387SDeepak Kodihalli     return eventdata(cmdData, sensorInfo, cmdData.eventData2);
5901bb0d387SDeepak Kodihalli }
5911bb0d387SDeepak Kodihalli 
5921bb0d387SDeepak Kodihalli /** @brief Update d-bus based on eventdata3 type sensor data
5931bb0d387SDeepak Kodihalli  *  @param[in] cmdData - input sensor data
5941bb0d387SDeepak Kodihalli  *  @param[in] sensorInfo - sensor d-bus info
5951bb0d387SDeepak Kodihalli  *  @return a IPMI error code
5961bb0d387SDeepak Kodihalli  */
eventdata3(const SetSensorReadingReq & cmdData,const Info & sensorInfo)5971bb0d387SDeepak Kodihalli inline ipmi_ret_t eventdata3(const SetSensorReadingReq& cmdData,
5981bb0d387SDeepak Kodihalli                              const Info& sensorInfo)
5991bb0d387SDeepak Kodihalli {
6001bb0d387SDeepak Kodihalli     return eventdata(cmdData, sensorInfo, cmdData.eventData3);
6011bb0d387SDeepak Kodihalli }
602e0af7209SDhruvaraj Subhashchandran 
603e0af7209SDhruvaraj Subhashchandran } // namespace set
604e0af7209SDhruvaraj Subhashchandran 
605e0af7209SDhruvaraj Subhashchandran namespace notify
606e0af7209SDhruvaraj Subhashchandran {
607e0af7209SDhruvaraj Subhashchandran 
608e0af7209SDhruvaraj Subhashchandran /** @brief Make a DBus message for a Dbus call
609e0af7209SDhruvaraj Subhashchandran  *  @param[in] updateInterface - Interface name
610e0af7209SDhruvaraj Subhashchandran  *  @param[in] sensorPath - Path of the sensor
611e0af7209SDhruvaraj Subhashchandran  *  @param[in] command - command to be executed
612e0af7209SDhruvaraj Subhashchandran  *  @param[in] sensorInterface - DBus interface of sensor
613e0af7209SDhruvaraj Subhashchandran  *  @return a dbus message
614e0af7209SDhruvaraj Subhashchandran  */
615e0af7209SDhruvaraj Subhashchandran IpmiUpdateData makeDbusMsg(const std::string& updateInterface,
616e0af7209SDhruvaraj Subhashchandran                            const std::string& sensorPath,
617e0af7209SDhruvaraj Subhashchandran                            const std::string& command,
618e0af7209SDhruvaraj Subhashchandran                            const std::string& sensorInterface);
619e0af7209SDhruvaraj Subhashchandran 
6201bb0d387SDeepak Kodihalli /** @brief Update d-bus based on assertion type sensor data
621e0af7209SDhruvaraj Subhashchandran  *  @param[in] interfaceMap - sensor interface
622e0af7209SDhruvaraj Subhashchandran  *  @param[in] cmdData - input sensor data
6231bb0d387SDeepak Kodihalli  *  @param[in] sensorInfo - sensor d-bus info
624e0af7209SDhruvaraj Subhashchandran  *  @return a IPMI error code
625e0af7209SDhruvaraj Subhashchandran  */
6261bb0d387SDeepak Kodihalli ipmi_ret_t assertion(const SetSensorReadingReq& cmdData,
6271bb0d387SDeepak Kodihalli                      const Info& sensorInfo);
628e0af7209SDhruvaraj Subhashchandran 
629e0af7209SDhruvaraj Subhashchandran } // namespace notify
630816e92b5STom Joseph 
631816e92b5STom Joseph namespace inventory
632816e92b5STom Joseph {
633816e92b5STom Joseph 
634816e92b5STom Joseph namespace get
635816e92b5STom Joseph {
636816e92b5STom Joseph 
637ff8c9b49SLei YU #ifndef FEATURE_SENSORS_CACHE
638ff8c9b49SLei YU 
639816e92b5STom Joseph /**
640816e92b5STom Joseph  *  @brief Map the Dbus info to sensor's assertion status in the Get sensor
641816e92b5STom Joseph  *         reading command response.
642816e92b5STom Joseph  *
643816e92b5STom Joseph  *  @param[in] sensorInfo - Dbus info related to sensor.
644816e92b5STom Joseph  *
645816e92b5STom Joseph  *  @return Response for get sensor reading command.
646816e92b5STom Joseph  */
647816e92b5STom Joseph GetSensorResponse assertion(const Info& sensorInfo);
648816e92b5STom Joseph 
649ff8c9b49SLei YU #else
650ff8c9b49SLei YU 
651ff8c9b49SLei YU /**
652ff8c9b49SLei YU  *  @brief Map the Dbus info to sensor's assertion status in the Get sensor
653ff8c9b49SLei YU  *         reading command response.
654ff8c9b49SLei YU  *
655ff8c9b49SLei YU  *  @param[in] id - The sensor id
656ff8c9b49SLei YU  *  @param[in] sensorInfo - Dbus info related to sensor.
657ff8c9b49SLei YU  *  @param[in] msg - Dbus message from match callback.
658ff8c9b49SLei YU  *
659ff8c9b49SLei YU  *  @return Response for get sensor reading command.
660ff8c9b49SLei YU  */
661ff8c9b49SLei YU std::optional<GetSensorResponse> assertion(uint8_t id, const Info& sensorInfo,
6628e8152c5SLei YU                                            const PropertyMap& properties);
663ff8c9b49SLei YU 
664ff8c9b49SLei YU #endif
665ff8c9b49SLei YU 
666816e92b5STom Joseph } // namespace get
667816e92b5STom Joseph 
668816e92b5STom Joseph } // namespace inventory
669e0af7209SDhruvaraj Subhashchandran } // namespace sensor
670e0af7209SDhruvaraj Subhashchandran } // namespace ipmi
671