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