blob: 6768634ce842dd79d66ecd6297986cac6313b79e [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
Patrick Venture586d35b2018-09-07 19:56:18 -07007#include <cmath>
Vernon Mauerye08fbff2019-04-03 09:19:34 -07008#include <ipmid/api.hpp>
Vernon Mauery33250242019-03-12 16:49:26 -07009#include <ipmid/types.hpp>
Vernon Mauery6a98fe72019-03-11 15:57:48 -070010#include <ipmid/utils.hpp>
Tony Leec5324252019-10-31 17:24:16 +080011#include <phosphor-logging/elog-errors.hpp>
12#include <phosphor-logging/log.hpp>
William A. Kennington III4c008022018-10-12 17:18:14 -070013#include <sdbusplus/message/types.hpp>
Patrick Venture0b02be92018-08-31 11:55:55 -070014
Lei YU97140502021-09-17 13:49:43 +080015#ifdef FEATURE_SENSORS_CACHE
Lei YUa55e9ea2021-09-18 15:15:17 +080016
Lei YU97140502021-09-17 13:49:43 +080017extern ipmi::sensor::SensorCacheMap sensorCacheMap;
Lei YUa55e9ea2021-09-18 15:15:17 +080018
19// The signal's message type is 0x04 from DBus spec:
20// https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages
21static constexpr auto msgTypeSignal = 0x04;
22
Lei YU97140502021-09-17 13:49:43 +080023#endif
24
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -050025namespace ipmi
26{
27namespace sensor
28{
29
30using Assertion = uint16_t;
31using Deassertion = uint16_t;
32using AssertionSet = std::pair<Assertion, Deassertion>;
33
34using Service = std::string;
35using Path = std::string;
36using Interface = std::string;
37
38using ServicePath = std::pair<Path, Service>;
39
40using Interfaces = std::vector<Interface>;
41
42using MapperResponseType = std::map<Path, std::map<Service, Interfaces>>;
Tony Leec5324252019-10-31 17:24:16 +080043using namespace phosphor::logging;
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -050044
45/** @brief get the D-Bus service and service path
46 * @param[in] bus - The Dbus bus object
47 * @param[in] interface - interface to the service
48 * @param[in] path - interested path in the list of objects
49 * @return pair of service path and service
50 */
51ServicePath getServiceAndPath(sdbusplus::bus::bus& bus,
52 const std::string& interface,
53 const std::string& path = std::string());
54
55/** @brief Make assertion set from input data
56 * @param[in] cmdData - Input sensor data
57 * @return pair of assertion and deassertion set
58 */
59AssertionSet getAssertionSet(const SetSensorReadingReq& cmdData);
60
61/** @brief send the message to DBus
62 * @param[in] msg - message to send
63 * @return failure status in IPMI error code
64 */
Dhruvaraj Subhashchandran2a444d02017-08-07 01:45:14 -050065ipmi_ret_t updateToDbus(IpmiUpdateData& msg);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -050066
Tom Joseph816e92b2017-09-06 19:23:00 +053067namespace get
68{
69
Tom Josephb0adbcd2018-01-24 11:51:29 +053070/** @brief Populate sensor name from the D-Bus property associated with the
71 * sensor. In the example entry from the yaml, the name of the D-bus
72 * property "AttemptsLeft" is the sensor name.
73 *
74 * 0x07:
75 * sensorType: 195
76 * path: /xyz/openbmc_project/state/host0
77 * sensorReadingType: 0x6F
78 * serviceInterface: org.freedesktop.DBus.Properties
79 * readingType: readingAssertion
80 * sensorNamePattern: nameProperty
81 * interfaces:
82 * xyz.openbmc_project.Control.Boot.RebootAttempts:
83 * AttemptsLeft:
84 * Offsets:
85 * 0xFF:
86 * type: uint32_t
87 *
88 *
89 * @param[in] sensorInfo - Dbus info related to sensor.
90 *
91 * @return On success return the sensor name for the sensor.
92 */
93inline SensorName nameProperty(const Info& sensorInfo)
94{
95 return sensorInfo.propertyInterfaces.begin()->second.begin()->first;
96}
97
98/** @brief Populate sensor name from the D-Bus object associated with the
99 * sensor. If the object path is /system/chassis/motherboard/dimm0 then
100 * the leaf dimm0 is considered as the sensor name.
101 *
102 * @param[in] sensorInfo - Dbus info related to sensor.
103 *
104 * @return On success return the sensor name for the sensor.
105 */
106inline SensorName nameLeaf(const Info& sensorInfo)
107{
108 return sensorInfo.sensorPath.substr(
Patrick Venture0b02be92018-08-31 11:55:55 -0700109 sensorInfo.sensorPath.find_last_of('/') + 1,
110 sensorInfo.sensorPath.length());
Tom Josephb0adbcd2018-01-24 11:51:29 +0530111}
112
113/** @brief Populate sensor name from the D-Bus object associated with the
Lotus Xu2101a442020-12-24 16:01:56 +0800114 * sensor and the property.
115 * If the object path is /xyz/openbmc_project/inventory/Fan0 and
116 * the property is Present, the leaf Fan0 and the Property is
117 * joined to Fan0_Present as the sensor name.
118 *
119 * @param[in] sensorInfo - Dbus info related to sensor.
120 *
121 * @return On success return the sensor name for the sensor.
122 */
123inline SensorName nameLeafProperty(const Info& sensorInfo)
124{
125 return nameLeaf(sensorInfo) + "_" + nameProperty(sensorInfo);
126}
127
128/** @brief Populate sensor name from the D-Bus object associated with the
Tom Josephb0adbcd2018-01-24 11:51:29 +0530129 * sensor. If the object path is /system/chassis/motherboard/cpu0/core0
130 * then the sensor name is cpu0_core0. The leaf and the parent is put
131 * together to get the sensor name.
132 *
133 * @param[in] sensorInfo - Dbus info related to sensor.
134 *
135 * @return On success return the sensor name for the sensor.
136 */
137SensorName nameParentLeaf(const Info& sensorInfo);
138
Tom Joseph816e92b2017-09-06 19:23:00 +0530139/**
140 * @brief Helper function to map the dbus info to sensor's assertion status
141 * for the get sensor reading command.
142 *
143 * @param[in] sensorInfo - Dbus info related to sensor.
144 * @param[in] path - Dbus object path.
145 * @param[in] interface - Dbus interface.
146 *
147 * @return Response for get sensor reading command.
148 */
149GetSensorResponse mapDbusToAssertion(const Info& sensorInfo,
150 const InstancePath& path,
151 const DbusInterface& interface);
152
Lei YU8c2c0482021-09-16 17:28:28 +0800153#ifndef FEATURE_SENSORS_CACHE
Tom Joseph816e92b2017-09-06 19:23:00 +0530154/**
155 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
156 * reading command response.
157 *
158 * @param[in] sensorInfo - Dbus info related to sensor.
159 *
160 * @return Response for get sensor reading command.
161 */
162GetSensorResponse assertion(const Info& sensorInfo);
163
Tom Josephe4014fc2017-09-06 23:57:36 +0530164/**
165 * @brief Maps the Dbus info to the reading field in the Get sensor reading
166 * command response.
167 *
168 * @param[in] sensorInfo - Dbus info related to sensor.
169 *
170 * @return Response for get sensor reading command.
171 */
172GetSensorResponse eventdata2(const Info& sensorInfo);
173
Tom Joseph295f17e2017-09-07 00:09:46 +0530174/**
175 * @brief readingAssertion is a case where the entire assertion state field
176 * serves as the sensor value.
177 *
178 * @tparam T - type of the dbus property related to sensor.
179 * @param[in] sensorInfo - Dbus info related to sensor.
180 *
181 * @return Response for get sensor reading command.
182 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700183template <typename T>
Tom Joseph295f17e2017-09-07 00:09:46 +0530184GetSensorResponse readingAssertion(const Info& sensorInfo)
185{
186 sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
Patrick Venture0b02be92018-08-31 11:55:55 -0700187 GetSensorResponse response{};
Tom Joseph295f17e2017-09-07 00:09:46 +0530188
Jeremy Kerr3dc35582020-05-17 15:47:07 +0800189 enableScanning(&response);
190
Patrick Venture0b02be92018-08-31 11:55:55 -0700191 auto service = ipmi::getService(bus, sensorInfo.sensorInterface,
Tom Joseph295f17e2017-09-07 00:09:46 +0530192 sensorInfo.sensorPath);
193
194 auto propValue = ipmi::getDbusProperty(
Patrick Venture0b02be92018-08-31 11:55:55 -0700195 bus, service, sensorInfo.sensorPath,
196 sensorInfo.propertyInterfaces.begin()->first,
197 sensorInfo.propertyInterfaces.begin()->second.begin()->first);
Tom Joseph295f17e2017-09-07 00:09:46 +0530198
Sui Chen4cc42552019-09-11 10:28:35 -0700199 setAssertionBytes(static_cast<uint16_t>(std::get<T>(propValue)), &response);
Tom Joseph295f17e2017-09-07 00:09:46 +0530200
201 return response;
202}
203
Tom Josephe05b2922017-09-07 00:43:16 +0530204/** @brief Map the Dbus info to the reading field in the Get sensor reading
205 * command response
206 *
207 * @tparam T - type of the dbus property related to sensor.
208 * @param[in] sensorInfo - Dbus info related to sensor.
209 *
210 * @return Response for get sensor reading command.
211 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700212template <typename T>
Tom Josephe05b2922017-09-07 00:43:16 +0530213GetSensorResponse readingData(const Info& sensorInfo)
214{
215 sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
Tom Josephe05b2922017-09-07 00:43:16 +0530216
Sui Chen4cc42552019-09-11 10:28:35 -0700217 GetSensorResponse response{};
218
219 enableScanning(&response);
Tom Josephe05b2922017-09-07 00:43:16 +0530220
Patrick Venture0b02be92018-08-31 11:55:55 -0700221 auto service = ipmi::getService(bus, sensorInfo.sensorInterface,
Tom Josephe05b2922017-09-07 00:43:16 +0530222 sensorInfo.sensorPath);
223
Brandon Kim9cf85622019-06-19 12:05:08 -0700224#ifdef UPDATE_FUNCTIONAL_ON_FAIL
225 // Check the OperationalStatus interface for functional property
226 if (sensorInfo.propertyInterfaces.begin()->first ==
227 "xyz.openbmc_project.Sensor.Value")
228 {
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
Tom Josephe05b2922017-09-07 00:43:16 +0530250 auto propValue = ipmi::getDbusProperty(
Patrick Venture0b02be92018-08-31 11:55:55 -0700251 bus, service, sensorInfo.sensorPath,
252 sensorInfo.propertyInterfaces.begin()->first,
253 sensorInfo.propertyInterfaces.begin()->second.begin()->first);
Tom Josephe05b2922017-09-07 00:43:16 +0530254
Vernon Maueryf442e112019-04-09 11:44:36 -0700255 double value = std::get<T>(propValue) *
Patrick Venture586d35b2018-09-07 19:56:18 -0700256 std::pow(10, sensorInfo.scale - sensorInfo.exponentR);
Tony Leec5324252019-10-31 17:24:16 +0800257 int32_t rawData =
258 (value - sensorInfo.scaledOffset) / sensorInfo.coefficientM;
Tom Josephe05b2922017-09-07 00:43:16 +0530259
Tony Leec5324252019-10-31 17:24:16 +0800260 constexpr uint8_t sensorUnitsSignedBits = 2 << 6;
261 constexpr uint8_t signedDataFormat = 0x80;
262 // if sensorUnits1 [7:6] = 10b, sensor is signed
263 if ((sensorInfo.sensorUnits1 & sensorUnitsSignedBits) == signedDataFormat)
264 {
265 if (rawData > std::numeric_limits<int8_t>::max() ||
266 rawData < std::numeric_limits<int8_t>::lowest())
267 {
268 log<level::ERR>("Value out of range");
269 throw std::out_of_range("Value out of range");
270 }
271 setReading(static_cast<int8_t>(rawData), &response);
272 }
273 else
274 {
275 if (rawData > std::numeric_limits<uint8_t>::max() ||
276 rawData < std::numeric_limits<uint8_t>::lowest())
277 {
278 log<level::ERR>("Value out of range");
279 throw std::out_of_range("Value out of range");
280 }
281 setReading(static_cast<uint8_t>(rawData), &response);
282 }
Tom Josephe05b2922017-09-07 00:43:16 +0530283
Konstantin Aladyshevf93b29c2021-05-05 14:49:14 +0300284 if (!std::isfinite(value))
285 {
286 response.readingOrStateUnavailable = 1;
287 }
288
Konstantin Aladyshev778f6592021-11-02 11:28:25 +0300289 bool critAlarmHigh;
290 try
291 {
292 critAlarmHigh = std::get<bool>(ipmi::getDbusProperty(
293 bus, service, sensorInfo.sensorPath,
294 "xyz.openbmc_project.Sensor.Threshold.Critical",
295 "CriticalAlarmHigh"));
296 }
297 catch (const std::exception& e)
298 {
299 critAlarmHigh = false;
300 }
301 bool critAlarmLow;
302 try
303 {
304 critAlarmLow = std::get<bool>(ipmi::getDbusProperty(
305 bus, service, sensorInfo.sensorPath,
306 "xyz.openbmc_project.Sensor.Threshold.Critical",
307 "CriticalAlarmLow"));
308 }
309 catch (const std::exception& e)
310 {
311 critAlarmLow = false;
312 }
313 bool warningAlarmHigh;
314 try
315 {
316 warningAlarmHigh = std::get<bool>(ipmi::getDbusProperty(
317 bus, service, sensorInfo.sensorPath,
318 "xyz.openbmc_project.Sensor.Threshold.Warning",
319 "WarningAlarmHigh"));
320 }
321 catch (const std::exception& e)
322 {
323 warningAlarmHigh = false;
324 }
325 bool warningAlarmLow;
326 try
327 {
328 warningAlarmLow = std::get<bool>(ipmi::getDbusProperty(
329 bus, service, sensorInfo.sensorPath,
330 "xyz.openbmc_project.Sensor.Threshold.Warning", "WarningAlarmlow"));
331 }
332 catch (const std::exception& e)
333 {
334 warningAlarmLow = false;
335 }
336 response.thresholdLevelsStates =
337 (static_cast<uint8_t>(critAlarmHigh) << 4) |
338 (static_cast<uint8_t>(warningAlarmHigh) << 3) |
339 (static_cast<uint8_t>(warningAlarmLow) << 2) |
340 (static_cast<uint8_t>(critAlarmLow) << 1);
341
Tom Josephe05b2922017-09-07 00:43:16 +0530342 return response;
343}
344
Lei YU8c2c0482021-09-16 17:28:28 +0800345#else
346
Lei YU8c2c0482021-09-16 17:28:28 +0800347/**
348 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
349 * reading command response.
350 *
351 * @param[in] id - The sensor id
352 * @param[in] sensorInfo - Dbus info related to sensor.
353 * @param[in] msg - Dbus message from match callback.
354 *
355 * @return Response for get sensor reading command.
356 */
357std::optional<GetSensorResponse> assertion(uint8_t id, const Info& sensorInfo,
358 sdbusplus::message::message& msg);
359
360/**
361 * @brief Maps the Dbus info to the reading field in the Get sensor reading
362 * command response.
363 *
364 * @param[in] id - The sensor id
365 * @param[in] sensorInfo - Dbus info related to sensor.
366 * @param[in] msg - Dbus message from match callback.
367 *
368 * @return Response for get sensor reading command.
369 */
370std::optional<GetSensorResponse> eventdata2(uint8_t id, const Info& sensorInfo,
371 sdbusplus::message::message& msg);
372
373/**
374 * @brief readingAssertion is a case where the entire assertion state field
375 * serves as the sensor value.
376 *
377 * @tparam T - type of the dbus property related to sensor.
378 * @param[in] id - The sensor id
379 * @param[in] sensorInfo - Dbus info related to sensor.
380 * @param[in] msg - Dbus message from match callback.
381 *
382 * @return Response for get sensor reading command.
383 */
384template <typename T>
385std::optional<GetSensorResponse>
386 readingAssertion(uint8_t id, const Info& sensorInfo,
387 sdbusplus::message::message& msg)
388{
Lei YU7d720342021-09-18 18:39:09 +0800389 auto type = msg.get_type();
390 if (type == msgTypeSignal)
391 {
392 // This is signal callback
393 std::string interfaceName;
394 msg.read(interfaceName);
395 if (interfaceName != sensorInfo.sensorInterface)
396 {
397 // Not the interface we need
398 return {};
399 }
400 }
401 // Now the message only contains the properties.
402 GetSensorResponse response{};
403 std::map<std::string, ipmi::Value> properties;
404
405 enableScanning(&response);
406
407 msg.read(properties);
408
409 auto iter = properties.find(
410 sensorInfo.propertyInterfaces.begin()->second.begin()->first);
411 if (iter == properties.end())
412 {
413 return {};
414 }
415
416 setAssertionBytes(static_cast<uint16_t>(std::get<T>(iter->second)),
417 &response);
418
419 if (!sensorCacheMap[id].has_value())
420 {
421 sensorCacheMap[id] = SensorData{};
422 }
423 sensorCacheMap[id]->response = response;
424 return response;
Lei YU8c2c0482021-09-16 17:28:28 +0800425}
426
427/** @brief Get sensor reading from the dbus message from match
428 *
429 * @tparam T - type of the dbus property related to sensor.
430 * @param[in] id - The sensor id
431 * @param[in] sensorInfo - Dbus info related to sensor.
432 * @param[in] msg - Dbus message from match callback.
433 *
434 * @return Response for get sensor reading command.
435 */
436template <typename T>
437std::optional<GetSensorResponse> readingData(uint8_t id, const Info& sensorInfo,
438 sdbusplus::message::message& msg)
439{
Lei YU97140502021-09-17 13:49:43 +0800440 std::map<std::string, ipmi::Value> properties;
Lei YUa55e9ea2021-09-18 15:15:17 +0800441 auto type = msg.get_type();
442 if (type == msgTypeSignal)
443 {
444 // This is signal callback
445 std::string interfaceName;
446 msg.read(interfaceName);
Lei YU97140502021-09-17 13:49:43 +0800447
Lei YUa55e9ea2021-09-18 15:15:17 +0800448 if (interfaceName ==
449 "xyz.openbmc_project.State.Decorator.OperationalStatus")
Lei YU97140502021-09-17 13:49:43 +0800450 {
Lei YUa55e9ea2021-09-18 15:15:17 +0800451 msg.read(properties);
452 auto val = properties.find("Functional");
453 if (val != properties.end())
454 {
455 sensorCacheMap[id]->functional = std::get<bool>(val->second);
456 }
457 return {};
Lei YU97140502021-09-17 13:49:43 +0800458 }
Lei YUa55e9ea2021-09-18 15:15:17 +0800459 if (interfaceName == "xyz.openbmc_project.State.Decorator.Availability")
Lei YU97140502021-09-17 13:49:43 +0800460 {
Lei YUa55e9ea2021-09-18 15:15:17 +0800461 msg.read(properties);
462 auto val = properties.find("Available");
463 if (val != properties.end())
464 {
465 sensorCacheMap[id]->available = std::get<bool>(val->second);
466 }
467 return {};
Lei YU97140502021-09-17 13:49:43 +0800468 }
Lei YU97140502021-09-17 13:49:43 +0800469
Lei YUa55e9ea2021-09-18 15:15:17 +0800470 if (interfaceName != sensorInfo.sensorInterface)
471 {
472 // Not the interface we need
473 return {};
474 }
Lei YU97140502021-09-17 13:49:43 +0800475
476#ifdef UPDATE_FUNCTIONAL_ON_FAIL
Lei YUa55e9ea2021-09-18 15:15:17 +0800477 if (sensorCacheMap[id])
Lei YU97140502021-09-17 13:49:43 +0800478 {
Lei YUa55e9ea2021-09-18 15:15:17 +0800479 if (!sensorCacheMap[id]->functional)
480 {
481 throw SensorFunctionalError();
482 }
Lei YU97140502021-09-17 13:49:43 +0800483 }
Lei YU97140502021-09-17 13:49:43 +0800484#endif
Lei YUa55e9ea2021-09-18 15:15:17 +0800485 }
486 // Now the message only contains the properties.
Lei YU97140502021-09-17 13:49:43 +0800487
488 GetSensorResponse response{};
489
490 enableScanning(&response);
491
492 msg.read(properties);
493
494 auto iter = properties.find(
495 sensorInfo.propertyInterfaces.begin()->second.begin()->first);
496 if (iter == properties.end())
497 {
498 return {};
499 }
500
501 double value = std::get<T>(iter->second) *
502 std::pow(10, sensorInfo.scale - sensorInfo.exponentR);
503 int32_t rawData =
504 (value - sensorInfo.scaledOffset) / sensorInfo.coefficientM;
505
506 constexpr uint8_t sensorUnitsSignedBits = 2 << 6;
507 constexpr uint8_t signedDataFormat = 0x80;
508 // if sensorUnits1 [7:6] = 10b, sensor is signed
509 if ((sensorInfo.sensorUnits1 & sensorUnitsSignedBits) == signedDataFormat)
510 {
511 if (rawData > std::numeric_limits<int8_t>::max() ||
512 rawData < std::numeric_limits<int8_t>::lowest())
513 {
514 log<level::ERR>("Value out of range");
515 throw std::out_of_range("Value out of range");
516 }
517 setReading(static_cast<int8_t>(rawData), &response);
518 }
519 else
520 {
521 if (rawData > std::numeric_limits<uint8_t>::max() ||
522 rawData < std::numeric_limits<uint8_t>::lowest())
523 {
524 log<level::ERR>("Value out of range");
525 throw std::out_of_range("Value out of range");
526 }
527 setReading(static_cast<uint8_t>(rawData), &response);
528 }
529
530 if (!std::isfinite(value))
531 {
532 response.readingOrStateUnavailable = 1;
533 }
534
535 if (!sensorCacheMap[id].has_value())
536 {
537 sensorCacheMap[id] = SensorData{};
538 }
539 sensorCacheMap[id]->response = response;
540
541 return response;
Lei YU8c2c0482021-09-16 17:28:28 +0800542}
543
544#endif // FEATURE_SENSORS_CACHE
545
Patrick Venture0b02be92018-08-31 11:55:55 -0700546} // namespace get
Tom Joseph816e92b2017-09-06 19:23:00 +0530547
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500548namespace set
549{
550
551/** @brief Make a DBus message for a Dbus call
552 * @param[in] updateInterface - Interface name
553 * @param[in] sensorPath - Path of the sensor
554 * @param[in] command - command to be executed
555 * @param[in] sensorInterface - DBus interface of sensor
556 * @return a dbus message
557 */
558IpmiUpdateData makeDbusMsg(const std::string& updateInterface,
559 const std::string& sensorPath,
560 const std::string& command,
561 const std::string& sensorInterface);
562
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500563/** @brief Update d-bus based on assertion type sensor data
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500564 * @param[in] cmdData - input sensor data
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500565 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500566 * @return a IPMI error code
567 */
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500568ipmi_ret_t assertion(const SetSensorReadingReq& cmdData,
569 const Info& sensorInfo);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500570
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500571/** @brief Update d-bus based on a reading assertion
572 * @tparam T - type of d-bus property mapping this sensor
573 * @param[in] cmdData - input sensor data
574 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500575 * @return a IPMI error code
576 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700577template <typename T>
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500578ipmi_ret_t readingAssertion(const SetSensorReadingReq& cmdData,
579 const Info& sensorInfo)
580{
Patrick Venture0b02be92018-08-31 11:55:55 -0700581 auto msg =
582 makeDbusMsg("org.freedesktop.DBus.Properties", sensorInfo.sensorPath,
583 "Set", sensorInfo.sensorInterface);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500584
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500585 const auto& interface = sensorInfo.propertyInterfaces.begin();
586 msg.append(interface->first);
587 for (const auto& property : interface->second)
588 {
589 msg.append(property.first);
Andrew Geissler6467ed22020-05-16 16:03:53 -0500590 std::variant<T> value = static_cast<T>((cmdData.assertOffset8_14 << 8) |
591 cmdData.assertOffset0_7);
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500592 msg.append(value);
593 }
594 return updateToDbus(msg);
595}
596
Emily Shaffercc941e12017-06-14 13:06:26 -0700597/** @brief Update d-bus based on a discrete reading
598 * @param[in] cmdData - input sensor data
599 * @param[in] sensorInfo - sensor d-bus info
600 * @return an IPMI error code
601 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700602template <typename T>
Emily Shaffercc941e12017-06-14 13:06:26 -0700603ipmi_ret_t readingData(const SetSensorReadingReq& cmdData,
604 const Info& sensorInfo)
605{
Patrick Venture0b02be92018-08-31 11:55:55 -0700606 T raw_value =
607 (sensorInfo.coefficientM * cmdData.reading) + sensorInfo.scaledOffset;
Tom Joseph22102152018-03-02 18:46:39 +0530608
Patrick Venture586d35b2018-09-07 19:56:18 -0700609 raw_value *= std::pow(10, sensorInfo.exponentR - sensorInfo.scale);
Tom Joseph22102152018-03-02 18:46:39 +0530610
Patrick Venture0b02be92018-08-31 11:55:55 -0700611 auto msg =
612 makeDbusMsg("org.freedesktop.DBus.Properties", sensorInfo.sensorPath,
613 "Set", sensorInfo.sensorInterface);
Emily Shaffercc941e12017-06-14 13:06:26 -0700614
615 const auto& interface = sensorInfo.propertyInterfaces.begin();
616 msg.append(interface->first);
617
Emily Shaffercc941e12017-06-14 13:06:26 -0700618 for (const auto& property : interface->second)
619 {
620 msg.append(property.first);
Vernon Mauery16b86932019-05-01 08:36:11 -0700621 std::variant<T> value = raw_value;
Emily Shaffercc941e12017-06-14 13:06:26 -0700622 msg.append(value);
623 }
624 return updateToDbus(msg);
625}
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500626
627/** @brief Update d-bus based on eventdata type sensor data
628 * @param[in] cmdData - input sensor data
629 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500630 * @return a IPMI error code
631 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700632ipmi_ret_t eventdata(const SetSensorReadingReq& cmdData, const Info& sensorInfo,
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500633 uint8_t data);
634
635/** @brief Update d-bus based on eventdata1 type sensor data
636 * @param[in] cmdData - input sensor data
637 * @param[in] sensorInfo - sensor d-bus info
638 * @return a IPMI error code
639 */
640inline ipmi_ret_t eventdata1(const SetSensorReadingReq& cmdData,
641 const Info& sensorInfo)
642{
643 return eventdata(cmdData, sensorInfo, cmdData.eventData1);
644}
645
646/** @brief Update d-bus based on eventdata2 type sensor data
647 * @param[in] cmdData - input sensor data
648 * @param[in] sensorInfo - sensor d-bus info
649 * @return a IPMI error code
650 */
651inline ipmi_ret_t eventdata2(const SetSensorReadingReq& cmdData,
652 const Info& sensorInfo)
653{
654 return eventdata(cmdData, sensorInfo, cmdData.eventData2);
655}
656
657/** @brief Update d-bus based on eventdata3 type sensor data
658 * @param[in] cmdData - input sensor data
659 * @param[in] sensorInfo - sensor d-bus info
660 * @return a IPMI error code
661 */
662inline ipmi_ret_t eventdata3(const SetSensorReadingReq& cmdData,
663 const Info& sensorInfo)
664{
665 return eventdata(cmdData, sensorInfo, cmdData.eventData3);
666}
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500667
Patrick Venture0b02be92018-08-31 11:55:55 -0700668} // namespace set
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500669
670namespace notify
671{
672
673/** @brief Make a DBus message for a Dbus call
674 * @param[in] updateInterface - Interface name
675 * @param[in] sensorPath - Path of the sensor
676 * @param[in] command - command to be executed
677 * @param[in] sensorInterface - DBus interface of sensor
678 * @return a dbus message
679 */
680IpmiUpdateData makeDbusMsg(const std::string& updateInterface,
681 const std::string& sensorPath,
682 const std::string& command,
683 const std::string& sensorInterface);
684
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500685/** @brief Update d-bus based on assertion type sensor data
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500686 * @param[in] interfaceMap - sensor interface
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500687 * @param[in] cmdData - input sensor data
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500688 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500689 * @return a IPMI error code
690 */
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500691ipmi_ret_t assertion(const SetSensorReadingReq& cmdData,
692 const Info& sensorInfo);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500693
Patrick Venture0b02be92018-08-31 11:55:55 -0700694} // namespace notify
Tom Joseph816e92b2017-09-06 19:23:00 +0530695
696namespace inventory
697{
698
699namespace get
700{
701
Lei YUff8c9b42021-10-15 14:20:57 +0800702#ifndef FEATURE_SENSORS_CACHE
703
Tom Joseph816e92b2017-09-06 19:23:00 +0530704/**
705 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
706 * reading command response.
707 *
708 * @param[in] sensorInfo - Dbus info related to sensor.
709 *
710 * @return Response for get sensor reading command.
711 */
712GetSensorResponse assertion(const Info& sensorInfo);
713
Lei YUff8c9b42021-10-15 14:20:57 +0800714#else
715
716/**
717 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
718 * reading command response.
719 *
720 * @param[in] id - The sensor id
721 * @param[in] sensorInfo - Dbus info related to sensor.
722 * @param[in] msg - Dbus message from match callback.
723 *
724 * @return Response for get sensor reading command.
725 */
726std::optional<GetSensorResponse> assertion(uint8_t id, const Info& sensorInfo,
727 sdbusplus::message::message& msg);
728
729#endif
730
Tom Joseph816e92b2017-09-06 19:23:00 +0530731} // namespace get
732
733} // namespace inventory
Patrick Venture0b02be92018-08-31 11:55:55 -0700734} // namespace sensor
735} // namespace ipmi