blob: db80a6912587ebf4ad00ac5ad5f2f648440c1b91 [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);
179
Patrick Venture0b02be92018-08-31 11:55:55 -0700180 auto service = ipmi::getService(bus, sensorInfo.sensorInterface,
Tom Joseph295f17e2017-09-07 00:09:46 +0530181 sensorInfo.sensorPath);
182
183 auto propValue = ipmi::getDbusProperty(
Patrick Venture0b02be92018-08-31 11:55:55 -0700184 bus, service, sensorInfo.sensorPath,
185 sensorInfo.propertyInterfaces.begin()->first,
186 sensorInfo.propertyInterfaces.begin()->second.begin()->first);
Tom Joseph295f17e2017-09-07 00:09:46 +0530187
Sui Chen4cc42552019-09-11 10:28:35 -0700188 setAssertionBytes(static_cast<uint16_t>(std::get<T>(propValue)), &response);
Tom Joseph295f17e2017-09-07 00:09:46 +0530189
190 return response;
191}
192
Tom Josephe05b2922017-09-07 00:43:16 +0530193/** @brief Map the Dbus info to the reading field in the Get sensor reading
194 * command response
195 *
196 * @tparam T - type of the dbus property related to sensor.
197 * @param[in] sensorInfo - Dbus info related to sensor.
198 *
199 * @return Response for get sensor reading command.
200 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700201template <typename T>
Tom Josephe05b2922017-09-07 00:43:16 +0530202GetSensorResponse readingData(const Info& sensorInfo)
203{
Patrick Williams5d82f472022-07-22 19:26:53 -0500204 sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
Tom Josephe05b2922017-09-07 00:43:16 +0530205
Sui Chen4cc42552019-09-11 10:28:35 -0700206 GetSensorResponse response{};
207
208 enableScanning(&response);
Tom Josephe05b2922017-09-07 00:43:16 +0530209
Patrick Venture0b02be92018-08-31 11:55:55 -0700210 auto service = ipmi::getService(bus, sensorInfo.sensorInterface,
Tom Josephe05b2922017-09-07 00:43:16 +0530211 sensorInfo.sensorPath);
212
Brandon Kim9cf85622019-06-19 12:05:08 -0700213#ifdef UPDATE_FUNCTIONAL_ON_FAIL
214 // Check the OperationalStatus interface for functional property
215 if (sensorInfo.propertyInterfaces.begin()->first ==
216 "xyz.openbmc_project.Sensor.Value")
217 {
218 bool functional = true;
219 try
220 {
221 auto funcValue = ipmi::getDbusProperty(
222 bus, service, sensorInfo.sensorPath,
223 "xyz.openbmc_project.State.Decorator.OperationalStatus",
224 "Functional");
225 functional = std::get<bool>(funcValue);
226 }
227 catch (...)
228 {
229 // No-op if Functional property could not be found since this
230 // check is only valid for Sensor.Value read for hwmonio
231 }
232 if (!functional)
233 {
234 throw SensorFunctionalError();
235 }
236 }
237#endif
238
Tom Josephe05b2922017-09-07 00:43:16 +0530239 auto propValue = ipmi::getDbusProperty(
Patrick Venture0b02be92018-08-31 11:55:55 -0700240 bus, service, sensorInfo.sensorPath,
241 sensorInfo.propertyInterfaces.begin()->first,
242 sensorInfo.propertyInterfaces.begin()->second.begin()->first);
Tom Josephe05b2922017-09-07 00:43:16 +0530243
Vernon Maueryf442e112019-04-09 11:44:36 -0700244 double value = std::get<T>(propValue) *
Patrick Venture586d35b2018-09-07 19:56:18 -0700245 std::pow(10, sensorInfo.scale - sensorInfo.exponentR);
Patrick Williams1318a5e2024-08-16 15:19:54 -0400246 int32_t rawData =
247 (value - sensorInfo.scaledOffset) / sensorInfo.coefficientM;
Tom Josephe05b2922017-09-07 00:43:16 +0530248
Tony Leec5324252019-10-31 17:24:16 +0800249 constexpr uint8_t sensorUnitsSignedBits = 2 << 6;
250 constexpr uint8_t signedDataFormat = 0x80;
251 // if sensorUnits1 [7:6] = 10b, sensor is signed
Willy Tu9154caa2021-12-02 02:28:54 -0800252 int32_t minClamp;
253 int32_t maxClamp;
Tony Leec5324252019-10-31 17:24:16 +0800254 if ((sensorInfo.sensorUnits1 & sensorUnitsSignedBits) == signedDataFormat)
255 {
Willy Tu9154caa2021-12-02 02:28:54 -0800256 minClamp = std::numeric_limits<int8_t>::lowest();
257 maxClamp = std::numeric_limits<int8_t>::max();
Tony Leec5324252019-10-31 17:24:16 +0800258 }
259 else
260 {
Willy Tu9154caa2021-12-02 02:28:54 -0800261 minClamp = std::numeric_limits<uint8_t>::lowest();
262 maxClamp = std::numeric_limits<uint8_t>::max();
Tony Leec5324252019-10-31 17:24:16 +0800263 }
Willy Tu9154caa2021-12-02 02:28:54 -0800264 setReading(static_cast<uint8_t>(std::clamp(rawData, minClamp, maxClamp)),
265 &response);
Tom Josephe05b2922017-09-07 00:43:16 +0530266
Konstantin Aladyshevf93b29c2021-05-05 14:49:14 +0300267 if (!std::isfinite(value))
268 {
269 response.readingOrStateUnavailable = 1;
270 }
271
Konstantin Aladyshev778f6592021-11-02 11:28:25 +0300272 bool critAlarmHigh;
273 try
274 {
275 critAlarmHigh = std::get<bool>(ipmi::getDbusProperty(
276 bus, service, sensorInfo.sensorPath,
277 "xyz.openbmc_project.Sensor.Threshold.Critical",
278 "CriticalAlarmHigh"));
279 }
280 catch (const std::exception& e)
281 {
282 critAlarmHigh = false;
283 }
284 bool critAlarmLow;
285 try
286 {
287 critAlarmLow = std::get<bool>(ipmi::getDbusProperty(
288 bus, service, sensorInfo.sensorPath,
289 "xyz.openbmc_project.Sensor.Threshold.Critical",
290 "CriticalAlarmLow"));
291 }
292 catch (const std::exception& e)
293 {
294 critAlarmLow = false;
295 }
296 bool warningAlarmHigh;
297 try
298 {
299 warningAlarmHigh = std::get<bool>(ipmi::getDbusProperty(
300 bus, service, sensorInfo.sensorPath,
301 "xyz.openbmc_project.Sensor.Threshold.Warning",
302 "WarningAlarmHigh"));
303 }
304 catch (const std::exception& e)
305 {
306 warningAlarmHigh = false;
307 }
308 bool warningAlarmLow;
309 try
310 {
311 warningAlarmLow = std::get<bool>(ipmi::getDbusProperty(
312 bus, service, sensorInfo.sensorPath,
Tim Leed09db492022-05-30 10:22:34 +0800313 "xyz.openbmc_project.Sensor.Threshold.Warning", "WarningAlarmLow"));
Konstantin Aladyshev778f6592021-11-02 11:28:25 +0300314 }
315 catch (const std::exception& e)
316 {
317 warningAlarmLow = false;
318 }
319 response.thresholdLevelsStates =
George Liu33d90e12022-05-16 12:54:20 +0800320 (static_cast<uint8_t>(critAlarmHigh) << 3) |
321 (static_cast<uint8_t>(critAlarmLow) << 2) |
322 (static_cast<uint8_t>(warningAlarmHigh) << 1) |
323 (static_cast<uint8_t>(warningAlarmLow));
Konstantin Aladyshev778f6592021-11-02 11:28:25 +0300324
Tom Josephe05b2922017-09-07 00:43:16 +0530325 return response;
326}
327
Lei YU8c2c0482021-09-16 17:28:28 +0800328#else
329
Lei YU8c2c0482021-09-16 17:28:28 +0800330/**
331 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
332 * reading command response.
333 *
334 * @param[in] id - The sensor id
335 * @param[in] sensorInfo - Dbus info related to sensor.
336 * @param[in] msg - Dbus message from match callback.
337 *
338 * @return Response for get sensor reading command.
339 */
340std::optional<GetSensorResponse> assertion(uint8_t id, const Info& sensorInfo,
Lei YU8e8152c2021-12-06 20:11:08 +0800341 const PropertyMap& properties);
Lei YU8c2c0482021-09-16 17:28:28 +0800342
343/**
344 * @brief Maps the Dbus info to the reading field in the Get sensor reading
345 * command response.
346 *
347 * @param[in] id - The sensor id
348 * @param[in] sensorInfo - Dbus info related to sensor.
349 * @param[in] msg - Dbus message from match callback.
350 *
351 * @return Response for get sensor reading command.
352 */
353std::optional<GetSensorResponse> eventdata2(uint8_t id, const Info& sensorInfo,
Lei YU8e8152c2021-12-06 20:11:08 +0800354 const PropertyMap& properties);
Lei YU8c2c0482021-09-16 17:28:28 +0800355
356/**
357 * @brief readingAssertion is a case where the entire assertion state field
358 * serves as the sensor value.
359 *
360 * @tparam T - type of the dbus property related to sensor.
361 * @param[in] id - The sensor id
362 * @param[in] sensorInfo - Dbus info related to sensor.
363 * @param[in] msg - Dbus message from match callback.
364 *
365 * @return Response for get sensor reading command.
366 */
367template <typename T>
Patrick Williams1318a5e2024-08-16 15:19:54 -0400368std::optional<GetSensorResponse> readingAssertion(
369 uint8_t id, const Info& sensorInfo, const PropertyMap& properties)
Lei YU8c2c0482021-09-16 17:28:28 +0800370{
Lei YU7d720342021-09-18 18:39:09 +0800371 GetSensorResponse response{};
Lei YU7d720342021-09-18 18:39:09 +0800372 enableScanning(&response);
373
Lei YU7d720342021-09-18 18:39:09 +0800374 auto iter = properties.find(
375 sensorInfo.propertyInterfaces.begin()->second.begin()->first);
376 if (iter == properties.end())
377 {
378 return {};
379 }
380
381 setAssertionBytes(static_cast<uint16_t>(std::get<T>(iter->second)),
382 &response);
383
384 if (!sensorCacheMap[id].has_value())
385 {
386 sensorCacheMap[id] = SensorData{};
387 }
388 sensorCacheMap[id]->response = response;
389 return response;
Lei YU8c2c0482021-09-16 17:28:28 +0800390}
391
392/** @brief Get sensor reading from the dbus message from match
393 *
394 * @tparam T - type of the dbus property related to sensor.
395 * @param[in] id - The sensor id
396 * @param[in] sensorInfo - Dbus info related to sensor.
397 * @param[in] msg - Dbus message from match callback.
398 *
399 * @return Response for get sensor reading command.
400 */
401template <typename T>
402std::optional<GetSensorResponse> readingData(uint8_t id, const Info& sensorInfo,
Lei YU8e8152c2021-12-06 20:11:08 +0800403 const PropertyMap& properties)
Lei YU8c2c0482021-09-16 17:28:28 +0800404{
Lei YU8e8152c2021-12-06 20:11:08 +0800405 auto iter = properties.find("Functional");
406 if (iter != properties.end())
Lei YUa55e9ea2021-09-18 15:15:17 +0800407 {
Lei YU8e8152c2021-12-06 20:11:08 +0800408 sensorCacheMap[id]->functional = std::get<bool>(iter->second);
Lei YUa55e9ea2021-09-18 15:15:17 +0800409 }
Lei YU8e8152c2021-12-06 20:11:08 +0800410 iter = properties.find("Available");
411 if (iter != properties.end())
412 {
413 sensorCacheMap[id]->available = std::get<bool>(iter->second);
414 }
415#ifdef UPDATE_FUNCTIONAL_ON_FAIL
416 if (sensorCacheMap[id])
417 {
418 if (!sensorCacheMap[id]->functional)
419 {
420 throw SensorFunctionalError();
421 }
422 }
423#endif
Lei YU97140502021-09-17 13:49:43 +0800424
425 GetSensorResponse response{};
426
427 enableScanning(&response);
428
Lei YU8e8152c2021-12-06 20:11:08 +0800429 iter = properties.find(
Lei YU97140502021-09-17 13:49:43 +0800430 sensorInfo.propertyInterfaces.begin()->second.begin()->first);
431 if (iter == properties.end())
432 {
433 return {};
434 }
435
436 double value = std::get<T>(iter->second) *
437 std::pow(10, sensorInfo.scale - sensorInfo.exponentR);
Patrick Williams1318a5e2024-08-16 15:19:54 -0400438 int32_t rawData =
439 (value - sensorInfo.scaledOffset) / sensorInfo.coefficientM;
Lei YU97140502021-09-17 13:49:43 +0800440
441 constexpr uint8_t sensorUnitsSignedBits = 2 << 6;
442 constexpr uint8_t signedDataFormat = 0x80;
443 // if sensorUnits1 [7:6] = 10b, sensor is signed
444 if ((sensorInfo.sensorUnits1 & sensorUnitsSignedBits) == signedDataFormat)
445 {
446 if (rawData > std::numeric_limits<int8_t>::max() ||
447 rawData < std::numeric_limits<int8_t>::lowest())
448 {
George Liu9b745a82024-07-19 09:09:36 +0800449 lg2::error("Value out of range");
Lei YU97140502021-09-17 13:49:43 +0800450 throw std::out_of_range("Value out of range");
451 }
452 setReading(static_cast<int8_t>(rawData), &response);
453 }
454 else
455 {
456 if (rawData > std::numeric_limits<uint8_t>::max() ||
457 rawData < std::numeric_limits<uint8_t>::lowest())
458 {
George Liu9b745a82024-07-19 09:09:36 +0800459 lg2::error("Value out of range");
Lei YU97140502021-09-17 13:49:43 +0800460 throw std::out_of_range("Value out of range");
461 }
462 setReading(static_cast<uint8_t>(rawData), &response);
463 }
464
465 if (!std::isfinite(value))
466 {
467 response.readingOrStateUnavailable = 1;
468 }
469
470 if (!sensorCacheMap[id].has_value())
471 {
472 sensorCacheMap[id] = SensorData{};
473 }
474 sensorCacheMap[id]->response = response;
475
476 return response;
Lei YU8c2c0482021-09-16 17:28:28 +0800477}
478
479#endif // FEATURE_SENSORS_CACHE
480
Patrick Venture0b02be92018-08-31 11:55:55 -0700481} // namespace get
Tom Joseph816e92b2017-09-06 19:23:00 +0530482
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500483namespace set
484{
485
486/** @brief Make a DBus message for a Dbus call
487 * @param[in] updateInterface - Interface name
488 * @param[in] sensorPath - Path of the sensor
489 * @param[in] command - command to be executed
490 * @param[in] sensorInterface - DBus interface of sensor
491 * @return a dbus message
492 */
493IpmiUpdateData makeDbusMsg(const std::string& updateInterface,
494 const std::string& sensorPath,
495 const std::string& command,
496 const std::string& sensorInterface);
497
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500498/** @brief Update d-bus based on assertion type sensor data
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500499 * @param[in] cmdData - input sensor data
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500500 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500501 * @return a IPMI error code
502 */
George Liu23c868c2025-07-04 09:31:35 +0800503ipmi::Cc assertion(const SetSensorReadingReq& cmdData, const Info& sensorInfo);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500504
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500505/** @brief Update d-bus based on a reading assertion
506 * @tparam T - type of d-bus property mapping this sensor
507 * @param[in] cmdData - input sensor data
508 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500509 * @return a IPMI error code
510 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700511template <typename T>
George Liu23c868c2025-07-04 09:31:35 +0800512ipmi::Cc readingAssertion(const SetSensorReadingReq& cmdData,
513 const Info& sensorInfo)
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500514{
Patrick Williams1318a5e2024-08-16 15:19:54 -0400515 auto msg =
516 makeDbusMsg("org.freedesktop.DBus.Properties", sensorInfo.sensorPath,
517 "Set", sensorInfo.sensorInterface);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500518
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500519 const auto& interface = sensorInfo.propertyInterfaces.begin();
520 msg.append(interface->first);
521 for (const auto& property : interface->second)
522 {
523 msg.append(property.first);
Patrick Williams1318a5e2024-08-16 15:19:54 -0400524 std::variant<T> value = static_cast<T>(
525 (cmdData.assertOffset8_14 << 8) | cmdData.assertOffset0_7);
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500526 msg.append(value);
527 }
528 return updateToDbus(msg);
529}
530
Emily Shaffercc941e12017-06-14 13:06:26 -0700531/** @brief Update d-bus based on a discrete reading
532 * @param[in] cmdData - input sensor data
533 * @param[in] sensorInfo - sensor d-bus info
534 * @return an IPMI error code
535 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700536template <typename T>
George Liu23c868c2025-07-04 09:31:35 +0800537ipmi::Cc readingData(const SetSensorReadingReq& cmdData, const Info& sensorInfo)
Emily Shaffercc941e12017-06-14 13:06:26 -0700538{
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -0500539 T raw_value = (sensorInfo.coefficientM * cmdData.reading) +
540 sensorInfo.scaledOffset;
Tom Joseph22102152018-03-02 18:46:39 +0530541
Patrick Venture586d35b2018-09-07 19:56:18 -0700542 raw_value *= std::pow(10, sensorInfo.exponentR - sensorInfo.scale);
Tom Joseph22102152018-03-02 18:46:39 +0530543
Patrick Williams1318a5e2024-08-16 15:19:54 -0400544 auto msg =
545 makeDbusMsg("org.freedesktop.DBus.Properties", sensorInfo.sensorPath,
546 "Set", sensorInfo.sensorInterface);
Emily Shaffercc941e12017-06-14 13:06:26 -0700547
548 const auto& interface = sensorInfo.propertyInterfaces.begin();
549 msg.append(interface->first);
550
Emily Shaffercc941e12017-06-14 13:06:26 -0700551 for (const auto& property : interface->second)
552 {
553 msg.append(property.first);
Vernon Mauery16b86932019-05-01 08:36:11 -0700554 std::variant<T> value = raw_value;
Emily Shaffercc941e12017-06-14 13:06:26 -0700555 msg.append(value);
556 }
557 return updateToDbus(msg);
558}
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500559
560/** @brief Update d-bus based on eventdata type sensor data
561 * @param[in] cmdData - input sensor data
562 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500563 * @return a IPMI error code
564 */
George Liu23c868c2025-07-04 09:31:35 +0800565ipmi::Cc eventdata(const SetSensorReadingReq& cmdData, const Info& sensorInfo,
566 uint8_t data);
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500567
568/** @brief Update d-bus based on eventdata1 type sensor data
569 * @param[in] cmdData - input sensor data
570 * @param[in] sensorInfo - sensor d-bus info
571 * @return a IPMI error code
572 */
George Liu23c868c2025-07-04 09:31:35 +0800573inline ipmi::Cc eventdata1(const SetSensorReadingReq& cmdData,
574 const Info& sensorInfo)
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500575{
576 return eventdata(cmdData, sensorInfo, cmdData.eventData1);
577}
578
579/** @brief Update d-bus based on eventdata2 type sensor data
580 * @param[in] cmdData - input sensor data
581 * @param[in] sensorInfo - sensor d-bus info
582 * @return a IPMI error code
583 */
George Liu23c868c2025-07-04 09:31:35 +0800584inline ipmi::Cc eventdata2(const SetSensorReadingReq& cmdData,
585 const Info& sensorInfo)
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500586{
587 return eventdata(cmdData, sensorInfo, cmdData.eventData2);
588}
589
590/** @brief Update d-bus based on eventdata3 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 eventdata3(const SetSensorReadingReq& cmdData,
596 const Info& sensorInfo)
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500597{
598 return eventdata(cmdData, sensorInfo, cmdData.eventData3);
599}
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500600
Patrick Venture0b02be92018-08-31 11:55:55 -0700601} // namespace set
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500602
603namespace notify
604{
605
606/** @brief Make a DBus message for a Dbus call
607 * @param[in] updateInterface - Interface name
608 * @param[in] sensorPath - Path of the sensor
609 * @param[in] command - command to be executed
610 * @param[in] sensorInterface - DBus interface of sensor
611 * @return a dbus message
612 */
613IpmiUpdateData makeDbusMsg(const std::string& updateInterface,
614 const std::string& sensorPath,
615 const std::string& command,
616 const std::string& sensorInterface);
617
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500618/** @brief Update d-bus based on assertion type sensor data
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500619 * @param[in] interfaceMap - sensor interface
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500620 * @param[in] cmdData - input sensor data
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500621 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500622 * @return a IPMI error code
623 */
George Liu23c868c2025-07-04 09:31:35 +0800624ipmi::Cc assertion(const SetSensorReadingReq& cmdData, const Info& sensorInfo);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500625
Patrick Venture0b02be92018-08-31 11:55:55 -0700626} // namespace notify
Tom Joseph816e92b2017-09-06 19:23:00 +0530627
628namespace inventory
629{
630
631namespace get
632{
633
Lei YUff8c9b42021-10-15 14:20:57 +0800634#ifndef FEATURE_SENSORS_CACHE
635
Tom Joseph816e92b2017-09-06 19:23:00 +0530636/**
637 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
638 * reading command response.
639 *
640 * @param[in] sensorInfo - Dbus info related to sensor.
641 *
642 * @return Response for get sensor reading command.
643 */
644GetSensorResponse assertion(const Info& sensorInfo);
645
Lei YUff8c9b42021-10-15 14:20:57 +0800646#else
647
648/**
649 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
650 * reading command response.
651 *
652 * @param[in] id - The sensor id
653 * @param[in] sensorInfo - Dbus info related to sensor.
654 * @param[in] msg - Dbus message from match callback.
655 *
656 * @return Response for get sensor reading command.
657 */
658std::optional<GetSensorResponse> assertion(uint8_t id, const Info& sensorInfo,
Lei YU8e8152c2021-12-06 20:11:08 +0800659 const PropertyMap& properties);
Lei YUff8c9b42021-10-15 14:20:57 +0800660
661#endif
662
Tom Joseph816e92b2017-09-06 19:23:00 +0530663} // namespace get
664
665} // namespace inventory
Patrick Venture0b02be92018-08-31 11:55:55 -0700666} // namespace sensor
667} // namespace ipmi