blob: 1cb2b409c3261c2f84d02da20ece38b6d6eebe86 [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>;
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -050033using Service = std::string;
34using Path = std::string;
35using Interface = std::string;
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -050036using ServicePath = std::pair<Path, Service>;
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -050037using Interfaces = std::vector<Interface>;
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -050038using MapperResponseType = std::map<Path, std::map<Service, Interfaces>>;
Lei YU8e8152c2021-12-06 20:11:08 +080039using PropertyMap = ipmi::PropertyMap;
40
Tony Leec5324252019-10-31 17:24:16 +080041using namespace phosphor::logging;
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -050042
43/** @brief get the D-Bus service and service path
44 * @param[in] bus - The Dbus bus object
45 * @param[in] interface - interface to the service
46 * @param[in] path - interested path in the list of objects
47 * @return pair of service path and service
48 */
49ServicePath getServiceAndPath(sdbusplus::bus::bus& bus,
50 const std::string& interface,
51 const std::string& path = std::string());
52
53/** @brief Make assertion set from input data
54 * @param[in] cmdData - Input sensor data
55 * @return pair of assertion and deassertion set
56 */
57AssertionSet getAssertionSet(const SetSensorReadingReq& cmdData);
58
59/** @brief send the message to DBus
60 * @param[in] msg - message to send
61 * @return failure status in IPMI error code
62 */
Dhruvaraj Subhashchandran2a444d02017-08-07 01:45:14 -050063ipmi_ret_t updateToDbus(IpmiUpdateData& msg);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -050064
Tom Joseph816e92b2017-09-06 19:23:00 +053065namespace get
66{
67
Tom Josephb0adbcd2018-01-24 11:51:29 +053068/** @brief Populate sensor name from the D-Bus property associated with the
69 * sensor. In the example entry from the yaml, the name of the D-bus
70 * property "AttemptsLeft" is the sensor name.
71 *
72 * 0x07:
73 * sensorType: 195
74 * path: /xyz/openbmc_project/state/host0
75 * sensorReadingType: 0x6F
76 * serviceInterface: org.freedesktop.DBus.Properties
77 * readingType: readingAssertion
78 * sensorNamePattern: nameProperty
79 * interfaces:
80 * xyz.openbmc_project.Control.Boot.RebootAttempts:
81 * AttemptsLeft:
82 * Offsets:
83 * 0xFF:
84 * type: uint32_t
85 *
86 *
87 * @param[in] sensorInfo - Dbus info related to sensor.
88 *
89 * @return On success return the sensor name for the sensor.
90 */
91inline SensorName nameProperty(const Info& sensorInfo)
92{
93 return sensorInfo.propertyInterfaces.begin()->second.begin()->first;
94}
95
96/** @brief Populate sensor name from the D-Bus object associated with the
97 * sensor. If the object path is /system/chassis/motherboard/dimm0 then
98 * the leaf dimm0 is considered as the sensor name.
99 *
100 * @param[in] sensorInfo - Dbus info related to sensor.
101 *
102 * @return On success return the sensor name for the sensor.
103 */
104inline SensorName nameLeaf(const Info& sensorInfo)
105{
106 return sensorInfo.sensorPath.substr(
Patrick Venture0b02be92018-08-31 11:55:55 -0700107 sensorInfo.sensorPath.find_last_of('/') + 1,
108 sensorInfo.sensorPath.length());
Tom Josephb0adbcd2018-01-24 11:51:29 +0530109}
110
111/** @brief Populate sensor name from the D-Bus object associated with the
Lotus Xu2101a442020-12-24 16:01:56 +0800112 * sensor and the property.
113 * If the object path is /xyz/openbmc_project/inventory/Fan0 and
114 * the property is Present, the leaf Fan0 and the Property is
115 * joined to Fan0_Present as the sensor name.
116 *
117 * @param[in] sensorInfo - Dbus info related to sensor.
118 *
119 * @return On success return the sensor name for the sensor.
120 */
121inline SensorName nameLeafProperty(const Info& sensorInfo)
122{
123 return nameLeaf(sensorInfo) + "_" + nameProperty(sensorInfo);
124}
125
126/** @brief Populate sensor name from the D-Bus object associated with the
Tom Josephb0adbcd2018-01-24 11:51:29 +0530127 * sensor. If the object path is /system/chassis/motherboard/cpu0/core0
128 * then the sensor name is cpu0_core0. The leaf and the parent is put
129 * together to get the sensor name.
130 *
131 * @param[in] sensorInfo - Dbus info related to sensor.
132 *
133 * @return On success return the sensor name for the sensor.
134 */
135SensorName nameParentLeaf(const Info& sensorInfo);
136
Tom Joseph816e92b2017-09-06 19:23:00 +0530137/**
138 * @brief Helper function to map the dbus info to sensor's assertion status
139 * for the get sensor reading command.
140 *
141 * @param[in] sensorInfo - Dbus info related to sensor.
142 * @param[in] path - Dbus object path.
143 * @param[in] interface - Dbus interface.
144 *
145 * @return Response for get sensor reading command.
146 */
147GetSensorResponse mapDbusToAssertion(const Info& sensorInfo,
148 const InstancePath& path,
149 const DbusInterface& interface);
150
Lei YU8c2c0482021-09-16 17:28:28 +0800151#ifndef FEATURE_SENSORS_CACHE
Tom Joseph816e92b2017-09-06 19:23:00 +0530152/**
153 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
154 * reading command response.
155 *
156 * @param[in] sensorInfo - Dbus info related to sensor.
157 *
158 * @return Response for get sensor reading command.
159 */
160GetSensorResponse assertion(const Info& sensorInfo);
161
Tom Josephe4014fc2017-09-06 23:57:36 +0530162/**
163 * @brief Maps the Dbus info to the reading field in the Get sensor reading
164 * command response.
165 *
166 * @param[in] sensorInfo - Dbus info related to sensor.
167 *
168 * @return Response for get sensor reading command.
169 */
170GetSensorResponse eventdata2(const Info& sensorInfo);
171
Tom Joseph295f17e2017-09-07 00:09:46 +0530172/**
173 * @brief readingAssertion is a case where the entire assertion state field
174 * serves as the sensor value.
175 *
176 * @tparam T - type of the dbus property related to sensor.
177 * @param[in] sensorInfo - Dbus info related to sensor.
178 *
179 * @return Response for get sensor reading command.
180 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700181template <typename T>
Tom Joseph295f17e2017-09-07 00:09:46 +0530182GetSensorResponse readingAssertion(const Info& sensorInfo)
183{
184 sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
Patrick Venture0b02be92018-08-31 11:55:55 -0700185 GetSensorResponse response{};
Tom Joseph295f17e2017-09-07 00:09:46 +0530186
Jeremy Kerr3dc35582020-05-17 15:47:07 +0800187 enableScanning(&response);
188
Patrick Venture0b02be92018-08-31 11:55:55 -0700189 auto service = ipmi::getService(bus, sensorInfo.sensorInterface,
Tom Joseph295f17e2017-09-07 00:09:46 +0530190 sensorInfo.sensorPath);
191
192 auto propValue = ipmi::getDbusProperty(
Patrick Venture0b02be92018-08-31 11:55:55 -0700193 bus, service, sensorInfo.sensorPath,
194 sensorInfo.propertyInterfaces.begin()->first,
195 sensorInfo.propertyInterfaces.begin()->second.begin()->first);
Tom Joseph295f17e2017-09-07 00:09:46 +0530196
Sui Chen4cc42552019-09-11 10:28:35 -0700197 setAssertionBytes(static_cast<uint16_t>(std::get<T>(propValue)), &response);
Tom Joseph295f17e2017-09-07 00:09:46 +0530198
199 return response;
200}
201
Tom Josephe05b2922017-09-07 00:43:16 +0530202/** @brief Map the Dbus info to the reading field in the Get sensor reading
203 * command response
204 *
205 * @tparam T - type of the dbus property related to sensor.
206 * @param[in] sensorInfo - Dbus info related to sensor.
207 *
208 * @return Response for get sensor reading command.
209 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700210template <typename T>
Tom Josephe05b2922017-09-07 00:43:16 +0530211GetSensorResponse readingData(const Info& sensorInfo)
212{
213 sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
Tom Josephe05b2922017-09-07 00:43:16 +0530214
Sui Chen4cc42552019-09-11 10:28:35 -0700215 GetSensorResponse response{};
216
217 enableScanning(&response);
Tom Josephe05b2922017-09-07 00:43:16 +0530218
Patrick Venture0b02be92018-08-31 11:55:55 -0700219 auto service = ipmi::getService(bus, sensorInfo.sensorInterface,
Tom Josephe05b2922017-09-07 00:43:16 +0530220 sensorInfo.sensorPath);
221
Brandon Kim9cf85622019-06-19 12:05:08 -0700222#ifdef UPDATE_FUNCTIONAL_ON_FAIL
223 // Check the OperationalStatus interface for functional property
224 if (sensorInfo.propertyInterfaces.begin()->first ==
225 "xyz.openbmc_project.Sensor.Value")
226 {
227 bool functional = true;
228 try
229 {
230 auto funcValue = ipmi::getDbusProperty(
231 bus, service, sensorInfo.sensorPath,
232 "xyz.openbmc_project.State.Decorator.OperationalStatus",
233 "Functional");
234 functional = std::get<bool>(funcValue);
235 }
236 catch (...)
237 {
238 // No-op if Functional property could not be found since this
239 // check is only valid for Sensor.Value read for hwmonio
240 }
241 if (!functional)
242 {
243 throw SensorFunctionalError();
244 }
245 }
246#endif
247
Tom Josephe05b2922017-09-07 00:43:16 +0530248 auto propValue = ipmi::getDbusProperty(
Patrick Venture0b02be92018-08-31 11:55:55 -0700249 bus, service, sensorInfo.sensorPath,
250 sensorInfo.propertyInterfaces.begin()->first,
251 sensorInfo.propertyInterfaces.begin()->second.begin()->first);
Tom Josephe05b2922017-09-07 00:43:16 +0530252
Vernon Maueryf442e112019-04-09 11:44:36 -0700253 double value = std::get<T>(propValue) *
Patrick Venture586d35b2018-09-07 19:56:18 -0700254 std::pow(10, sensorInfo.scale - sensorInfo.exponentR);
Tony Leec5324252019-10-31 17:24:16 +0800255 int32_t rawData =
256 (value - sensorInfo.scaledOffset) / sensorInfo.coefficientM;
Tom Josephe05b2922017-09-07 00:43:16 +0530257
Tony Leec5324252019-10-31 17:24:16 +0800258 constexpr uint8_t sensorUnitsSignedBits = 2 << 6;
259 constexpr uint8_t signedDataFormat = 0x80;
260 // if sensorUnits1 [7:6] = 10b, sensor is signed
261 if ((sensorInfo.sensorUnits1 & sensorUnitsSignedBits) == signedDataFormat)
262 {
263 if (rawData > std::numeric_limits<int8_t>::max() ||
264 rawData < std::numeric_limits<int8_t>::lowest())
265 {
266 log<level::ERR>("Value out of range");
267 throw std::out_of_range("Value out of range");
268 }
269 setReading(static_cast<int8_t>(rawData), &response);
270 }
271 else
272 {
273 if (rawData > std::numeric_limits<uint8_t>::max() ||
274 rawData < std::numeric_limits<uint8_t>::lowest())
275 {
276 log<level::ERR>("Value out of range");
277 throw std::out_of_range("Value out of range");
278 }
279 setReading(static_cast<uint8_t>(rawData), &response);
280 }
Tom Josephe05b2922017-09-07 00:43:16 +0530281
Konstantin Aladyshevf93b29c2021-05-05 14:49:14 +0300282 if (!std::isfinite(value))
283 {
284 response.readingOrStateUnavailable = 1;
285 }
286
Konstantin Aladyshev778f6592021-11-02 11:28:25 +0300287 bool critAlarmHigh;
288 try
289 {
290 critAlarmHigh = std::get<bool>(ipmi::getDbusProperty(
291 bus, service, sensorInfo.sensorPath,
292 "xyz.openbmc_project.Sensor.Threshold.Critical",
293 "CriticalAlarmHigh"));
294 }
295 catch (const std::exception& e)
296 {
297 critAlarmHigh = false;
298 }
299 bool critAlarmLow;
300 try
301 {
302 critAlarmLow = std::get<bool>(ipmi::getDbusProperty(
303 bus, service, sensorInfo.sensorPath,
304 "xyz.openbmc_project.Sensor.Threshold.Critical",
305 "CriticalAlarmLow"));
306 }
307 catch (const std::exception& e)
308 {
309 critAlarmLow = false;
310 }
311 bool warningAlarmHigh;
312 try
313 {
314 warningAlarmHigh = std::get<bool>(ipmi::getDbusProperty(
315 bus, service, sensorInfo.sensorPath,
316 "xyz.openbmc_project.Sensor.Threshold.Warning",
317 "WarningAlarmHigh"));
318 }
319 catch (const std::exception& e)
320 {
321 warningAlarmHigh = false;
322 }
323 bool warningAlarmLow;
324 try
325 {
326 warningAlarmLow = std::get<bool>(ipmi::getDbusProperty(
327 bus, service, sensorInfo.sensorPath,
328 "xyz.openbmc_project.Sensor.Threshold.Warning", "WarningAlarmlow"));
329 }
330 catch (const std::exception& e)
331 {
332 warningAlarmLow = false;
333 }
334 response.thresholdLevelsStates =
335 (static_cast<uint8_t>(critAlarmHigh) << 4) |
336 (static_cast<uint8_t>(warningAlarmHigh) << 3) |
337 (static_cast<uint8_t>(warningAlarmLow) << 2) |
338 (static_cast<uint8_t>(critAlarmLow) << 1);
339
Tom Josephe05b2922017-09-07 00:43:16 +0530340 return response;
341}
342
Lei YU8c2c0482021-09-16 17:28:28 +0800343#else
344
Lei YU8c2c0482021-09-16 17:28:28 +0800345/**
346 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
347 * reading command response.
348 *
349 * @param[in] id - The sensor id
350 * @param[in] sensorInfo - Dbus info related to sensor.
351 * @param[in] msg - Dbus message from match callback.
352 *
353 * @return Response for get sensor reading command.
354 */
355std::optional<GetSensorResponse> assertion(uint8_t id, const Info& sensorInfo,
Lei YU8e8152c2021-12-06 20:11:08 +0800356 const PropertyMap& properties);
Lei YU8c2c0482021-09-16 17:28:28 +0800357
358/**
359 * @brief Maps the Dbus info to the reading field in the Get sensor reading
360 * command response.
361 *
362 * @param[in] id - The sensor id
363 * @param[in] sensorInfo - Dbus info related to sensor.
364 * @param[in] msg - Dbus message from match callback.
365 *
366 * @return Response for get sensor reading command.
367 */
368std::optional<GetSensorResponse> eventdata2(uint8_t id, const Info& sensorInfo,
Lei YU8e8152c2021-12-06 20:11:08 +0800369 const PropertyMap& properties);
Lei YU8c2c0482021-09-16 17:28:28 +0800370
371/**
372 * @brief readingAssertion is a case where the entire assertion state field
373 * serves as the sensor value.
374 *
375 * @tparam T - type of the dbus property related to sensor.
376 * @param[in] id - The sensor id
377 * @param[in] sensorInfo - Dbus info related to sensor.
378 * @param[in] msg - Dbus message from match callback.
379 *
380 * @return Response for get sensor reading command.
381 */
382template <typename T>
Lei YU8e8152c2021-12-06 20:11:08 +0800383std::optional<GetSensorResponse> readingAssertion(uint8_t id,
384 const Info& sensorInfo,
385 const PropertyMap& properties)
Lei YU8c2c0482021-09-16 17:28:28 +0800386{
Lei YU7d720342021-09-18 18:39:09 +0800387 GetSensorResponse response{};
Lei YU7d720342021-09-18 18:39:09 +0800388 enableScanning(&response);
389
Lei YU7d720342021-09-18 18:39:09 +0800390 auto iter = properties.find(
391 sensorInfo.propertyInterfaces.begin()->second.begin()->first);
392 if (iter == properties.end())
393 {
394 return {};
395 }
396
397 setAssertionBytes(static_cast<uint16_t>(std::get<T>(iter->second)),
398 &response);
399
400 if (!sensorCacheMap[id].has_value())
401 {
402 sensorCacheMap[id] = SensorData{};
403 }
404 sensorCacheMap[id]->response = response;
405 return response;
Lei YU8c2c0482021-09-16 17:28:28 +0800406}
407
408/** @brief Get sensor reading from the dbus message from match
409 *
410 * @tparam T - type of the dbus property related to sensor.
411 * @param[in] id - The sensor id
412 * @param[in] sensorInfo - Dbus info related to sensor.
413 * @param[in] msg - Dbus message from match callback.
414 *
415 * @return Response for get sensor reading command.
416 */
417template <typename T>
418std::optional<GetSensorResponse> readingData(uint8_t id, const Info& sensorInfo,
Lei YU8e8152c2021-12-06 20:11:08 +0800419 const PropertyMap& properties)
Lei YU8c2c0482021-09-16 17:28:28 +0800420{
Lei YU8e8152c2021-12-06 20:11:08 +0800421 auto iter = properties.find("Functional");
422 if (iter != properties.end())
Lei YUa55e9ea2021-09-18 15:15:17 +0800423 {
Lei YU8e8152c2021-12-06 20:11:08 +0800424 sensorCacheMap[id]->functional = std::get<bool>(iter->second);
Lei YUa55e9ea2021-09-18 15:15:17 +0800425 }
Lei YU8e8152c2021-12-06 20:11:08 +0800426 iter = properties.find("Available");
427 if (iter != properties.end())
428 {
429 sensorCacheMap[id]->available = std::get<bool>(iter->second);
430 }
431#ifdef UPDATE_FUNCTIONAL_ON_FAIL
432 if (sensorCacheMap[id])
433 {
434 if (!sensorCacheMap[id]->functional)
435 {
436 throw SensorFunctionalError();
437 }
438 }
439#endif
Lei YU97140502021-09-17 13:49:43 +0800440
441 GetSensorResponse response{};
442
443 enableScanning(&response);
444
Lei YU8e8152c2021-12-06 20:11:08 +0800445 iter = properties.find(
Lei YU97140502021-09-17 13:49:43 +0800446 sensorInfo.propertyInterfaces.begin()->second.begin()->first);
447 if (iter == properties.end())
448 {
449 return {};
450 }
451
452 double value = std::get<T>(iter->second) *
453 std::pow(10, sensorInfo.scale - sensorInfo.exponentR);
454 int32_t rawData =
455 (value - sensorInfo.scaledOffset) / sensorInfo.coefficientM;
456
457 constexpr uint8_t sensorUnitsSignedBits = 2 << 6;
458 constexpr uint8_t signedDataFormat = 0x80;
459 // if sensorUnits1 [7:6] = 10b, sensor is signed
460 if ((sensorInfo.sensorUnits1 & sensorUnitsSignedBits) == signedDataFormat)
461 {
462 if (rawData > std::numeric_limits<int8_t>::max() ||
463 rawData < std::numeric_limits<int8_t>::lowest())
464 {
465 log<level::ERR>("Value out of range");
466 throw std::out_of_range("Value out of range");
467 }
468 setReading(static_cast<int8_t>(rawData), &response);
469 }
470 else
471 {
472 if (rawData > std::numeric_limits<uint8_t>::max() ||
473 rawData < std::numeric_limits<uint8_t>::lowest())
474 {
475 log<level::ERR>("Value out of range");
476 throw std::out_of_range("Value out of range");
477 }
478 setReading(static_cast<uint8_t>(rawData), &response);
479 }
480
481 if (!std::isfinite(value))
482 {
483 response.readingOrStateUnavailable = 1;
484 }
485
486 if (!sensorCacheMap[id].has_value())
487 {
488 sensorCacheMap[id] = SensorData{};
489 }
490 sensorCacheMap[id]->response = response;
491
492 return response;
Lei YU8c2c0482021-09-16 17:28:28 +0800493}
494
495#endif // FEATURE_SENSORS_CACHE
496
Patrick Venture0b02be92018-08-31 11:55:55 -0700497} // namespace get
Tom Joseph816e92b2017-09-06 19:23:00 +0530498
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500499namespace set
500{
501
502/** @brief Make a DBus message for a Dbus call
503 * @param[in] updateInterface - Interface name
504 * @param[in] sensorPath - Path of the sensor
505 * @param[in] command - command to be executed
506 * @param[in] sensorInterface - DBus interface of sensor
507 * @return a dbus message
508 */
509IpmiUpdateData makeDbusMsg(const std::string& updateInterface,
510 const std::string& sensorPath,
511 const std::string& command,
512 const std::string& sensorInterface);
513
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500514/** @brief Update d-bus based on assertion type sensor data
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500515 * @param[in] cmdData - input sensor data
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500516 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500517 * @return a IPMI error code
518 */
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500519ipmi_ret_t assertion(const SetSensorReadingReq& cmdData,
520 const Info& sensorInfo);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500521
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500522/** @brief Update d-bus based on a reading assertion
523 * @tparam T - type of d-bus property mapping this sensor
524 * @param[in] cmdData - input sensor data
525 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500526 * @return a IPMI error code
527 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700528template <typename T>
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500529ipmi_ret_t readingAssertion(const SetSensorReadingReq& cmdData,
530 const Info& sensorInfo)
531{
Patrick Venture0b02be92018-08-31 11:55:55 -0700532 auto msg =
533 makeDbusMsg("org.freedesktop.DBus.Properties", sensorInfo.sensorPath,
534 "Set", sensorInfo.sensorInterface);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500535
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500536 const auto& interface = sensorInfo.propertyInterfaces.begin();
537 msg.append(interface->first);
538 for (const auto& property : interface->second)
539 {
540 msg.append(property.first);
Andrew Geissler6467ed22020-05-16 16:03:53 -0500541 std::variant<T> value = static_cast<T>((cmdData.assertOffset8_14 << 8) |
542 cmdData.assertOffset0_7);
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500543 msg.append(value);
544 }
545 return updateToDbus(msg);
546}
547
Emily Shaffercc941e12017-06-14 13:06:26 -0700548/** @brief Update d-bus based on a discrete reading
549 * @param[in] cmdData - input sensor data
550 * @param[in] sensorInfo - sensor d-bus info
551 * @return an IPMI error code
552 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700553template <typename T>
Emily Shaffercc941e12017-06-14 13:06:26 -0700554ipmi_ret_t readingData(const SetSensorReadingReq& cmdData,
555 const Info& sensorInfo)
556{
Patrick Venture0b02be92018-08-31 11:55:55 -0700557 T raw_value =
558 (sensorInfo.coefficientM * cmdData.reading) + sensorInfo.scaledOffset;
Tom Joseph22102152018-03-02 18:46:39 +0530559
Patrick Venture586d35b2018-09-07 19:56:18 -0700560 raw_value *= std::pow(10, sensorInfo.exponentR - sensorInfo.scale);
Tom Joseph22102152018-03-02 18:46:39 +0530561
Patrick Venture0b02be92018-08-31 11:55:55 -0700562 auto msg =
563 makeDbusMsg("org.freedesktop.DBus.Properties", sensorInfo.sensorPath,
564 "Set", sensorInfo.sensorInterface);
Emily Shaffercc941e12017-06-14 13:06:26 -0700565
566 const auto& interface = sensorInfo.propertyInterfaces.begin();
567 msg.append(interface->first);
568
Emily Shaffercc941e12017-06-14 13:06:26 -0700569 for (const auto& property : interface->second)
570 {
571 msg.append(property.first);
Vernon Mauery16b86932019-05-01 08:36:11 -0700572 std::variant<T> value = raw_value;
Emily Shaffercc941e12017-06-14 13:06:26 -0700573 msg.append(value);
574 }
575 return updateToDbus(msg);
576}
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500577
578/** @brief Update d-bus based on eventdata type sensor data
579 * @param[in] cmdData - input sensor data
580 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500581 * @return a IPMI error code
582 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700583ipmi_ret_t eventdata(const SetSensorReadingReq& cmdData, const Info& sensorInfo,
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500584 uint8_t data);
585
586/** @brief Update d-bus based on eventdata1 type sensor data
587 * @param[in] cmdData - input sensor data
588 * @param[in] sensorInfo - sensor d-bus info
589 * @return a IPMI error code
590 */
591inline ipmi_ret_t eventdata1(const SetSensorReadingReq& cmdData,
592 const Info& sensorInfo)
593{
594 return eventdata(cmdData, sensorInfo, cmdData.eventData1);
595}
596
597/** @brief Update d-bus based on eventdata2 type sensor data
598 * @param[in] cmdData - input sensor data
599 * @param[in] sensorInfo - sensor d-bus info
600 * @return a IPMI error code
601 */
602inline ipmi_ret_t eventdata2(const SetSensorReadingReq& cmdData,
603 const Info& sensorInfo)
604{
605 return eventdata(cmdData, sensorInfo, cmdData.eventData2);
606}
607
608/** @brief Update d-bus based on eventdata3 type sensor data
609 * @param[in] cmdData - input sensor data
610 * @param[in] sensorInfo - sensor d-bus info
611 * @return a IPMI error code
612 */
613inline ipmi_ret_t eventdata3(const SetSensorReadingReq& cmdData,
614 const Info& sensorInfo)
615{
616 return eventdata(cmdData, sensorInfo, cmdData.eventData3);
617}
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500618
Patrick Venture0b02be92018-08-31 11:55:55 -0700619} // namespace set
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500620
621namespace notify
622{
623
624/** @brief Make a DBus message for a Dbus call
625 * @param[in] updateInterface - Interface name
626 * @param[in] sensorPath - Path of the sensor
627 * @param[in] command - command to be executed
628 * @param[in] sensorInterface - DBus interface of sensor
629 * @return a dbus message
630 */
631IpmiUpdateData makeDbusMsg(const std::string& updateInterface,
632 const std::string& sensorPath,
633 const std::string& command,
634 const std::string& sensorInterface);
635
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500636/** @brief Update d-bus based on assertion type sensor data
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500637 * @param[in] interfaceMap - sensor interface
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500638 * @param[in] cmdData - input sensor data
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500639 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500640 * @return a IPMI error code
641 */
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500642ipmi_ret_t assertion(const SetSensorReadingReq& cmdData,
643 const Info& sensorInfo);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500644
Patrick Venture0b02be92018-08-31 11:55:55 -0700645} // namespace notify
Tom Joseph816e92b2017-09-06 19:23:00 +0530646
647namespace inventory
648{
649
650namespace get
651{
652
Lei YUff8c9b42021-10-15 14:20:57 +0800653#ifndef FEATURE_SENSORS_CACHE
654
Tom Joseph816e92b2017-09-06 19:23:00 +0530655/**
656 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
657 * reading command response.
658 *
659 * @param[in] sensorInfo - Dbus info related to sensor.
660 *
661 * @return Response for get sensor reading command.
662 */
663GetSensorResponse assertion(const Info& sensorInfo);
664
Lei YUff8c9b42021-10-15 14:20:57 +0800665#else
666
667/**
668 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
669 * reading command response.
670 *
671 * @param[in] id - The sensor id
672 * @param[in] sensorInfo - Dbus info related to sensor.
673 * @param[in] msg - Dbus message from match callback.
674 *
675 * @return Response for get sensor reading command.
676 */
677std::optional<GetSensorResponse> assertion(uint8_t id, const Info& sensorInfo,
Lei YU8e8152c2021-12-06 20:11:08 +0800678 const PropertyMap& properties);
Lei YUff8c9b42021-10-15 14:20:57 +0800679
680#endif
681
Tom Joseph816e92b2017-09-06 19:23:00 +0530682} // namespace get
683
684} // namespace inventory
Patrick Venture0b02be92018-08-31 11:55:55 -0700685} // namespace sensor
686} // namespace ipmi