blob: 6c3a8e5e073ec20a5e15bd68a7c5d7f5d449de76 [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>
11#include <phosphor-logging/log.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
44/** @brief get the D-Bus service and service path
45 * @param[in] bus - The Dbus bus object
46 * @param[in] interface - interface to the service
47 * @param[in] path - interested path in the list of objects
48 * @return pair of service path and service
49 */
Patrick Williams5d82f472022-07-22 19:26:53 -050050ServicePath getServiceAndPath(sdbusplus::bus_t& bus,
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -050051 const std::string& interface,
52 const std::string& path = std::string());
53
54/** @brief Make assertion set from input data
55 * @param[in] cmdData - Input sensor data
56 * @return pair of assertion and deassertion set
57 */
58AssertionSet getAssertionSet(const SetSensorReadingReq& cmdData);
59
60/** @brief send the message to DBus
61 * @param[in] msg - message to send
62 * @return failure status in IPMI error code
63 */
Dhruvaraj Subhashchandran2a444d02017-08-07 01:45:14 -050064ipmi_ret_t updateToDbus(IpmiUpdateData& msg);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -050065
Tom Joseph816e92b2017-09-06 19:23:00 +053066namespace get
67{
68
Tom Josephb0adbcd2018-01-24 11:51:29 +053069/** @brief Populate sensor name from the D-Bus property associated with the
70 * sensor. In the example entry from the yaml, the name of the D-bus
71 * property "AttemptsLeft" is the sensor name.
72 *
73 * 0x07:
74 * sensorType: 195
75 * path: /xyz/openbmc_project/state/host0
76 * sensorReadingType: 0x6F
77 * serviceInterface: org.freedesktop.DBus.Properties
78 * readingType: readingAssertion
79 * sensorNamePattern: nameProperty
80 * interfaces:
81 * xyz.openbmc_project.Control.Boot.RebootAttempts:
82 * AttemptsLeft:
83 * Offsets:
84 * 0xFF:
85 * type: uint32_t
86 *
87 *
88 * @param[in] sensorInfo - Dbus info related to sensor.
89 *
90 * @return On success return the sensor name for the sensor.
91 */
92inline SensorName nameProperty(const Info& sensorInfo)
93{
94 return sensorInfo.propertyInterfaces.begin()->second.begin()->first;
95}
96
97/** @brief Populate sensor name from the D-Bus object associated with the
98 * sensor. If the object path is /system/chassis/motherboard/dimm0 then
99 * the leaf dimm0 is considered as the sensor name.
100 *
101 * @param[in] sensorInfo - Dbus info related to sensor.
102 *
103 * @return On success return the sensor name for the sensor.
104 */
105inline SensorName nameLeaf(const Info& sensorInfo)
106{
107 return sensorInfo.sensorPath.substr(
Patrick Venture0b02be92018-08-31 11:55:55 -0700108 sensorInfo.sensorPath.find_last_of('/') + 1,
109 sensorInfo.sensorPath.length());
Tom Josephb0adbcd2018-01-24 11:51:29 +0530110}
111
112/** @brief Populate sensor name from the D-Bus object associated with the
Lotus Xu2101a442020-12-24 16:01:56 +0800113 * sensor and the property.
114 * If the object path is /xyz/openbmc_project/inventory/Fan0 and
115 * the property is Present, the leaf Fan0 and the Property is
116 * joined to Fan0_Present as the sensor name.
117 *
118 * @param[in] sensorInfo - Dbus info related to sensor.
119 *
120 * @return On success return the sensor name for the sensor.
121 */
122inline SensorName nameLeafProperty(const Info& sensorInfo)
123{
124 return nameLeaf(sensorInfo) + "_" + nameProperty(sensorInfo);
125}
126
127/** @brief Populate sensor name from the D-Bus object associated with the
Tom Josephb0adbcd2018-01-24 11:51:29 +0530128 * sensor. If the object path is /system/chassis/motherboard/cpu0/core0
129 * then the sensor name is cpu0_core0. The leaf and the parent is put
130 * together to get the sensor name.
131 *
132 * @param[in] sensorInfo - Dbus info related to sensor.
133 *
134 * @return On success return the sensor name for the sensor.
135 */
136SensorName nameParentLeaf(const Info& sensorInfo);
137
Tom Joseph816e92b2017-09-06 19:23:00 +0530138/**
139 * @brief Helper function to map the dbus info to sensor's assertion status
140 * for the get sensor reading command.
141 *
142 * @param[in] sensorInfo - Dbus info related to sensor.
143 * @param[in] path - Dbus object path.
144 * @param[in] interface - Dbus interface.
145 *
146 * @return Response for get sensor reading command.
147 */
148GetSensorResponse mapDbusToAssertion(const Info& sensorInfo,
149 const InstancePath& path,
150 const DbusInterface& interface);
151
Lei YU8c2c0482021-09-16 17:28:28 +0800152#ifndef FEATURE_SENSORS_CACHE
Tom Joseph816e92b2017-09-06 19:23:00 +0530153/**
154 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
155 * reading command response.
156 *
157 * @param[in] sensorInfo - Dbus info related to sensor.
158 *
159 * @return Response for get sensor reading command.
160 */
161GetSensorResponse assertion(const Info& sensorInfo);
162
Tom Josephe4014fc2017-09-06 23:57:36 +0530163/**
164 * @brief Maps the Dbus info to the reading field in the Get sensor reading
165 * command response.
166 *
167 * @param[in] sensorInfo - Dbus info related to sensor.
168 *
169 * @return Response for get sensor reading command.
170 */
171GetSensorResponse eventdata2(const Info& sensorInfo);
172
Tom Joseph295f17e2017-09-07 00:09:46 +0530173/**
174 * @brief readingAssertion is a case where the entire assertion state field
175 * serves as the sensor value.
176 *
177 * @tparam T - type of the dbus property related to sensor.
178 * @param[in] sensorInfo - Dbus info related to sensor.
179 *
180 * @return Response for get sensor reading command.
181 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700182template <typename T>
Tom Joseph295f17e2017-09-07 00:09:46 +0530183GetSensorResponse readingAssertion(const Info& sensorInfo)
184{
Patrick Williams5d82f472022-07-22 19:26:53 -0500185 sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
Patrick Venture0b02be92018-08-31 11:55:55 -0700186 GetSensorResponse response{};
Tom Joseph295f17e2017-09-07 00:09:46 +0530187
Jeremy Kerr3dc35582020-05-17 15:47:07 +0800188 enableScanning(&response);
189
Patrick Venture0b02be92018-08-31 11:55:55 -0700190 auto service = ipmi::getService(bus, sensorInfo.sensorInterface,
Tom Joseph295f17e2017-09-07 00:09:46 +0530191 sensorInfo.sensorPath);
192
193 auto propValue = ipmi::getDbusProperty(
Patrick Venture0b02be92018-08-31 11:55:55 -0700194 bus, service, sensorInfo.sensorPath,
195 sensorInfo.propertyInterfaces.begin()->first,
196 sensorInfo.propertyInterfaces.begin()->second.begin()->first);
Tom Joseph295f17e2017-09-07 00:09:46 +0530197
Sui Chen4cc42552019-09-11 10:28:35 -0700198 setAssertionBytes(static_cast<uint16_t>(std::get<T>(propValue)), &response);
Tom Joseph295f17e2017-09-07 00:09:46 +0530199
200 return response;
201}
202
Tom Josephe05b2922017-09-07 00:43:16 +0530203/** @brief Map the Dbus info to the reading field in the Get sensor reading
204 * command response
205 *
206 * @tparam T - type of the dbus property related to sensor.
207 * @param[in] sensorInfo - Dbus info related to sensor.
208 *
209 * @return Response for get sensor reading command.
210 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700211template <typename T>
Tom Josephe05b2922017-09-07 00:43:16 +0530212GetSensorResponse readingData(const Info& sensorInfo)
213{
Patrick Williams5d82f472022-07-22 19:26:53 -0500214 sdbusplus::bus_t bus{ipmid_get_sd_bus_connection()};
Tom Josephe05b2922017-09-07 00:43:16 +0530215
Sui Chen4cc42552019-09-11 10:28:35 -0700216 GetSensorResponse response{};
217
218 enableScanning(&response);
Tom Josephe05b2922017-09-07 00:43:16 +0530219
Patrick Venture0b02be92018-08-31 11:55:55 -0700220 auto service = ipmi::getService(bus, sensorInfo.sensorInterface,
Tom Josephe05b2922017-09-07 00:43:16 +0530221 sensorInfo.sensorPath);
222
Brandon Kim9cf85622019-06-19 12:05:08 -0700223#ifdef UPDATE_FUNCTIONAL_ON_FAIL
224 // Check the OperationalStatus interface for functional property
225 if (sensorInfo.propertyInterfaces.begin()->first ==
226 "xyz.openbmc_project.Sensor.Value")
227 {
228 bool functional = true;
229 try
230 {
231 auto funcValue = ipmi::getDbusProperty(
232 bus, service, sensorInfo.sensorPath,
233 "xyz.openbmc_project.State.Decorator.OperationalStatus",
234 "Functional");
235 functional = std::get<bool>(funcValue);
236 }
237 catch (...)
238 {
239 // No-op if Functional property could not be found since this
240 // check is only valid for Sensor.Value read for hwmonio
241 }
242 if (!functional)
243 {
244 throw SensorFunctionalError();
245 }
246 }
247#endif
248
Tom Josephe05b2922017-09-07 00:43:16 +0530249 auto propValue = ipmi::getDbusProperty(
Patrick Venture0b02be92018-08-31 11:55:55 -0700250 bus, service, sensorInfo.sensorPath,
251 sensorInfo.propertyInterfaces.begin()->first,
252 sensorInfo.propertyInterfaces.begin()->second.begin()->first);
Tom Josephe05b2922017-09-07 00:43:16 +0530253
Vernon Maueryf442e112019-04-09 11:44:36 -0700254 double value = std::get<T>(propValue) *
Patrick Venture586d35b2018-09-07 19:56:18 -0700255 std::pow(10, sensorInfo.scale - sensorInfo.exponentR);
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -0500256 int32_t rawData = (value - sensorInfo.scaledOffset) /
257 sensorInfo.coefficientM;
Tom Josephe05b2922017-09-07 00:43:16 +0530258
Tony Leec5324252019-10-31 17:24:16 +0800259 constexpr uint8_t sensorUnitsSignedBits = 2 << 6;
260 constexpr uint8_t signedDataFormat = 0x80;
261 // if sensorUnits1 [7:6] = 10b, sensor is signed
Willy Tu9154caa2021-12-02 02:28:54 -0800262 int32_t minClamp;
263 int32_t maxClamp;
Tony Leec5324252019-10-31 17:24:16 +0800264 if ((sensorInfo.sensorUnits1 & sensorUnitsSignedBits) == signedDataFormat)
265 {
Willy Tu9154caa2021-12-02 02:28:54 -0800266 minClamp = std::numeric_limits<int8_t>::lowest();
267 maxClamp = std::numeric_limits<int8_t>::max();
Tony Leec5324252019-10-31 17:24:16 +0800268 }
269 else
270 {
Willy Tu9154caa2021-12-02 02:28:54 -0800271 minClamp = std::numeric_limits<uint8_t>::lowest();
272 maxClamp = std::numeric_limits<uint8_t>::max();
Tony Leec5324252019-10-31 17:24:16 +0800273 }
Willy Tu9154caa2021-12-02 02:28:54 -0800274 setReading(static_cast<uint8_t>(std::clamp(rawData, minClamp, maxClamp)),
275 &response);
Tom Josephe05b2922017-09-07 00:43:16 +0530276
Konstantin Aladyshevf93b29c2021-05-05 14:49:14 +0300277 if (!std::isfinite(value))
278 {
279 response.readingOrStateUnavailable = 1;
280 }
281
Konstantin Aladyshev778f6592021-11-02 11:28:25 +0300282 bool critAlarmHigh;
283 try
284 {
285 critAlarmHigh = std::get<bool>(ipmi::getDbusProperty(
286 bus, service, sensorInfo.sensorPath,
287 "xyz.openbmc_project.Sensor.Threshold.Critical",
288 "CriticalAlarmHigh"));
289 }
290 catch (const std::exception& e)
291 {
292 critAlarmHigh = false;
293 }
294 bool critAlarmLow;
295 try
296 {
297 critAlarmLow = std::get<bool>(ipmi::getDbusProperty(
298 bus, service, sensorInfo.sensorPath,
299 "xyz.openbmc_project.Sensor.Threshold.Critical",
300 "CriticalAlarmLow"));
301 }
302 catch (const std::exception& e)
303 {
304 critAlarmLow = false;
305 }
306 bool warningAlarmHigh;
307 try
308 {
309 warningAlarmHigh = std::get<bool>(ipmi::getDbusProperty(
310 bus, service, sensorInfo.sensorPath,
311 "xyz.openbmc_project.Sensor.Threshold.Warning",
312 "WarningAlarmHigh"));
313 }
314 catch (const std::exception& e)
315 {
316 warningAlarmHigh = false;
317 }
318 bool warningAlarmLow;
319 try
320 {
321 warningAlarmLow = std::get<bool>(ipmi::getDbusProperty(
322 bus, service, sensorInfo.sensorPath,
Tim Leed09db492022-05-30 10:22:34 +0800323 "xyz.openbmc_project.Sensor.Threshold.Warning", "WarningAlarmLow"));
Konstantin Aladyshev778f6592021-11-02 11:28:25 +0300324 }
325 catch (const std::exception& e)
326 {
327 warningAlarmLow = false;
328 }
329 response.thresholdLevelsStates =
George Liu33d90e12022-05-16 12:54:20 +0800330 (static_cast<uint8_t>(critAlarmHigh) << 3) |
331 (static_cast<uint8_t>(critAlarmLow) << 2) |
332 (static_cast<uint8_t>(warningAlarmHigh) << 1) |
333 (static_cast<uint8_t>(warningAlarmLow));
Konstantin Aladyshev778f6592021-11-02 11:28:25 +0300334
Tom Josephe05b2922017-09-07 00:43:16 +0530335 return response;
336}
337
Lei YU8c2c0482021-09-16 17:28:28 +0800338#else
339
Lei YU8c2c0482021-09-16 17:28:28 +0800340/**
341 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
342 * reading command response.
343 *
344 * @param[in] id - The sensor id
345 * @param[in] sensorInfo - Dbus info related to sensor.
346 * @param[in] msg - Dbus message from match callback.
347 *
348 * @return Response for get sensor reading command.
349 */
350std::optional<GetSensorResponse> assertion(uint8_t id, const Info& sensorInfo,
Lei YU8e8152c2021-12-06 20:11:08 +0800351 const PropertyMap& properties);
Lei YU8c2c0482021-09-16 17:28:28 +0800352
353/**
354 * @brief Maps the Dbus info to the reading field in the Get sensor reading
355 * 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> eventdata2(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 readingAssertion is a case where the entire assertion state field
368 * serves as the sensor value.
369 *
370 * @tparam T - type of the dbus property related to sensor.
371 * @param[in] id - The sensor id
372 * @param[in] sensorInfo - Dbus info related to sensor.
373 * @param[in] msg - Dbus message from match callback.
374 *
375 * @return Response for get sensor reading command.
376 */
377template <typename T>
Lei YU8e8152c2021-12-06 20:11:08 +0800378std::optional<GetSensorResponse> readingAssertion(uint8_t id,
379 const Info& sensorInfo,
380 const PropertyMap& properties)
Lei YU8c2c0482021-09-16 17:28:28 +0800381{
Lei YU7d720342021-09-18 18:39:09 +0800382 GetSensorResponse response{};
Lei YU7d720342021-09-18 18:39:09 +0800383 enableScanning(&response);
384
Lei YU7d720342021-09-18 18:39:09 +0800385 auto iter = properties.find(
386 sensorInfo.propertyInterfaces.begin()->second.begin()->first);
387 if (iter == properties.end())
388 {
389 return {};
390 }
391
392 setAssertionBytes(static_cast<uint16_t>(std::get<T>(iter->second)),
393 &response);
394
395 if (!sensorCacheMap[id].has_value())
396 {
397 sensorCacheMap[id] = SensorData{};
398 }
399 sensorCacheMap[id]->response = response;
400 return response;
Lei YU8c2c0482021-09-16 17:28:28 +0800401}
402
403/** @brief Get sensor reading from the dbus message from match
404 *
405 * @tparam T - type of the dbus property related to sensor.
406 * @param[in] id - The sensor id
407 * @param[in] sensorInfo - Dbus info related to sensor.
408 * @param[in] msg - Dbus message from match callback.
409 *
410 * @return Response for get sensor reading command.
411 */
412template <typename T>
413std::optional<GetSensorResponse> readingData(uint8_t id, const Info& sensorInfo,
Lei YU8e8152c2021-12-06 20:11:08 +0800414 const PropertyMap& properties)
Lei YU8c2c0482021-09-16 17:28:28 +0800415{
Lei YU8e8152c2021-12-06 20:11:08 +0800416 auto iter = properties.find("Functional");
417 if (iter != properties.end())
Lei YUa55e9ea2021-09-18 15:15:17 +0800418 {
Lei YU8e8152c2021-12-06 20:11:08 +0800419 sensorCacheMap[id]->functional = std::get<bool>(iter->second);
Lei YUa55e9ea2021-09-18 15:15:17 +0800420 }
Lei YU8e8152c2021-12-06 20:11:08 +0800421 iter = properties.find("Available");
422 if (iter != properties.end())
423 {
424 sensorCacheMap[id]->available = std::get<bool>(iter->second);
425 }
426#ifdef UPDATE_FUNCTIONAL_ON_FAIL
427 if (sensorCacheMap[id])
428 {
429 if (!sensorCacheMap[id]->functional)
430 {
431 throw SensorFunctionalError();
432 }
433 }
434#endif
Lei YU97140502021-09-17 13:49:43 +0800435
436 GetSensorResponse response{};
437
438 enableScanning(&response);
439
Lei YU8e8152c2021-12-06 20:11:08 +0800440 iter = properties.find(
Lei YU97140502021-09-17 13:49:43 +0800441 sensorInfo.propertyInterfaces.begin()->second.begin()->first);
442 if (iter == properties.end())
443 {
444 return {};
445 }
446
447 double value = std::get<T>(iter->second) *
448 std::pow(10, sensorInfo.scale - sensorInfo.exponentR);
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -0500449 int32_t rawData = (value - sensorInfo.scaledOffset) /
450 sensorInfo.coefficientM;
Lei YU97140502021-09-17 13:49:43 +0800451
452 constexpr uint8_t sensorUnitsSignedBits = 2 << 6;
453 constexpr uint8_t signedDataFormat = 0x80;
454 // if sensorUnits1 [7:6] = 10b, sensor is signed
455 if ((sensorInfo.sensorUnits1 & sensorUnitsSignedBits) == signedDataFormat)
456 {
457 if (rawData > std::numeric_limits<int8_t>::max() ||
458 rawData < std::numeric_limits<int8_t>::lowest())
459 {
460 log<level::ERR>("Value out of range");
461 throw std::out_of_range("Value out of range");
462 }
463 setReading(static_cast<int8_t>(rawData), &response);
464 }
465 else
466 {
467 if (rawData > std::numeric_limits<uint8_t>::max() ||
468 rawData < std::numeric_limits<uint8_t>::lowest())
469 {
470 log<level::ERR>("Value out of range");
471 throw std::out_of_range("Value out of range");
472 }
473 setReading(static_cast<uint8_t>(rawData), &response);
474 }
475
476 if (!std::isfinite(value))
477 {
478 response.readingOrStateUnavailable = 1;
479 }
480
481 if (!sensorCacheMap[id].has_value())
482 {
483 sensorCacheMap[id] = SensorData{};
484 }
485 sensorCacheMap[id]->response = response;
486
487 return response;
Lei YU8c2c0482021-09-16 17:28:28 +0800488}
489
490#endif // FEATURE_SENSORS_CACHE
491
Patrick Venture0b02be92018-08-31 11:55:55 -0700492} // namespace get
Tom Joseph816e92b2017-09-06 19:23:00 +0530493
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500494namespace set
495{
496
497/** @brief Make a DBus message for a Dbus call
498 * @param[in] updateInterface - Interface name
499 * @param[in] sensorPath - Path of the sensor
500 * @param[in] command - command to be executed
501 * @param[in] sensorInterface - DBus interface of sensor
502 * @return a dbus message
503 */
504IpmiUpdateData makeDbusMsg(const std::string& updateInterface,
505 const std::string& sensorPath,
506 const std::string& command,
507 const std::string& sensorInterface);
508
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500509/** @brief Update d-bus based on assertion type sensor data
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500510 * @param[in] cmdData - input sensor data
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500511 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500512 * @return a IPMI error code
513 */
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500514ipmi_ret_t assertion(const SetSensorReadingReq& cmdData,
515 const Info& sensorInfo);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500516
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500517/** @brief Update d-bus based on a reading assertion
518 * @tparam T - type of d-bus property mapping this sensor
519 * @param[in] cmdData - input sensor data
520 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500521 * @return a IPMI error code
522 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700523template <typename T>
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500524ipmi_ret_t readingAssertion(const SetSensorReadingReq& cmdData,
525 const Info& sensorInfo)
526{
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -0500527 auto msg = makeDbusMsg("org.freedesktop.DBus.Properties",
528 sensorInfo.sensorPath, "Set",
529 sensorInfo.sensorInterface);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500530
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500531 const auto& interface = sensorInfo.propertyInterfaces.begin();
532 msg.append(interface->first);
533 for (const auto& property : interface->second)
534 {
535 msg.append(property.first);
Andrew Geissler6467ed22020-05-16 16:03:53 -0500536 std::variant<T> value = static_cast<T>((cmdData.assertOffset8_14 << 8) |
537 cmdData.assertOffset0_7);
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500538 msg.append(value);
539 }
540 return updateToDbus(msg);
541}
542
Emily Shaffercc941e12017-06-14 13:06:26 -0700543/** @brief Update d-bus based on a discrete reading
544 * @param[in] cmdData - input sensor data
545 * @param[in] sensorInfo - sensor d-bus info
546 * @return an IPMI error code
547 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700548template <typename T>
Emily Shaffercc941e12017-06-14 13:06:26 -0700549ipmi_ret_t readingData(const SetSensorReadingReq& cmdData,
550 const Info& sensorInfo)
551{
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -0500552 T raw_value = (sensorInfo.coefficientM * cmdData.reading) +
553 sensorInfo.scaledOffset;
Tom Joseph22102152018-03-02 18:46:39 +0530554
Patrick Venture586d35b2018-09-07 19:56:18 -0700555 raw_value *= std::pow(10, sensorInfo.exponentR - sensorInfo.scale);
Tom Joseph22102152018-03-02 18:46:39 +0530556
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -0500557 auto msg = makeDbusMsg("org.freedesktop.DBus.Properties",
558 sensorInfo.sensorPath, "Set",
559 sensorInfo.sensorInterface);
Emily Shaffercc941e12017-06-14 13:06:26 -0700560
561 const auto& interface = sensorInfo.propertyInterfaces.begin();
562 msg.append(interface->first);
563
Emily Shaffercc941e12017-06-14 13:06:26 -0700564 for (const auto& property : interface->second)
565 {
566 msg.append(property.first);
Vernon Mauery16b86932019-05-01 08:36:11 -0700567 std::variant<T> value = raw_value;
Emily Shaffercc941e12017-06-14 13:06:26 -0700568 msg.append(value);
569 }
570 return updateToDbus(msg);
571}
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500572
573/** @brief Update d-bus based on eventdata type sensor data
574 * @param[in] cmdData - input sensor data
575 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500576 * @return a IPMI error code
577 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700578ipmi_ret_t eventdata(const SetSensorReadingReq& cmdData, const Info& sensorInfo,
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500579 uint8_t data);
580
581/** @brief Update d-bus based on eventdata1 type sensor data
582 * @param[in] cmdData - input sensor data
583 * @param[in] sensorInfo - sensor d-bus info
584 * @return a IPMI error code
585 */
586inline ipmi_ret_t eventdata1(const SetSensorReadingReq& cmdData,
587 const Info& sensorInfo)
588{
589 return eventdata(cmdData, sensorInfo, cmdData.eventData1);
590}
591
592/** @brief Update d-bus based on eventdata2 type sensor data
593 * @param[in] cmdData - input sensor data
594 * @param[in] sensorInfo - sensor d-bus info
595 * @return a IPMI error code
596 */
597inline ipmi_ret_t eventdata2(const SetSensorReadingReq& cmdData,
598 const Info& sensorInfo)
599{
600 return eventdata(cmdData, sensorInfo, cmdData.eventData2);
601}
602
603/** @brief Update d-bus based on eventdata3 type sensor data
604 * @param[in] cmdData - input sensor data
605 * @param[in] sensorInfo - sensor d-bus info
606 * @return a IPMI error code
607 */
608inline ipmi_ret_t eventdata3(const SetSensorReadingReq& cmdData,
609 const Info& sensorInfo)
610{
611 return eventdata(cmdData, sensorInfo, cmdData.eventData3);
612}
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500613
Patrick Venture0b02be92018-08-31 11:55:55 -0700614} // namespace set
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500615
616namespace notify
617{
618
619/** @brief Make a DBus message for a Dbus call
620 * @param[in] updateInterface - Interface name
621 * @param[in] sensorPath - Path of the sensor
622 * @param[in] command - command to be executed
623 * @param[in] sensorInterface - DBus interface of sensor
624 * @return a dbus message
625 */
626IpmiUpdateData makeDbusMsg(const std::string& updateInterface,
627 const std::string& sensorPath,
628 const std::string& command,
629 const std::string& sensorInterface);
630
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500631/** @brief Update d-bus based on assertion type sensor data
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500632 * @param[in] interfaceMap - sensor interface
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500633 * @param[in] cmdData - input sensor data
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500634 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500635 * @return a IPMI error code
636 */
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500637ipmi_ret_t assertion(const SetSensorReadingReq& cmdData,
638 const Info& sensorInfo);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500639
Patrick Venture0b02be92018-08-31 11:55:55 -0700640} // namespace notify
Tom Joseph816e92b2017-09-06 19:23:00 +0530641
642namespace inventory
643{
644
645namespace get
646{
647
Lei YUff8c9b42021-10-15 14:20:57 +0800648#ifndef FEATURE_SENSORS_CACHE
649
Tom Joseph816e92b2017-09-06 19:23:00 +0530650/**
651 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
652 * reading command response.
653 *
654 * @param[in] sensorInfo - Dbus info related to sensor.
655 *
656 * @return Response for get sensor reading command.
657 */
658GetSensorResponse assertion(const Info& sensorInfo);
659
Lei YUff8c9b42021-10-15 14:20:57 +0800660#else
661
662/**
663 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
664 * reading command response.
665 *
666 * @param[in] id - The sensor id
667 * @param[in] sensorInfo - Dbus info related to sensor.
668 * @param[in] msg - Dbus message from match callback.
669 *
670 * @return Response for get sensor reading command.
671 */
672std::optional<GetSensorResponse> assertion(uint8_t id, const Info& sensorInfo,
Lei YU8e8152c2021-12-06 20:11:08 +0800673 const PropertyMap& properties);
Lei YUff8c9b42021-10-15 14:20:57 +0800674
675#endif
676
Tom Joseph816e92b2017-09-06 19:23:00 +0530677} // namespace get
678
679} // namespace inventory
Patrick Venture0b02be92018-08-31 11:55:55 -0700680} // namespace sensor
681} // namespace ipmi