blob: 7ecfee8f005f95e190a4115c2e4cf36808403003 [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{
389 // TODO
390 return {};
391}
392
393/** @brief Get sensor reading from the dbus message from match
394 *
395 * @tparam T - type of the dbus property related to sensor.
396 * @param[in] id - The sensor id
397 * @param[in] sensorInfo - Dbus info related to sensor.
398 * @param[in] msg - Dbus message from match callback.
399 *
400 * @return Response for get sensor reading command.
401 */
402template <typename T>
403std::optional<GetSensorResponse> readingData(uint8_t id, const Info& sensorInfo,
404 sdbusplus::message::message& msg)
405{
Lei YU97140502021-09-17 13:49:43 +0800406 std::map<std::string, ipmi::Value> properties;
Lei YUa55e9ea2021-09-18 15:15:17 +0800407 auto type = msg.get_type();
408 if (type == msgTypeSignal)
409 {
410 // This is signal callback
411 std::string interfaceName;
412 msg.read(interfaceName);
Lei YU97140502021-09-17 13:49:43 +0800413
Lei YUa55e9ea2021-09-18 15:15:17 +0800414 if (interfaceName ==
415 "xyz.openbmc_project.State.Decorator.OperationalStatus")
Lei YU97140502021-09-17 13:49:43 +0800416 {
Lei YUa55e9ea2021-09-18 15:15:17 +0800417 msg.read(properties);
418 auto val = properties.find("Functional");
419 if (val != properties.end())
420 {
421 sensorCacheMap[id]->functional = std::get<bool>(val->second);
422 }
423 return {};
Lei YU97140502021-09-17 13:49:43 +0800424 }
Lei YUa55e9ea2021-09-18 15:15:17 +0800425 if (interfaceName == "xyz.openbmc_project.State.Decorator.Availability")
Lei YU97140502021-09-17 13:49:43 +0800426 {
Lei YUa55e9ea2021-09-18 15:15:17 +0800427 msg.read(properties);
428 auto val = properties.find("Available");
429 if (val != properties.end())
430 {
431 sensorCacheMap[id]->available = std::get<bool>(val->second);
432 }
433 return {};
Lei YU97140502021-09-17 13:49:43 +0800434 }
Lei YU97140502021-09-17 13:49:43 +0800435
Lei YUa55e9ea2021-09-18 15:15:17 +0800436 if (interfaceName != sensorInfo.sensorInterface)
437 {
438 // Not the interface we need
439 return {};
440 }
Lei YU97140502021-09-17 13:49:43 +0800441
442#ifdef UPDATE_FUNCTIONAL_ON_FAIL
Lei YUa55e9ea2021-09-18 15:15:17 +0800443 if (sensorCacheMap[id])
Lei YU97140502021-09-17 13:49:43 +0800444 {
Lei YUa55e9ea2021-09-18 15:15:17 +0800445 if (!sensorCacheMap[id]->functional)
446 {
447 throw SensorFunctionalError();
448 }
Lei YU97140502021-09-17 13:49:43 +0800449 }
Lei YU97140502021-09-17 13:49:43 +0800450#endif
Lei YUa55e9ea2021-09-18 15:15:17 +0800451 }
452 // Now the message only contains the properties.
Lei YU97140502021-09-17 13:49:43 +0800453
454 GetSensorResponse response{};
455
456 enableScanning(&response);
457
458 msg.read(properties);
459
460 auto iter = properties.find(
461 sensorInfo.propertyInterfaces.begin()->second.begin()->first);
462 if (iter == properties.end())
463 {
464 return {};
465 }
466
467 double value = std::get<T>(iter->second) *
468 std::pow(10, sensorInfo.scale - sensorInfo.exponentR);
469 int32_t rawData =
470 (value - sensorInfo.scaledOffset) / sensorInfo.coefficientM;
471
472 constexpr uint8_t sensorUnitsSignedBits = 2 << 6;
473 constexpr uint8_t signedDataFormat = 0x80;
474 // if sensorUnits1 [7:6] = 10b, sensor is signed
475 if ((sensorInfo.sensorUnits1 & sensorUnitsSignedBits) == signedDataFormat)
476 {
477 if (rawData > std::numeric_limits<int8_t>::max() ||
478 rawData < std::numeric_limits<int8_t>::lowest())
479 {
480 log<level::ERR>("Value out of range");
481 throw std::out_of_range("Value out of range");
482 }
483 setReading(static_cast<int8_t>(rawData), &response);
484 }
485 else
486 {
487 if (rawData > std::numeric_limits<uint8_t>::max() ||
488 rawData < std::numeric_limits<uint8_t>::lowest())
489 {
490 log<level::ERR>("Value out of range");
491 throw std::out_of_range("Value out of range");
492 }
493 setReading(static_cast<uint8_t>(rawData), &response);
494 }
495
496 if (!std::isfinite(value))
497 {
498 response.readingOrStateUnavailable = 1;
499 }
500
501 if (!sensorCacheMap[id].has_value())
502 {
503 sensorCacheMap[id] = SensorData{};
504 }
505 sensorCacheMap[id]->response = response;
506
507 return response;
Lei YU8c2c0482021-09-16 17:28:28 +0800508}
509
510#endif // FEATURE_SENSORS_CACHE
511
Patrick Venture0b02be92018-08-31 11:55:55 -0700512} // namespace get
Tom Joseph816e92b2017-09-06 19:23:00 +0530513
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500514namespace set
515{
516
517/** @brief Make a DBus message for a Dbus call
518 * @param[in] updateInterface - Interface name
519 * @param[in] sensorPath - Path of the sensor
520 * @param[in] command - command to be executed
521 * @param[in] sensorInterface - DBus interface of sensor
522 * @return a dbus message
523 */
524IpmiUpdateData makeDbusMsg(const std::string& updateInterface,
525 const std::string& sensorPath,
526 const std::string& command,
527 const std::string& sensorInterface);
528
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500529/** @brief Update d-bus based on assertion type sensor data
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500530 * @param[in] cmdData - input sensor data
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500531 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500532 * @return a IPMI error code
533 */
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500534ipmi_ret_t assertion(const SetSensorReadingReq& cmdData,
535 const Info& sensorInfo);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500536
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500537/** @brief Update d-bus based on a reading assertion
538 * @tparam T - type of d-bus property mapping this sensor
539 * @param[in] cmdData - input sensor data
540 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500541 * @return a IPMI error code
542 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700543template <typename T>
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500544ipmi_ret_t readingAssertion(const SetSensorReadingReq& cmdData,
545 const Info& sensorInfo)
546{
Patrick Venture0b02be92018-08-31 11:55:55 -0700547 auto msg =
548 makeDbusMsg("org.freedesktop.DBus.Properties", sensorInfo.sensorPath,
549 "Set", sensorInfo.sensorInterface);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500550
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500551 const auto& interface = sensorInfo.propertyInterfaces.begin();
552 msg.append(interface->first);
553 for (const auto& property : interface->second)
554 {
555 msg.append(property.first);
Andrew Geissler6467ed22020-05-16 16:03:53 -0500556 std::variant<T> value = static_cast<T>((cmdData.assertOffset8_14 << 8) |
557 cmdData.assertOffset0_7);
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500558 msg.append(value);
559 }
560 return updateToDbus(msg);
561}
562
Emily Shaffercc941e12017-06-14 13:06:26 -0700563/** @brief Update d-bus based on a discrete reading
564 * @param[in] cmdData - input sensor data
565 * @param[in] sensorInfo - sensor d-bus info
566 * @return an IPMI error code
567 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700568template <typename T>
Emily Shaffercc941e12017-06-14 13:06:26 -0700569ipmi_ret_t readingData(const SetSensorReadingReq& cmdData,
570 const Info& sensorInfo)
571{
Patrick Venture0b02be92018-08-31 11:55:55 -0700572 T raw_value =
573 (sensorInfo.coefficientM * cmdData.reading) + sensorInfo.scaledOffset;
Tom Joseph22102152018-03-02 18:46:39 +0530574
Patrick Venture586d35b2018-09-07 19:56:18 -0700575 raw_value *= std::pow(10, sensorInfo.exponentR - sensorInfo.scale);
Tom Joseph22102152018-03-02 18:46:39 +0530576
Patrick Venture0b02be92018-08-31 11:55:55 -0700577 auto msg =
578 makeDbusMsg("org.freedesktop.DBus.Properties", sensorInfo.sensorPath,
579 "Set", sensorInfo.sensorInterface);
Emily Shaffercc941e12017-06-14 13:06:26 -0700580
581 const auto& interface = sensorInfo.propertyInterfaces.begin();
582 msg.append(interface->first);
583
Emily Shaffercc941e12017-06-14 13:06:26 -0700584 for (const auto& property : interface->second)
585 {
586 msg.append(property.first);
Vernon Mauery16b86932019-05-01 08:36:11 -0700587 std::variant<T> value = raw_value;
Emily Shaffercc941e12017-06-14 13:06:26 -0700588 msg.append(value);
589 }
590 return updateToDbus(msg);
591}
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500592
593/** @brief Update d-bus based on eventdata type sensor data
594 * @param[in] cmdData - input sensor data
595 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500596 * @return a IPMI error code
597 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700598ipmi_ret_t eventdata(const SetSensorReadingReq& cmdData, const Info& sensorInfo,
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500599 uint8_t data);
600
601/** @brief Update d-bus based on eventdata1 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 */
606inline ipmi_ret_t eventdata1(const SetSensorReadingReq& cmdData,
607 const Info& sensorInfo)
608{
609 return eventdata(cmdData, sensorInfo, cmdData.eventData1);
610}
611
612/** @brief Update d-bus based on eventdata2 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 */
617inline ipmi_ret_t eventdata2(const SetSensorReadingReq& cmdData,
618 const Info& sensorInfo)
619{
620 return eventdata(cmdData, sensorInfo, cmdData.eventData2);
621}
622
623/** @brief Update d-bus based on eventdata3 type sensor data
624 * @param[in] cmdData - input sensor data
625 * @param[in] sensorInfo - sensor d-bus info
626 * @return a IPMI error code
627 */
628inline ipmi_ret_t eventdata3(const SetSensorReadingReq& cmdData,
629 const Info& sensorInfo)
630{
631 return eventdata(cmdData, sensorInfo, cmdData.eventData3);
632}
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500633
Patrick Venture0b02be92018-08-31 11:55:55 -0700634} // namespace set
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500635
636namespace notify
637{
638
639/** @brief Make a DBus message for a Dbus call
640 * @param[in] updateInterface - Interface name
641 * @param[in] sensorPath - Path of the sensor
642 * @param[in] command - command to be executed
643 * @param[in] sensorInterface - DBus interface of sensor
644 * @return a dbus message
645 */
646IpmiUpdateData makeDbusMsg(const std::string& updateInterface,
647 const std::string& sensorPath,
648 const std::string& command,
649 const std::string& sensorInterface);
650
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500651/** @brief Update d-bus based on assertion type sensor data
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500652 * @param[in] interfaceMap - sensor interface
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500653 * @param[in] cmdData - input sensor data
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500654 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500655 * @return a IPMI error code
656 */
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500657ipmi_ret_t assertion(const SetSensorReadingReq& cmdData,
658 const Info& sensorInfo);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500659
Patrick Venture0b02be92018-08-31 11:55:55 -0700660} // namespace notify
Tom Joseph816e92b2017-09-06 19:23:00 +0530661
662namespace inventory
663{
664
665namespace get
666{
667
668/**
669 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
670 * reading command response.
671 *
672 * @param[in] sensorInfo - Dbus info related to sensor.
673 *
674 * @return Response for get sensor reading command.
675 */
676GetSensorResponse assertion(const Info& sensorInfo);
677
678} // namespace get
679
680} // namespace inventory
Patrick Venture0b02be92018-08-31 11:55:55 -0700681} // namespace sensor
682} // namespace ipmi