blob: 6b716d525bf8d48380d9b5ffe9d5d168f6f3dfed [file] [log] [blame]
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -05001#pragma once
2
Brandon Kim9cf85622019-06-19 12:05:08 -07003#include "config.h"
4
Patrick Venture46470a32018-09-07 19:26:25 -07005#include "sensorhandler.hpp"
Patrick Venture0b02be92018-08-31 11:55:55 -07006
Vernon Mauerye08fbff2019-04-03 09:19:34 -07007#include <ipmid/api.hpp>
Vernon Mauery33250242019-03-12 16:49:26 -07008#include <ipmid/types.hpp>
Vernon Mauery6a98fe72019-03-11 15:57:48 -07009#include <ipmid/utils.hpp>
Tony Leec5324252019-10-31 17:24:16 +080010#include <phosphor-logging/elog-errors.hpp>
George Liu9b745a82024-07-19 09:09:36 +080011#include <phosphor-logging/lg2.hpp>
William A. Kennington III4c008022018-10-12 17:18:14 -070012#include <sdbusplus/message/types.hpp>
Alexander Hansenf365c7f2025-11-14 12:08:34 +010013#include <xyz/openbmc_project/Sensor/Value/common.hpp>
Patrick Venture0b02be92018-08-31 11:55:55 -070014
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -050015#include <cmath>
16
Lei YU97140502021-09-17 13:49:43 +080017#ifdef FEATURE_SENSORS_CACHE
Lei YUa55e9ea2021-09-18 15:15:17 +080018
Lei YU97140502021-09-17 13:49:43 +080019extern ipmi::sensor::SensorCacheMap sensorCacheMap;
Lei YUa55e9ea2021-09-18 15:15:17 +080020
21// The signal's message type is 0x04 from DBus spec:
22// https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages
23static constexpr auto msgTypeSignal = 0x04;
24
Lei YU97140502021-09-17 13:49:43 +080025#endif
26
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -050027namespace ipmi
28{
29namespace sensor
30{
31
32using Assertion = uint16_t;
33using Deassertion = uint16_t;
34using AssertionSet = std::pair<Assertion, Deassertion>;
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -050035using Service = std::string;
36using Path = std::string;
37using Interface = std::string;
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -050038using ServicePath = std::pair<Path, Service>;
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -050039using Interfaces = std::vector<Interface>;
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -050040using MapperResponseType = std::map<Path, std::map<Service, Interfaces>>;
Lei YU8e8152c2021-12-06 20:11:08 +080041using PropertyMap = ipmi::PropertyMap;
42
Alexander Hansenf365c7f2025-11-14 12:08:34 +010043using SensorValue = sdbusplus::common::xyz::openbmc_project::sensor::Value;
44
Tony Leec5324252019-10-31 17:24:16 +080045using namespace phosphor::logging;
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -050046
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -050047/** @brief Make assertion set from input data
48 * @param[in] cmdData - Input sensor data
49 * @return pair of assertion and deassertion set
50 */
51AssertionSet getAssertionSet(const SetSensorReadingReq& cmdData);
52
53/** @brief send the message to DBus
54 * @param[in] msg - message to send
55 * @return failure status in IPMI error code
56 */
George Liu23c868c2025-07-04 09:31:35 +080057ipmi::Cc updateToDbus(IpmiUpdateData& msg);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -050058
Tom Joseph816e92b2017-09-06 19:23:00 +053059namespace get
60{
61
Tom Josephb0adbcd2018-01-24 11:51:29 +053062/** @brief Populate sensor name from the D-Bus property associated with the
63 * sensor. In the example entry from the yaml, the name of the D-bus
64 * property "AttemptsLeft" is the sensor name.
65 *
66 * 0x07:
67 * sensorType: 195
68 * path: /xyz/openbmc_project/state/host0
69 * sensorReadingType: 0x6F
70 * serviceInterface: org.freedesktop.DBus.Properties
71 * readingType: readingAssertion
72 * sensorNamePattern: nameProperty
73 * interfaces:
74 * xyz.openbmc_project.Control.Boot.RebootAttempts:
75 * AttemptsLeft:
76 * Offsets:
77 * 0xFF:
78 * type: uint32_t
79 *
80 *
81 * @param[in] sensorInfo - Dbus info related to sensor.
82 *
83 * @return On success return the sensor name for the sensor.
84 */
85inline SensorName nameProperty(const Info& sensorInfo)
86{
87 return sensorInfo.propertyInterfaces.begin()->second.begin()->first;
88}
89
90/** @brief Populate sensor name from the D-Bus object associated with the
91 * sensor. If the object path is /system/chassis/motherboard/dimm0 then
92 * the leaf dimm0 is considered as the sensor name.
93 *
94 * @param[in] sensorInfo - Dbus info related to sensor.
95 *
96 * @return On success return the sensor name for the sensor.
97 */
98inline SensorName nameLeaf(const Info& sensorInfo)
99{
100 return sensorInfo.sensorPath.substr(
Patrick Venture0b02be92018-08-31 11:55:55 -0700101 sensorInfo.sensorPath.find_last_of('/') + 1,
102 sensorInfo.sensorPath.length());
Tom Josephb0adbcd2018-01-24 11:51:29 +0530103}
104
105/** @brief Populate sensor name from the D-Bus object associated with the
Lotus Xu2101a442020-12-24 16:01:56 +0800106 * sensor and the property.
107 * If the object path is /xyz/openbmc_project/inventory/Fan0 and
108 * the property is Present, the leaf Fan0 and the Property is
109 * joined to Fan0_Present as the sensor name.
110 *
111 * @param[in] sensorInfo - Dbus info related to sensor.
112 *
113 * @return On success return the sensor name for the sensor.
114 */
115inline SensorName nameLeafProperty(const Info& sensorInfo)
116{
117 return nameLeaf(sensorInfo) + "_" + nameProperty(sensorInfo);
118}
119
120/** @brief Populate sensor name from the D-Bus object associated with the
Tom Josephb0adbcd2018-01-24 11:51:29 +0530121 * sensor. If the object path is /system/chassis/motherboard/cpu0/core0
122 * then the sensor name is cpu0_core0. The leaf and the parent is put
123 * together to get the sensor name.
124 *
125 * @param[in] sensorInfo - Dbus info related to sensor.
126 *
127 * @return On success return the sensor name for the sensor.
128 */
129SensorName nameParentLeaf(const Info& sensorInfo);
130
Tom Joseph816e92b2017-09-06 19:23:00 +0530131/**
132 * @brief Helper function to map the dbus info to sensor's assertion status
133 * for the get sensor reading command.
134 *
135 * @param[in] sensorInfo - Dbus info related to sensor.
136 * @param[in] path - Dbus object path.
137 * @param[in] interface - Dbus interface.
138 *
139 * @return Response for get sensor reading command.
140 */
141GetSensorResponse mapDbusToAssertion(const Info& sensorInfo,
142 const InstancePath& path,
143 const DbusInterface& interface);
144
Lei YU8c2c0482021-09-16 17:28:28 +0800145#ifndef FEATURE_SENSORS_CACHE
Tom Joseph816e92b2017-09-06 19:23:00 +0530146/**
147 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
148 * reading command response.
149 *
150 * @param[in] sensorInfo - Dbus info related to sensor.
151 *
152 * @return Response for get sensor reading command.
153 */
154GetSensorResponse assertion(const Info& sensorInfo);
155
Tom Josephe4014fc2017-09-06 23:57:36 +0530156/**
157 * @brief Maps the Dbus info to the reading field in the Get sensor reading
158 * command response.
159 *
160 * @param[in] sensorInfo - Dbus info related to sensor.
161 *
162 * @return Response for get sensor reading command.
163 */
164GetSensorResponse eventdata2(const Info& sensorInfo);
165
Tom Joseph295f17e2017-09-07 00:09:46 +0530166/**
167 * @brief readingAssertion is a case where the entire assertion state field
168 * serves as the sensor value.
169 *
170 * @tparam T - type of the dbus property related to sensor.
171 * @param[in] sensorInfo - Dbus info related to sensor.
172 *
173 * @return Response for get sensor reading command.
174 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700175template <typename T>
Tom Joseph295f17e2017-09-07 00:09:46 +0530176GetSensorResponse readingAssertion(const Info& sensorInfo)
177{
Patrick Williams5d82f472022-07-22 19:26:53 -0500178 sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
Patrick Venture0b02be92018-08-31 11:55:55 -0700179 GetSensorResponse response{};
Tom Joseph295f17e2017-09-07 00:09:46 +0530180
George Liue6b2be52025-08-19 13:57:43 +0800181 enableScanning(response);
George Liu08d3add2024-11-18 15:22:43 +0800182 try
183 {
184 auto service = ipmi::getService(bus, sensorInfo.sensorInterface,
185 sensorInfo.sensorPath);
186 auto propValue = ipmi::getDbusProperty(
187 bus, service, sensorInfo.sensorPath,
188 sensorInfo.propertyInterfaces.begin()->first,
189 sensorInfo.propertyInterfaces.begin()->second.begin()->first);
Jeremy Kerr3dc35582020-05-17 15:47:07 +0800190
George Liu08d3add2024-11-18 15:22:43 +0800191 setAssertionBytes(static_cast<uint16_t>(std::get<T>(propValue)),
George Liue6b2be52025-08-19 13:57:43 +0800192 response);
George Liu08d3add2024-11-18 15:22:43 +0800193 }
194 catch (const std::exception& e)
195 {
196 lg2::error(
197 "Failed to call readingAssertion, path: {PATH}, interface: {INTERFACE}: {ERROR}",
198 "PATH", sensorInfo.sensorPath, "INTERFACE",
199 sensorInfo.sensorInterface, "ERROR", e);
200 }
Tom Joseph295f17e2017-09-07 00:09:46 +0530201
202 return response;
203}
204
Tom Josephe05b2922017-09-07 00:43:16 +0530205/** @brief Map the Dbus info to the reading field in the Get sensor reading
206 * command response
207 *
208 * @tparam T - type of the dbus property related to sensor.
209 * @param[in] sensorInfo - Dbus info related to sensor.
210 *
211 * @return Response for get sensor reading command.
212 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700213template <typename T>
Tom Josephe05b2922017-09-07 00:43:16 +0530214GetSensorResponse readingData(const Info& sensorInfo)
215{
Patrick Williams5d82f472022-07-22 19:26:53 -0500216 sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
Tom Josephe05b2922017-09-07 00:43:16 +0530217
Sui Chen4cc42552019-09-11 10:28:35 -0700218 GetSensorResponse response{};
219
George Liue6b2be52025-08-19 13:57:43 +0800220 enableScanning(response);
Tom Josephe05b2922017-09-07 00:43:16 +0530221
Patrick Venture0b02be92018-08-31 11:55:55 -0700222 auto service = ipmi::getService(bus, sensorInfo.sensorInterface,
Tom Josephe05b2922017-09-07 00:43:16 +0530223 sensorInfo.sensorPath);
224
Brandon Kim9cf85622019-06-19 12:05:08 -0700225#ifdef UPDATE_FUNCTIONAL_ON_FAIL
226 // Check the OperationalStatus interface for functional property
Alexander Hansenf365c7f2025-11-14 12:08:34 +0100227 if (sensorInfo.propertyInterfaces.begin()->first == SensorValue::interface)
Brandon Kim9cf85622019-06-19 12:05:08 -0700228 {
229 bool functional = true;
230 try
231 {
232 auto funcValue = ipmi::getDbusProperty(
233 bus, service, sensorInfo.sensorPath,
234 "xyz.openbmc_project.State.Decorator.OperationalStatus",
235 "Functional");
236 functional = std::get<bool>(funcValue);
237 }
238 catch (...)
239 {
240 // No-op if Functional property could not be found since this
241 // check is only valid for Sensor.Value read for hwmonio
242 }
243 if (!functional)
244 {
245 throw SensorFunctionalError();
246 }
247 }
248#endif
249
George Liu08d3add2024-11-18 15:22:43 +0800250 double value{};
251 try
252 {
253 auto propValue = ipmi::getDbusProperty(
254 bus, service, sensorInfo.sensorPath,
255 sensorInfo.propertyInterfaces.begin()->first,
256 sensorInfo.propertyInterfaces.begin()->second.begin()->first);
Tom Josephe05b2922017-09-07 00:43:16 +0530257
George Liu08d3add2024-11-18 15:22:43 +0800258 value = std::get<T>(propValue) *
259 std::pow(10, sensorInfo.scale - sensorInfo.exponentR);
260 }
261 catch (const std::exception& e)
262 {
263 lg2::error(
264 "Failed to call readingData, path: {PATH}, interface: {INTERFACE}: {ERROR}",
265 "PATH", sensorInfo.sensorPath, "INTERFACE",
266 sensorInfo.sensorInterface, "ERROR", e);
267 return response;
268 }
269
Patrick Williams1318a5e2024-08-16 15:19:54 -0400270 int32_t rawData =
271 (value - sensorInfo.scaledOffset) / sensorInfo.coefficientM;
Tom Josephe05b2922017-09-07 00:43:16 +0530272
Tony Leec5324252019-10-31 17:24:16 +0800273 constexpr uint8_t sensorUnitsSignedBits = 2 << 6;
274 constexpr uint8_t signedDataFormat = 0x80;
275 // if sensorUnits1 [7:6] = 10b, sensor is signed
Willy Tu9154caa2021-12-02 02:28:54 -0800276 int32_t minClamp;
277 int32_t maxClamp;
Tony Leec5324252019-10-31 17:24:16 +0800278 if ((sensorInfo.sensorUnits1 & sensorUnitsSignedBits) == signedDataFormat)
279 {
Willy Tu9154caa2021-12-02 02:28:54 -0800280 minClamp = std::numeric_limits<int8_t>::lowest();
281 maxClamp = std::numeric_limits<int8_t>::max();
Tony Leec5324252019-10-31 17:24:16 +0800282 }
283 else
284 {
Willy Tu9154caa2021-12-02 02:28:54 -0800285 minClamp = std::numeric_limits<uint8_t>::lowest();
286 maxClamp = std::numeric_limits<uint8_t>::max();
Tony Leec5324252019-10-31 17:24:16 +0800287 }
Willy Tu9154caa2021-12-02 02:28:54 -0800288 setReading(static_cast<uint8_t>(std::clamp(rawData, minClamp, maxClamp)),
George Liue6b2be52025-08-19 13:57:43 +0800289 response);
Tom Josephe05b2922017-09-07 00:43:16 +0530290
Konstantin Aladyshevf93b29c2021-05-05 14:49:14 +0300291 if (!std::isfinite(value))
292 {
293 response.readingOrStateUnavailable = 1;
294 }
295
Konstantin Aladyshev778f6592021-11-02 11:28:25 +0300296 bool critAlarmHigh;
297 try
298 {
299 critAlarmHigh = std::get<bool>(ipmi::getDbusProperty(
300 bus, service, sensorInfo.sensorPath,
301 "xyz.openbmc_project.Sensor.Threshold.Critical",
302 "CriticalAlarmHigh"));
303 }
304 catch (const std::exception& e)
305 {
306 critAlarmHigh = false;
307 }
308 bool critAlarmLow;
309 try
310 {
311 critAlarmLow = std::get<bool>(ipmi::getDbusProperty(
312 bus, service, sensorInfo.sensorPath,
313 "xyz.openbmc_project.Sensor.Threshold.Critical",
314 "CriticalAlarmLow"));
315 }
316 catch (const std::exception& e)
317 {
318 critAlarmLow = false;
319 }
320 bool warningAlarmHigh;
321 try
322 {
323 warningAlarmHigh = std::get<bool>(ipmi::getDbusProperty(
324 bus, service, sensorInfo.sensorPath,
325 "xyz.openbmc_project.Sensor.Threshold.Warning",
326 "WarningAlarmHigh"));
327 }
328 catch (const std::exception& e)
329 {
330 warningAlarmHigh = false;
331 }
332 bool warningAlarmLow;
333 try
334 {
335 warningAlarmLow = std::get<bool>(ipmi::getDbusProperty(
336 bus, service, sensorInfo.sensorPath,
Tim Leed09db492022-05-30 10:22:34 +0800337 "xyz.openbmc_project.Sensor.Threshold.Warning", "WarningAlarmLow"));
Konstantin Aladyshev778f6592021-11-02 11:28:25 +0300338 }
339 catch (const std::exception& e)
340 {
341 warningAlarmLow = false;
342 }
343 response.thresholdLevelsStates =
YouPengWu19c962b2025-10-17 19:00:18 +0800344 0xC0 | (static_cast<uint8_t>(warningAlarmLow) << 0) |
345 (static_cast<uint8_t>(critAlarmLow) << 1) |
346 (static_cast<uint8_t>(warningAlarmHigh) << 3) |
347 (static_cast<uint8_t>(critAlarmHigh) << 4);
Tom Josephe05b2922017-09-07 00:43:16 +0530348 return response;
349}
350
Lei YU8c2c0482021-09-16 17:28:28 +0800351#else
352
Lei YU8c2c0482021-09-16 17:28:28 +0800353/**
354 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
355 * reading command response.
356 *
357 * @param[in] id - The sensor id
358 * @param[in] sensorInfo - Dbus info related to sensor.
359 * @param[in] msg - Dbus message from match callback.
360 *
361 * @return Response for get sensor reading command.
362 */
363std::optional<GetSensorResponse> assertion(uint8_t id, const Info& sensorInfo,
Lei YU8e8152c2021-12-06 20:11:08 +0800364 const PropertyMap& properties);
Lei YU8c2c0482021-09-16 17:28:28 +0800365
366/**
367 * @brief Maps the Dbus info to the reading field in the Get sensor reading
368 * command response.
369 *
370 * @param[in] id - The sensor id
371 * @param[in] sensorInfo - Dbus info related to sensor.
372 * @param[in] msg - Dbus message from match callback.
373 *
374 * @return Response for get sensor reading command.
375 */
376std::optional<GetSensorResponse> eventdata2(uint8_t id, const Info& sensorInfo,
Lei YU8e8152c2021-12-06 20:11:08 +0800377 const PropertyMap& properties);
Lei YU8c2c0482021-09-16 17:28:28 +0800378
379/**
380 * @brief readingAssertion is a case where the entire assertion state field
381 * serves as the sensor value.
382 *
383 * @tparam T - type of the dbus property related to sensor.
384 * @param[in] id - The sensor id
385 * @param[in] sensorInfo - Dbus info related to sensor.
386 * @param[in] msg - Dbus message from match callback.
387 *
388 * @return Response for get sensor reading command.
389 */
390template <typename T>
Patrick Williams1318a5e2024-08-16 15:19:54 -0400391std::optional<GetSensorResponse> readingAssertion(
392 uint8_t id, const Info& sensorInfo, const PropertyMap& properties)
Lei YU8c2c0482021-09-16 17:28:28 +0800393{
Lei YU7d720342021-09-18 18:39:09 +0800394 GetSensorResponse response{};
George Liue6b2be52025-08-19 13:57:43 +0800395 enableScanning(response);
Lei YU7d720342021-09-18 18:39:09 +0800396
Lei YU7d720342021-09-18 18:39:09 +0800397 auto iter = properties.find(
398 sensorInfo.propertyInterfaces.begin()->second.begin()->first);
399 if (iter == properties.end())
400 {
401 return {};
402 }
403
404 setAssertionBytes(static_cast<uint16_t>(std::get<T>(iter->second)),
George Liue6b2be52025-08-19 13:57:43 +0800405 response);
Lei YU7d720342021-09-18 18:39:09 +0800406
407 if (!sensorCacheMap[id].has_value())
408 {
409 sensorCacheMap[id] = SensorData{};
410 }
411 sensorCacheMap[id]->response = response;
412 return response;
Lei YU8c2c0482021-09-16 17:28:28 +0800413}
414
415/** @brief Get sensor reading from the dbus message from match
416 *
417 * @tparam T - type of the dbus property related to sensor.
418 * @param[in] id - The sensor id
419 * @param[in] sensorInfo - Dbus info related to sensor.
420 * @param[in] msg - Dbus message from match callback.
421 *
422 * @return Response for get sensor reading command.
423 */
424template <typename T>
425std::optional<GetSensorResponse> readingData(uint8_t id, const Info& sensorInfo,
Lei YU8e8152c2021-12-06 20:11:08 +0800426 const PropertyMap& properties)
Lei YU8c2c0482021-09-16 17:28:28 +0800427{
Lei YU8e8152c2021-12-06 20:11:08 +0800428 auto iter = properties.find("Functional");
429 if (iter != properties.end())
Lei YUa55e9ea2021-09-18 15:15:17 +0800430 {
Lei YU8e8152c2021-12-06 20:11:08 +0800431 sensorCacheMap[id]->functional = std::get<bool>(iter->second);
Lei YUa55e9ea2021-09-18 15:15:17 +0800432 }
Lei YU8e8152c2021-12-06 20:11:08 +0800433 iter = properties.find("Available");
434 if (iter != properties.end())
435 {
436 sensorCacheMap[id]->available = std::get<bool>(iter->second);
437 }
438#ifdef UPDATE_FUNCTIONAL_ON_FAIL
439 if (sensorCacheMap[id])
440 {
441 if (!sensorCacheMap[id]->functional)
442 {
443 throw SensorFunctionalError();
444 }
445 }
446#endif
Lei YU97140502021-09-17 13:49:43 +0800447
448 GetSensorResponse response{};
449
George Liue6b2be52025-08-19 13:57:43 +0800450 enableScanning(response);
Lei YU97140502021-09-17 13:49:43 +0800451
Lei YU8e8152c2021-12-06 20:11:08 +0800452 iter = properties.find(
Lei YU97140502021-09-17 13:49:43 +0800453 sensorInfo.propertyInterfaces.begin()->second.begin()->first);
454 if (iter == properties.end())
455 {
456 return {};
457 }
458
459 double value = std::get<T>(iter->second) *
460 std::pow(10, sensorInfo.scale - sensorInfo.exponentR);
Patrick Williams1318a5e2024-08-16 15:19:54 -0400461 int32_t rawData =
462 (value - sensorInfo.scaledOffset) / sensorInfo.coefficientM;
Lei YU97140502021-09-17 13:49:43 +0800463
464 constexpr uint8_t sensorUnitsSignedBits = 2 << 6;
465 constexpr uint8_t signedDataFormat = 0x80;
466 // if sensorUnits1 [7:6] = 10b, sensor is signed
467 if ((sensorInfo.sensorUnits1 & sensorUnitsSignedBits) == signedDataFormat)
468 {
469 if (rawData > std::numeric_limits<int8_t>::max() ||
470 rawData < std::numeric_limits<int8_t>::lowest())
471 {
George Liu9b745a82024-07-19 09:09:36 +0800472 lg2::error("Value out of range");
Lei YU97140502021-09-17 13:49:43 +0800473 throw std::out_of_range("Value out of range");
474 }
George Liue6b2be52025-08-19 13:57:43 +0800475 setReading(static_cast<int8_t>(rawData), response);
Lei YU97140502021-09-17 13:49:43 +0800476 }
477 else
478 {
479 if (rawData > std::numeric_limits<uint8_t>::max() ||
480 rawData < std::numeric_limits<uint8_t>::lowest())
481 {
George Liu9b745a82024-07-19 09:09:36 +0800482 lg2::error("Value out of range");
Lei YU97140502021-09-17 13:49:43 +0800483 throw std::out_of_range("Value out of range");
484 }
George Liue6b2be52025-08-19 13:57:43 +0800485 setReading(static_cast<uint8_t>(rawData), response);
Lei YU97140502021-09-17 13:49:43 +0800486 }
487
488 if (!std::isfinite(value))
489 {
490 response.readingOrStateUnavailable = 1;
491 }
492
493 if (!sensorCacheMap[id].has_value())
494 {
495 sensorCacheMap[id] = SensorData{};
496 }
497 sensorCacheMap[id]->response = response;
498
499 return response;
Lei YU8c2c0482021-09-16 17:28:28 +0800500}
501
502#endif // FEATURE_SENSORS_CACHE
503
Patrick Venture0b02be92018-08-31 11:55:55 -0700504} // namespace get
Tom Joseph816e92b2017-09-06 19:23:00 +0530505
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500506namespace set
507{
508
509/** @brief Make a DBus message for a Dbus call
510 * @param[in] updateInterface - Interface name
511 * @param[in] sensorPath - Path of the sensor
512 * @param[in] command - command to be executed
513 * @param[in] sensorInterface - DBus interface of sensor
514 * @return a dbus message
515 */
516IpmiUpdateData makeDbusMsg(const std::string& updateInterface,
517 const std::string& sensorPath,
518 const std::string& command,
519 const std::string& sensorInterface);
520
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500521/** @brief Update d-bus based on assertion type sensor data
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500522 * @param[in] cmdData - input sensor data
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500523 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500524 * @return a IPMI error code
525 */
George Liu23c868c2025-07-04 09:31:35 +0800526ipmi::Cc assertion(const SetSensorReadingReq& cmdData, const Info& sensorInfo);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500527
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500528/** @brief Update d-bus based on a reading assertion
529 * @tparam T - type of d-bus property mapping this sensor
530 * @param[in] cmdData - input sensor data
531 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500532 * @return a IPMI error code
533 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700534template <typename T>
George Liu23c868c2025-07-04 09:31:35 +0800535ipmi::Cc readingAssertion(const SetSensorReadingReq& cmdData,
536 const Info& sensorInfo)
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500537{
Patrick Williams1318a5e2024-08-16 15:19:54 -0400538 auto msg =
539 makeDbusMsg("org.freedesktop.DBus.Properties", sensorInfo.sensorPath,
540 "Set", sensorInfo.sensorInterface);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500541
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500542 const auto& interface = sensorInfo.propertyInterfaces.begin();
543 msg.append(interface->first);
544 for (const auto& property : interface->second)
545 {
546 msg.append(property.first);
Patrick Williams1318a5e2024-08-16 15:19:54 -0400547 std::variant<T> value = static_cast<T>(
548 (cmdData.assertOffset8_14 << 8) | cmdData.assertOffset0_7);
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500549 msg.append(value);
550 }
551 return updateToDbus(msg);
552}
553
Emily Shaffercc941e12017-06-14 13:06:26 -0700554/** @brief Update d-bus based on a discrete reading
555 * @param[in] cmdData - input sensor data
556 * @param[in] sensorInfo - sensor d-bus info
557 * @return an IPMI error code
558 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700559template <typename T>
George Liu23c868c2025-07-04 09:31:35 +0800560ipmi::Cc readingData(const SetSensorReadingReq& cmdData, const Info& sensorInfo)
Emily Shaffercc941e12017-06-14 13:06:26 -0700561{
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -0500562 T raw_value = (sensorInfo.coefficientM * cmdData.reading) +
563 sensorInfo.scaledOffset;
Tom Joseph22102152018-03-02 18:46:39 +0530564
Patrick Venture586d35b2018-09-07 19:56:18 -0700565 raw_value *= std::pow(10, sensorInfo.exponentR - sensorInfo.scale);
Tom Joseph22102152018-03-02 18:46:39 +0530566
Patrick Williams1318a5e2024-08-16 15:19:54 -0400567 auto msg =
568 makeDbusMsg("org.freedesktop.DBus.Properties", sensorInfo.sensorPath,
569 "Set", sensorInfo.sensorInterface);
Emily Shaffercc941e12017-06-14 13:06:26 -0700570
571 const auto& interface = sensorInfo.propertyInterfaces.begin();
572 msg.append(interface->first);
573
Emily Shaffercc941e12017-06-14 13:06:26 -0700574 for (const auto& property : interface->second)
575 {
576 msg.append(property.first);
Vernon Mauery16b86932019-05-01 08:36:11 -0700577 std::variant<T> value = raw_value;
Emily Shaffercc941e12017-06-14 13:06:26 -0700578 msg.append(value);
579 }
580 return updateToDbus(msg);
581}
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500582
583/** @brief Update d-bus based on eventdata type sensor data
584 * @param[in] cmdData - input sensor data
585 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500586 * @return a IPMI error code
587 */
George Liu23c868c2025-07-04 09:31:35 +0800588ipmi::Cc eventdata(const SetSensorReadingReq& cmdData, const Info& sensorInfo,
589 uint8_t data);
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500590
591/** @brief Update d-bus based on eventdata1 type sensor data
592 * @param[in] cmdData - input sensor data
593 * @param[in] sensorInfo - sensor d-bus info
594 * @return a IPMI error code
595 */
George Liu23c868c2025-07-04 09:31:35 +0800596inline ipmi::Cc eventdata1(const SetSensorReadingReq& cmdData,
597 const Info& sensorInfo)
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500598{
599 return eventdata(cmdData, sensorInfo, cmdData.eventData1);
600}
601
602/** @brief Update d-bus based on eventdata2 type sensor data
603 * @param[in] cmdData - input sensor data
604 * @param[in] sensorInfo - sensor d-bus info
605 * @return a IPMI error code
606 */
George Liu23c868c2025-07-04 09:31:35 +0800607inline ipmi::Cc eventdata2(const SetSensorReadingReq& cmdData,
608 const Info& sensorInfo)
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500609{
610 return eventdata(cmdData, sensorInfo, cmdData.eventData2);
611}
612
613/** @brief Update d-bus based on eventdata3 type sensor data
614 * @param[in] cmdData - input sensor data
615 * @param[in] sensorInfo - sensor d-bus info
616 * @return a IPMI error code
617 */
George Liu23c868c2025-07-04 09:31:35 +0800618inline ipmi::Cc eventdata3(const SetSensorReadingReq& cmdData,
619 const Info& sensorInfo)
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500620{
621 return eventdata(cmdData, sensorInfo, cmdData.eventData3);
622}
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500623
Patrick Venture0b02be92018-08-31 11:55:55 -0700624} // namespace set
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500625
626namespace notify
627{
628
629/** @brief Make a DBus message for a Dbus call
630 * @param[in] updateInterface - Interface name
631 * @param[in] sensorPath - Path of the sensor
632 * @param[in] command - command to be executed
633 * @param[in] sensorInterface - DBus interface of sensor
634 * @return a dbus message
635 */
636IpmiUpdateData makeDbusMsg(const std::string& updateInterface,
637 const std::string& sensorPath,
638 const std::string& command,
639 const std::string& sensorInterface);
640
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500641/** @brief Update d-bus based on assertion type sensor data
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500642 * @param[in] interfaceMap - sensor interface
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500643 * @param[in] cmdData - input sensor data
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500644 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500645 * @return a IPMI error code
646 */
George Liu23c868c2025-07-04 09:31:35 +0800647ipmi::Cc assertion(const SetSensorReadingReq& cmdData, const Info& sensorInfo);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500648
Patrick Venture0b02be92018-08-31 11:55:55 -0700649} // namespace notify
Tom Joseph816e92b2017-09-06 19:23:00 +0530650
651namespace inventory
652{
653
654namespace get
655{
656
Lei YUff8c9b42021-10-15 14:20:57 +0800657#ifndef FEATURE_SENSORS_CACHE
658
Tom Joseph816e92b2017-09-06 19:23:00 +0530659/**
660 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
661 * reading command response.
662 *
663 * @param[in] sensorInfo - Dbus info related to sensor.
664 *
665 * @return Response for get sensor reading command.
666 */
667GetSensorResponse assertion(const Info& sensorInfo);
668
Lei YUff8c9b42021-10-15 14:20:57 +0800669#else
670
671/**
672 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
673 * reading command response.
674 *
675 * @param[in] id - The sensor id
676 * @param[in] sensorInfo - Dbus info related to sensor.
677 * @param[in] msg - Dbus message from match callback.
678 *
679 * @return Response for get sensor reading command.
680 */
681std::optional<GetSensorResponse> assertion(uint8_t id, const Info& sensorInfo,
Lei YU8e8152c2021-12-06 20:11:08 +0800682 const PropertyMap& properties);
Lei YUff8c9b42021-10-15 14:20:57 +0800683
684#endif
685
Tom Joseph816e92b2017-09-06 19:23:00 +0530686} // namespace get
687
688} // namespace inventory
Patrick Venture0b02be92018-08-31 11:55:55 -0700689} // namespace sensor
690} // namespace ipmi