blob: 3d569716c98310dc3c8088f2d4e03e68fe774d25 [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>
Patrick Venture0b02be92018-08-31 11:55:55 -070013
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -050014#include <cmath>
15
Lei YU97140502021-09-17 13:49:43 +080016#ifdef FEATURE_SENSORS_CACHE
Lei YUa55e9ea2021-09-18 15:15:17 +080017
Lei YU97140502021-09-17 13:49:43 +080018extern ipmi::sensor::SensorCacheMap sensorCacheMap;
Lei YUa55e9ea2021-09-18 15:15:17 +080019
20// The signal's message type is 0x04 from DBus spec:
21// https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages
22static constexpr auto msgTypeSignal = 0x04;
23
Lei YU97140502021-09-17 13:49:43 +080024#endif
25
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -050026namespace ipmi
27{
28namespace sensor
29{
30
31using Assertion = uint16_t;
32using Deassertion = uint16_t;
33using AssertionSet = std::pair<Assertion, Deassertion>;
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -050034using Service = std::string;
35using Path = std::string;
36using Interface = std::string;
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -050037using ServicePath = std::pair<Path, Service>;
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -050038using Interfaces = std::vector<Interface>;
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -050039using MapperResponseType = std::map<Path, std::map<Service, Interfaces>>;
Lei YU8e8152c2021-12-06 20:11:08 +080040using PropertyMap = ipmi::PropertyMap;
41
Tony Leec5324252019-10-31 17:24:16 +080042using namespace phosphor::logging;
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -050043
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -050044/** @brief Make assertion set from input data
45 * @param[in] cmdData - Input sensor data
46 * @return pair of assertion and deassertion set
47 */
48AssertionSet getAssertionSet(const SetSensorReadingReq& cmdData);
49
50/** @brief send the message to DBus
51 * @param[in] msg - message to send
52 * @return failure status in IPMI error code
53 */
George Liu23c868c2025-07-04 09:31:35 +080054ipmi::Cc updateToDbus(IpmiUpdateData& msg);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -050055
Tom Joseph816e92b2017-09-06 19:23:00 +053056namespace get
57{
58
Tom Josephb0adbcd2018-01-24 11:51:29 +053059/** @brief Populate sensor name from the D-Bus property associated with the
60 * sensor. In the example entry from the yaml, the name of the D-bus
61 * property "AttemptsLeft" is the sensor name.
62 *
63 * 0x07:
64 * sensorType: 195
65 * path: /xyz/openbmc_project/state/host0
66 * sensorReadingType: 0x6F
67 * serviceInterface: org.freedesktop.DBus.Properties
68 * readingType: readingAssertion
69 * sensorNamePattern: nameProperty
70 * interfaces:
71 * xyz.openbmc_project.Control.Boot.RebootAttempts:
72 * AttemptsLeft:
73 * Offsets:
74 * 0xFF:
75 * type: uint32_t
76 *
77 *
78 * @param[in] sensorInfo - Dbus info related to sensor.
79 *
80 * @return On success return the sensor name for the sensor.
81 */
82inline SensorName nameProperty(const Info& sensorInfo)
83{
84 return sensorInfo.propertyInterfaces.begin()->second.begin()->first;
85}
86
87/** @brief Populate sensor name from the D-Bus object associated with the
88 * sensor. If the object path is /system/chassis/motherboard/dimm0 then
89 * the leaf dimm0 is considered as the sensor name.
90 *
91 * @param[in] sensorInfo - Dbus info related to sensor.
92 *
93 * @return On success return the sensor name for the sensor.
94 */
95inline SensorName nameLeaf(const Info& sensorInfo)
96{
97 return sensorInfo.sensorPath.substr(
Patrick Venture0b02be92018-08-31 11:55:55 -070098 sensorInfo.sensorPath.find_last_of('/') + 1,
99 sensorInfo.sensorPath.length());
Tom Josephb0adbcd2018-01-24 11:51:29 +0530100}
101
102/** @brief Populate sensor name from the D-Bus object associated with the
Lotus Xu2101a442020-12-24 16:01:56 +0800103 * sensor and the property.
104 * If the object path is /xyz/openbmc_project/inventory/Fan0 and
105 * the property is Present, the leaf Fan0 and the Property is
106 * joined to Fan0_Present as the sensor name.
107 *
108 * @param[in] sensorInfo - Dbus info related to sensor.
109 *
110 * @return On success return the sensor name for the sensor.
111 */
112inline SensorName nameLeafProperty(const Info& sensorInfo)
113{
114 return nameLeaf(sensorInfo) + "_" + nameProperty(sensorInfo);
115}
116
117/** @brief Populate sensor name from the D-Bus object associated with the
Tom Josephb0adbcd2018-01-24 11:51:29 +0530118 * sensor. If the object path is /system/chassis/motherboard/cpu0/core0
119 * then the sensor name is cpu0_core0. The leaf and the parent is put
120 * together to get the sensor name.
121 *
122 * @param[in] sensorInfo - Dbus info related to sensor.
123 *
124 * @return On success return the sensor name for the sensor.
125 */
126SensorName nameParentLeaf(const Info& sensorInfo);
127
Tom Joseph816e92b2017-09-06 19:23:00 +0530128/**
129 * @brief Helper function to map the dbus info to sensor's assertion status
130 * for the get sensor reading command.
131 *
132 * @param[in] sensorInfo - Dbus info related to sensor.
133 * @param[in] path - Dbus object path.
134 * @param[in] interface - Dbus interface.
135 *
136 * @return Response for get sensor reading command.
137 */
138GetSensorResponse mapDbusToAssertion(const Info& sensorInfo,
139 const InstancePath& path,
140 const DbusInterface& interface);
141
Lei YU8c2c0482021-09-16 17:28:28 +0800142#ifndef FEATURE_SENSORS_CACHE
Tom Joseph816e92b2017-09-06 19:23:00 +0530143/**
144 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
145 * reading command response.
146 *
147 * @param[in] sensorInfo - Dbus info related to sensor.
148 *
149 * @return Response for get sensor reading command.
150 */
151GetSensorResponse assertion(const Info& sensorInfo);
152
Tom Josephe4014fc2017-09-06 23:57:36 +0530153/**
154 * @brief Maps the Dbus info to the reading field in the Get sensor reading
155 * command response.
156 *
157 * @param[in] sensorInfo - Dbus info related to sensor.
158 *
159 * @return Response for get sensor reading command.
160 */
161GetSensorResponse eventdata2(const Info& sensorInfo);
162
Tom Joseph295f17e2017-09-07 00:09:46 +0530163/**
164 * @brief readingAssertion is a case where the entire assertion state field
165 * serves as the sensor value.
166 *
167 * @tparam T - type of the dbus property related to sensor.
168 * @param[in] sensorInfo - Dbus info related to sensor.
169 *
170 * @return Response for get sensor reading command.
171 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700172template <typename T>
Tom Joseph295f17e2017-09-07 00:09:46 +0530173GetSensorResponse readingAssertion(const Info& sensorInfo)
174{
Patrick Williams5d82f472022-07-22 19:26:53 -0500175 sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
Patrick Venture0b02be92018-08-31 11:55:55 -0700176 GetSensorResponse response{};
Tom Joseph295f17e2017-09-07 00:09:46 +0530177
Jeremy Kerr3dc35582020-05-17 15:47:07 +0800178 enableScanning(&response);
George Liu08d3add2024-11-18 15:22:43 +0800179 try
180 {
181 auto service = ipmi::getService(bus, sensorInfo.sensorInterface,
182 sensorInfo.sensorPath);
183 auto propValue = ipmi::getDbusProperty(
184 bus, service, sensorInfo.sensorPath,
185 sensorInfo.propertyInterfaces.begin()->first,
186 sensorInfo.propertyInterfaces.begin()->second.begin()->first);
Jeremy Kerr3dc35582020-05-17 15:47:07 +0800187
George Liu08d3add2024-11-18 15:22:43 +0800188 setAssertionBytes(static_cast<uint16_t>(std::get<T>(propValue)),
189 &response);
190 }
191 catch (const std::exception& e)
192 {
193 lg2::error(
194 "Failed to call readingAssertion, path: {PATH}, interface: {INTERFACE}: {ERROR}",
195 "PATH", sensorInfo.sensorPath, "INTERFACE",
196 sensorInfo.sensorInterface, "ERROR", e);
197 }
Tom Joseph295f17e2017-09-07 00:09:46 +0530198
199 return response;
200}
201
Tom Josephe05b2922017-09-07 00:43:16 +0530202/** @brief Map the Dbus info to the reading field in the Get sensor reading
203 * command response
204 *
205 * @tparam T - type of the dbus property related to sensor.
206 * @param[in] sensorInfo - Dbus info related to sensor.
207 *
208 * @return Response for get sensor reading command.
209 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700210template <typename T>
Tom Josephe05b2922017-09-07 00:43:16 +0530211GetSensorResponse readingData(const Info& sensorInfo)
212{
Patrick Williams5d82f472022-07-22 19:26:53 -0500213 sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
Tom Josephe05b2922017-09-07 00:43:16 +0530214
Sui Chen4cc42552019-09-11 10:28:35 -0700215 GetSensorResponse response{};
216
217 enableScanning(&response);
Tom Josephe05b2922017-09-07 00:43:16 +0530218
Patrick Venture0b02be92018-08-31 11:55:55 -0700219 auto service = ipmi::getService(bus, sensorInfo.sensorInterface,
Tom Josephe05b2922017-09-07 00:43:16 +0530220 sensorInfo.sensorPath);
221
Brandon Kim9cf85622019-06-19 12:05:08 -0700222#ifdef UPDATE_FUNCTIONAL_ON_FAIL
223 // Check the OperationalStatus interface for functional property
224 if (sensorInfo.propertyInterfaces.begin()->first ==
225 "xyz.openbmc_project.Sensor.Value")
226 {
227 bool functional = true;
228 try
229 {
230 auto funcValue = ipmi::getDbusProperty(
231 bus, service, sensorInfo.sensorPath,
232 "xyz.openbmc_project.State.Decorator.OperationalStatus",
233 "Functional");
234 functional = std::get<bool>(funcValue);
235 }
236 catch (...)
237 {
238 // No-op if Functional property could not be found since this
239 // check is only valid for Sensor.Value read for hwmonio
240 }
241 if (!functional)
242 {
243 throw SensorFunctionalError();
244 }
245 }
246#endif
247
George Liu08d3add2024-11-18 15:22:43 +0800248 double value{};
249 try
250 {
251 auto propValue = ipmi::getDbusProperty(
252 bus, service, sensorInfo.sensorPath,
253 sensorInfo.propertyInterfaces.begin()->first,
254 sensorInfo.propertyInterfaces.begin()->second.begin()->first);
Tom Josephe05b2922017-09-07 00:43:16 +0530255
George Liu08d3add2024-11-18 15:22:43 +0800256 value = std::get<T>(propValue) *
257 std::pow(10, sensorInfo.scale - sensorInfo.exponentR);
258 }
259 catch (const std::exception& e)
260 {
261 lg2::error(
262 "Failed to call readingData, path: {PATH}, interface: {INTERFACE}: {ERROR}",
263 "PATH", sensorInfo.sensorPath, "INTERFACE",
264 sensorInfo.sensorInterface, "ERROR", e);
265 return response;
266 }
267
Patrick Williams1318a5e2024-08-16 15:19:54 -0400268 int32_t rawData =
269 (value - sensorInfo.scaledOffset) / sensorInfo.coefficientM;
Tom Josephe05b2922017-09-07 00:43:16 +0530270
Tony Leec5324252019-10-31 17:24:16 +0800271 constexpr uint8_t sensorUnitsSignedBits = 2 << 6;
272 constexpr uint8_t signedDataFormat = 0x80;
273 // if sensorUnits1 [7:6] = 10b, sensor is signed
Willy Tu9154caa2021-12-02 02:28:54 -0800274 int32_t minClamp;
275 int32_t maxClamp;
Tony Leec5324252019-10-31 17:24:16 +0800276 if ((sensorInfo.sensorUnits1 & sensorUnitsSignedBits) == signedDataFormat)
277 {
Willy Tu9154caa2021-12-02 02:28:54 -0800278 minClamp = std::numeric_limits<int8_t>::lowest();
279 maxClamp = std::numeric_limits<int8_t>::max();
Tony Leec5324252019-10-31 17:24:16 +0800280 }
281 else
282 {
Willy Tu9154caa2021-12-02 02:28:54 -0800283 minClamp = std::numeric_limits<uint8_t>::lowest();
284 maxClamp = std::numeric_limits<uint8_t>::max();
Tony Leec5324252019-10-31 17:24:16 +0800285 }
Willy Tu9154caa2021-12-02 02:28:54 -0800286 setReading(static_cast<uint8_t>(std::clamp(rawData, minClamp, maxClamp)),
287 &response);
Tom Josephe05b2922017-09-07 00:43:16 +0530288
Konstantin Aladyshevf93b29c2021-05-05 14:49:14 +0300289 if (!std::isfinite(value))
290 {
291 response.readingOrStateUnavailable = 1;
292 }
293
Konstantin Aladyshev778f6592021-11-02 11:28:25 +0300294 bool critAlarmHigh;
295 try
296 {
297 critAlarmHigh = std::get<bool>(ipmi::getDbusProperty(
298 bus, service, sensorInfo.sensorPath,
299 "xyz.openbmc_project.Sensor.Threshold.Critical",
300 "CriticalAlarmHigh"));
301 }
302 catch (const std::exception& e)
303 {
304 critAlarmHigh = false;
305 }
306 bool critAlarmLow;
307 try
308 {
309 critAlarmLow = std::get<bool>(ipmi::getDbusProperty(
310 bus, service, sensorInfo.sensorPath,
311 "xyz.openbmc_project.Sensor.Threshold.Critical",
312 "CriticalAlarmLow"));
313 }
314 catch (const std::exception& e)
315 {
316 critAlarmLow = false;
317 }
318 bool warningAlarmHigh;
319 try
320 {
321 warningAlarmHigh = std::get<bool>(ipmi::getDbusProperty(
322 bus, service, sensorInfo.sensorPath,
323 "xyz.openbmc_project.Sensor.Threshold.Warning",
324 "WarningAlarmHigh"));
325 }
326 catch (const std::exception& e)
327 {
328 warningAlarmHigh = false;
329 }
330 bool warningAlarmLow;
331 try
332 {
333 warningAlarmLow = std::get<bool>(ipmi::getDbusProperty(
334 bus, service, sensorInfo.sensorPath,
Tim Leed09db492022-05-30 10:22:34 +0800335 "xyz.openbmc_project.Sensor.Threshold.Warning", "WarningAlarmLow"));
Konstantin Aladyshev778f6592021-11-02 11:28:25 +0300336 }
337 catch (const std::exception& e)
338 {
339 warningAlarmLow = false;
340 }
341 response.thresholdLevelsStates =
George Liu33d90e12022-05-16 12:54:20 +0800342 (static_cast<uint8_t>(critAlarmHigh) << 3) |
343 (static_cast<uint8_t>(critAlarmLow) << 2) |
344 (static_cast<uint8_t>(warningAlarmHigh) << 1) |
345 (static_cast<uint8_t>(warningAlarmLow));
Konstantin Aladyshev778f6592021-11-02 11:28:25 +0300346
Tom Josephe05b2922017-09-07 00:43:16 +0530347 return response;
348}
349
Lei YU8c2c0482021-09-16 17:28:28 +0800350#else
351
Lei YU8c2c0482021-09-16 17:28:28 +0800352/**
353 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
354 * reading command response.
355 *
356 * @param[in] id - The sensor id
357 * @param[in] sensorInfo - Dbus info related to sensor.
358 * @param[in] msg - Dbus message from match callback.
359 *
360 * @return Response for get sensor reading command.
361 */
362std::optional<GetSensorResponse> assertion(uint8_t id, const Info& sensorInfo,
Lei YU8e8152c2021-12-06 20:11:08 +0800363 const PropertyMap& properties);
Lei YU8c2c0482021-09-16 17:28:28 +0800364
365/**
366 * @brief Maps the Dbus info to the reading field in the Get sensor reading
367 * command response.
368 *
369 * @param[in] id - The sensor id
370 * @param[in] sensorInfo - Dbus info related to sensor.
371 * @param[in] msg - Dbus message from match callback.
372 *
373 * @return Response for get sensor reading command.
374 */
375std::optional<GetSensorResponse> eventdata2(uint8_t id, const Info& sensorInfo,
Lei YU8e8152c2021-12-06 20:11:08 +0800376 const PropertyMap& properties);
Lei YU8c2c0482021-09-16 17:28:28 +0800377
378/**
379 * @brief readingAssertion is a case where the entire assertion state field
380 * serves as the sensor value.
381 *
382 * @tparam T - type of the dbus property related to sensor.
383 * @param[in] id - The sensor id
384 * @param[in] sensorInfo - Dbus info related to sensor.
385 * @param[in] msg - Dbus message from match callback.
386 *
387 * @return Response for get sensor reading command.
388 */
389template <typename T>
Patrick Williams1318a5e2024-08-16 15:19:54 -0400390std::optional<GetSensorResponse> readingAssertion(
391 uint8_t id, const Info& sensorInfo, const PropertyMap& properties)
Lei YU8c2c0482021-09-16 17:28:28 +0800392{
Lei YU7d720342021-09-18 18:39:09 +0800393 GetSensorResponse response{};
Lei YU7d720342021-09-18 18:39:09 +0800394 enableScanning(&response);
395
Lei YU7d720342021-09-18 18:39:09 +0800396 auto iter = properties.find(
397 sensorInfo.propertyInterfaces.begin()->second.begin()->first);
398 if (iter == properties.end())
399 {
400 return {};
401 }
402
403 setAssertionBytes(static_cast<uint16_t>(std::get<T>(iter->second)),
404 &response);
405
406 if (!sensorCacheMap[id].has_value())
407 {
408 sensorCacheMap[id] = SensorData{};
409 }
410 sensorCacheMap[id]->response = response;
411 return response;
Lei YU8c2c0482021-09-16 17:28:28 +0800412}
413
414/** @brief Get sensor reading from the dbus message from match
415 *
416 * @tparam T - type of the dbus property related to sensor.
417 * @param[in] id - The sensor id
418 * @param[in] sensorInfo - Dbus info related to sensor.
419 * @param[in] msg - Dbus message from match callback.
420 *
421 * @return Response for get sensor reading command.
422 */
423template <typename T>
424std::optional<GetSensorResponse> readingData(uint8_t id, const Info& sensorInfo,
Lei YU8e8152c2021-12-06 20:11:08 +0800425 const PropertyMap& properties)
Lei YU8c2c0482021-09-16 17:28:28 +0800426{
Lei YU8e8152c2021-12-06 20:11:08 +0800427 auto iter = properties.find("Functional");
428 if (iter != properties.end())
Lei YUa55e9ea2021-09-18 15:15:17 +0800429 {
Lei YU8e8152c2021-12-06 20:11:08 +0800430 sensorCacheMap[id]->functional = std::get<bool>(iter->second);
Lei YUa55e9ea2021-09-18 15:15:17 +0800431 }
Lei YU8e8152c2021-12-06 20:11:08 +0800432 iter = properties.find("Available");
433 if (iter != properties.end())
434 {
435 sensorCacheMap[id]->available = std::get<bool>(iter->second);
436 }
437#ifdef UPDATE_FUNCTIONAL_ON_FAIL
438 if (sensorCacheMap[id])
439 {
440 if (!sensorCacheMap[id]->functional)
441 {
442 throw SensorFunctionalError();
443 }
444 }
445#endif
Lei YU97140502021-09-17 13:49:43 +0800446
447 GetSensorResponse response{};
448
449 enableScanning(&response);
450
Lei YU8e8152c2021-12-06 20:11:08 +0800451 iter = properties.find(
Lei YU97140502021-09-17 13:49:43 +0800452 sensorInfo.propertyInterfaces.begin()->second.begin()->first);
453 if (iter == properties.end())
454 {
455 return {};
456 }
457
458 double value = std::get<T>(iter->second) *
459 std::pow(10, sensorInfo.scale - sensorInfo.exponentR);
Patrick Williams1318a5e2024-08-16 15:19:54 -0400460 int32_t rawData =
461 (value - sensorInfo.scaledOffset) / sensorInfo.coefficientM;
Lei YU97140502021-09-17 13:49:43 +0800462
463 constexpr uint8_t sensorUnitsSignedBits = 2 << 6;
464 constexpr uint8_t signedDataFormat = 0x80;
465 // if sensorUnits1 [7:6] = 10b, sensor is signed
466 if ((sensorInfo.sensorUnits1 & sensorUnitsSignedBits) == signedDataFormat)
467 {
468 if (rawData > std::numeric_limits<int8_t>::max() ||
469 rawData < std::numeric_limits<int8_t>::lowest())
470 {
George Liu9b745a82024-07-19 09:09:36 +0800471 lg2::error("Value out of range");
Lei YU97140502021-09-17 13:49:43 +0800472 throw std::out_of_range("Value out of range");
473 }
474 setReading(static_cast<int8_t>(rawData), &response);
475 }
476 else
477 {
478 if (rawData > std::numeric_limits<uint8_t>::max() ||
479 rawData < std::numeric_limits<uint8_t>::lowest())
480 {
George Liu9b745a82024-07-19 09:09:36 +0800481 lg2::error("Value out of range");
Lei YU97140502021-09-17 13:49:43 +0800482 throw std::out_of_range("Value out of range");
483 }
484 setReading(static_cast<uint8_t>(rawData), &response);
485 }
486
487 if (!std::isfinite(value))
488 {
489 response.readingOrStateUnavailable = 1;
490 }
491
492 if (!sensorCacheMap[id].has_value())
493 {
494 sensorCacheMap[id] = SensorData{};
495 }
496 sensorCacheMap[id]->response = response;
497
498 return response;
Lei YU8c2c0482021-09-16 17:28:28 +0800499}
500
501#endif // FEATURE_SENSORS_CACHE
502
Patrick Venture0b02be92018-08-31 11:55:55 -0700503} // namespace get
Tom Joseph816e92b2017-09-06 19:23:00 +0530504
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500505namespace set
506{
507
508/** @brief Make a DBus message for a Dbus call
509 * @param[in] updateInterface - Interface name
510 * @param[in] sensorPath - Path of the sensor
511 * @param[in] command - command to be executed
512 * @param[in] sensorInterface - DBus interface of sensor
513 * @return a dbus message
514 */
515IpmiUpdateData makeDbusMsg(const std::string& updateInterface,
516 const std::string& sensorPath,
517 const std::string& command,
518 const std::string& sensorInterface);
519
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500520/** @brief Update d-bus based on assertion type sensor data
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500521 * @param[in] cmdData - input sensor data
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500522 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500523 * @return a IPMI error code
524 */
George Liu23c868c2025-07-04 09:31:35 +0800525ipmi::Cc assertion(const SetSensorReadingReq& cmdData, const Info& sensorInfo);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500526
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500527/** @brief Update d-bus based on a reading assertion
528 * @tparam T - type of d-bus property mapping this sensor
529 * @param[in] cmdData - input sensor data
530 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500531 * @return a IPMI error code
532 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700533template <typename T>
George Liu23c868c2025-07-04 09:31:35 +0800534ipmi::Cc readingAssertion(const SetSensorReadingReq& cmdData,
535 const Info& sensorInfo)
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500536{
Patrick Williams1318a5e2024-08-16 15:19:54 -0400537 auto msg =
538 makeDbusMsg("org.freedesktop.DBus.Properties", sensorInfo.sensorPath,
539 "Set", sensorInfo.sensorInterface);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500540
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500541 const auto& interface = sensorInfo.propertyInterfaces.begin();
542 msg.append(interface->first);
543 for (const auto& property : interface->second)
544 {
545 msg.append(property.first);
Patrick Williams1318a5e2024-08-16 15:19:54 -0400546 std::variant<T> value = static_cast<T>(
547 (cmdData.assertOffset8_14 << 8) | cmdData.assertOffset0_7);
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500548 msg.append(value);
549 }
550 return updateToDbus(msg);
551}
552
Emily Shaffercc941e12017-06-14 13:06:26 -0700553/** @brief Update d-bus based on a discrete reading
554 * @param[in] cmdData - input sensor data
555 * @param[in] sensorInfo - sensor d-bus info
556 * @return an IPMI error code
557 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700558template <typename T>
George Liu23c868c2025-07-04 09:31:35 +0800559ipmi::Cc readingData(const SetSensorReadingReq& cmdData, const Info& sensorInfo)
Emily Shaffercc941e12017-06-14 13:06:26 -0700560{
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -0500561 T raw_value = (sensorInfo.coefficientM * cmdData.reading) +
562 sensorInfo.scaledOffset;
Tom Joseph22102152018-03-02 18:46:39 +0530563
Patrick Venture586d35b2018-09-07 19:56:18 -0700564 raw_value *= std::pow(10, sensorInfo.exponentR - sensorInfo.scale);
Tom Joseph22102152018-03-02 18:46:39 +0530565
Patrick Williams1318a5e2024-08-16 15:19:54 -0400566 auto msg =
567 makeDbusMsg("org.freedesktop.DBus.Properties", sensorInfo.sensorPath,
568 "Set", sensorInfo.sensorInterface);
Emily Shaffercc941e12017-06-14 13:06:26 -0700569
570 const auto& interface = sensorInfo.propertyInterfaces.begin();
571 msg.append(interface->first);
572
Emily Shaffercc941e12017-06-14 13:06:26 -0700573 for (const auto& property : interface->second)
574 {
575 msg.append(property.first);
Vernon Mauery16b86932019-05-01 08:36:11 -0700576 std::variant<T> value = raw_value;
Emily Shaffercc941e12017-06-14 13:06:26 -0700577 msg.append(value);
578 }
579 return updateToDbus(msg);
580}
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500581
582/** @brief Update d-bus based on eventdata type sensor data
583 * @param[in] cmdData - input sensor data
584 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500585 * @return a IPMI error code
586 */
George Liu23c868c2025-07-04 09:31:35 +0800587ipmi::Cc eventdata(const SetSensorReadingReq& cmdData, const Info& sensorInfo,
588 uint8_t data);
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500589
590/** @brief Update d-bus based on eventdata1 type sensor data
591 * @param[in] cmdData - input sensor data
592 * @param[in] sensorInfo - sensor d-bus info
593 * @return a IPMI error code
594 */
George Liu23c868c2025-07-04 09:31:35 +0800595inline ipmi::Cc eventdata1(const SetSensorReadingReq& cmdData,
596 const Info& sensorInfo)
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500597{
598 return eventdata(cmdData, sensorInfo, cmdData.eventData1);
599}
600
601/** @brief Update d-bus based on eventdata2 type sensor data
602 * @param[in] cmdData - input sensor data
603 * @param[in] sensorInfo - sensor d-bus info
604 * @return a IPMI error code
605 */
George Liu23c868c2025-07-04 09:31:35 +0800606inline ipmi::Cc eventdata2(const SetSensorReadingReq& cmdData,
607 const Info& sensorInfo)
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500608{
609 return eventdata(cmdData, sensorInfo, cmdData.eventData2);
610}
611
612/** @brief Update d-bus based on eventdata3 type sensor data
613 * @param[in] cmdData - input sensor data
614 * @param[in] sensorInfo - sensor d-bus info
615 * @return a IPMI error code
616 */
George Liu23c868c2025-07-04 09:31:35 +0800617inline ipmi::Cc eventdata3(const SetSensorReadingReq& cmdData,
618 const Info& sensorInfo)
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500619{
620 return eventdata(cmdData, sensorInfo, cmdData.eventData3);
621}
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500622
Patrick Venture0b02be92018-08-31 11:55:55 -0700623} // namespace set
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500624
625namespace notify
626{
627
628/** @brief Make a DBus message for a Dbus call
629 * @param[in] updateInterface - Interface name
630 * @param[in] sensorPath - Path of the sensor
631 * @param[in] command - command to be executed
632 * @param[in] sensorInterface - DBus interface of sensor
633 * @return a dbus message
634 */
635IpmiUpdateData makeDbusMsg(const std::string& updateInterface,
636 const std::string& sensorPath,
637 const std::string& command,
638 const std::string& sensorInterface);
639
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500640/** @brief Update d-bus based on assertion type sensor data
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500641 * @param[in] interfaceMap - sensor interface
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500642 * @param[in] cmdData - input sensor data
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500643 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500644 * @return a IPMI error code
645 */
George Liu23c868c2025-07-04 09:31:35 +0800646ipmi::Cc assertion(const SetSensorReadingReq& cmdData, const Info& sensorInfo);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500647
Patrick Venture0b02be92018-08-31 11:55:55 -0700648} // namespace notify
Tom Joseph816e92b2017-09-06 19:23:00 +0530649
650namespace inventory
651{
652
653namespace get
654{
655
Lei YUff8c9b42021-10-15 14:20:57 +0800656#ifndef FEATURE_SENSORS_CACHE
657
Tom Joseph816e92b2017-09-06 19:23:00 +0530658/**
659 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
660 * reading command response.
661 *
662 * @param[in] sensorInfo - Dbus info related to sensor.
663 *
664 * @return Response for get sensor reading command.
665 */
666GetSensorResponse assertion(const Info& sensorInfo);
667
Lei YUff8c9b42021-10-15 14:20:57 +0800668#else
669
670/**
671 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
672 * reading command response.
673 *
674 * @param[in] id - The sensor id
675 * @param[in] sensorInfo - Dbus info related to sensor.
676 * @param[in] msg - Dbus message from match callback.
677 *
678 * @return Response for get sensor reading command.
679 */
680std::optional<GetSensorResponse> assertion(uint8_t id, const Info& sensorInfo,
Lei YU8e8152c2021-12-06 20:11:08 +0800681 const PropertyMap& properties);
Lei YUff8c9b42021-10-15 14:20:57 +0800682
683#endif
684
Tom Joseph816e92b2017-09-06 19:23:00 +0530685} // namespace get
686
687} // namespace inventory
Patrick Venture0b02be92018-08-31 11:55:55 -0700688} // namespace sensor
689} // namespace ipmi