blob: 73f0dbf11df7f6a1a9f6ff430870446db2fe2554 [file] [log] [blame]
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -05001#pragma once
2
Patrick Venture46470a32018-09-07 19:26:25 -07003#include "sensorhandler.hpp"
Patrick Venture0b02be92018-08-31 11:55:55 -07004
Patrick Venture586d35b2018-09-07 19:56:18 -07005#include <cmath>
Vernon Mauerye08fbff2019-04-03 09:19:34 -07006#include <ipmid/api.hpp>
Vernon Mauery33250242019-03-12 16:49:26 -07007#include <ipmid/types.hpp>
Vernon Mauery6a98fe72019-03-11 15:57:48 -07008#include <ipmid/utils.hpp>
William A. Kennington III4c008022018-10-12 17:18:14 -07009#include <sdbusplus/message/types.hpp>
Patrick Venture0b02be92018-08-31 11:55:55 -070010
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -050011namespace ipmi
12{
13namespace sensor
14{
15
16using Assertion = uint16_t;
17using Deassertion = uint16_t;
18using AssertionSet = std::pair<Assertion, Deassertion>;
19
20using Service = std::string;
21using Path = std::string;
22using Interface = std::string;
23
24using ServicePath = std::pair<Path, Service>;
25
26using Interfaces = std::vector<Interface>;
27
28using MapperResponseType = std::map<Path, std::map<Service, Interfaces>>;
29
30/** @brief get the D-Bus service and service path
31 * @param[in] bus - The Dbus bus object
32 * @param[in] interface - interface to the service
33 * @param[in] path - interested path in the list of objects
34 * @return pair of service path and service
35 */
36ServicePath getServiceAndPath(sdbusplus::bus::bus& bus,
37 const std::string& interface,
38 const std::string& path = std::string());
39
40/** @brief Make assertion set from input data
41 * @param[in] cmdData - Input sensor data
42 * @return pair of assertion and deassertion set
43 */
44AssertionSet getAssertionSet(const SetSensorReadingReq& cmdData);
45
46/** @brief send the message to DBus
47 * @param[in] msg - message to send
48 * @return failure status in IPMI error code
49 */
Dhruvaraj Subhashchandran2a444d02017-08-07 01:45:14 -050050ipmi_ret_t updateToDbus(IpmiUpdateData& msg);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -050051
Tom Joseph816e92b2017-09-06 19:23:00 +053052namespace get
53{
54
Tom Josephb0adbcd2018-01-24 11:51:29 +053055/** @brief Populate sensor name from the D-Bus property associated with the
56 * sensor. In the example entry from the yaml, the name of the D-bus
57 * property "AttemptsLeft" is the sensor name.
58 *
59 * 0x07:
60 * sensorType: 195
61 * path: /xyz/openbmc_project/state/host0
62 * sensorReadingType: 0x6F
63 * serviceInterface: org.freedesktop.DBus.Properties
64 * readingType: readingAssertion
65 * sensorNamePattern: nameProperty
66 * interfaces:
67 * xyz.openbmc_project.Control.Boot.RebootAttempts:
68 * AttemptsLeft:
69 * Offsets:
70 * 0xFF:
71 * type: uint32_t
72 *
73 *
74 * @param[in] sensorInfo - Dbus info related to sensor.
75 *
76 * @return On success return the sensor name for the sensor.
77 */
78inline SensorName nameProperty(const Info& sensorInfo)
79{
80 return sensorInfo.propertyInterfaces.begin()->second.begin()->first;
81}
82
83/** @brief Populate sensor name from the D-Bus object associated with the
84 * sensor. If the object path is /system/chassis/motherboard/dimm0 then
85 * the leaf dimm0 is considered as the sensor name.
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 nameLeaf(const Info& sensorInfo)
92{
93 return sensorInfo.sensorPath.substr(
Patrick Venture0b02be92018-08-31 11:55:55 -070094 sensorInfo.sensorPath.find_last_of('/') + 1,
95 sensorInfo.sensorPath.length());
Tom Josephb0adbcd2018-01-24 11:51:29 +053096}
97
98/** @brief Populate sensor name from the D-Bus object associated with the
99 * sensor. If the object path is /system/chassis/motherboard/cpu0/core0
100 * then the sensor name is cpu0_core0. The leaf and the parent is put
101 * together to get the sensor name.
102 *
103 * @param[in] sensorInfo - Dbus info related to sensor.
104 *
105 * @return On success return the sensor name for the sensor.
106 */
107SensorName nameParentLeaf(const Info& sensorInfo);
108
Tom Joseph816e92b2017-09-06 19:23:00 +0530109/**
110 * @brief Helper function to map the dbus info to sensor's assertion status
111 * for the get sensor reading command.
112 *
113 * @param[in] sensorInfo - Dbus info related to sensor.
114 * @param[in] path - Dbus object path.
115 * @param[in] interface - Dbus interface.
116 *
117 * @return Response for get sensor reading command.
118 */
119GetSensorResponse mapDbusToAssertion(const Info& sensorInfo,
120 const InstancePath& path,
121 const DbusInterface& interface);
122
123/**
124 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
125 * reading command response.
126 *
127 * @param[in] sensorInfo - Dbus info related to sensor.
128 *
129 * @return Response for get sensor reading command.
130 */
131GetSensorResponse assertion(const Info& sensorInfo);
132
Tom Josephe4014fc2017-09-06 23:57:36 +0530133/**
134 * @brief Maps the Dbus info to the reading field in the Get sensor reading
135 * command response.
136 *
137 * @param[in] sensorInfo - Dbus info related to sensor.
138 *
139 * @return Response for get sensor reading command.
140 */
141GetSensorResponse eventdata2(const Info& sensorInfo);
142
Tom Joseph295f17e2017-09-07 00:09:46 +0530143/**
144 * @brief readingAssertion is a case where the entire assertion state field
145 * serves as the sensor value.
146 *
147 * @tparam T - type of the dbus property related to sensor.
148 * @param[in] sensorInfo - Dbus info related to sensor.
149 *
150 * @return Response for get sensor reading command.
151 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700152template <typename T>
Tom Joseph295f17e2017-09-07 00:09:46 +0530153GetSensorResponse readingAssertion(const Info& sensorInfo)
154{
155 sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
Patrick Venture0b02be92018-08-31 11:55:55 -0700156 GetSensorResponse response{};
Tom Joseph295f17e2017-09-07 00:09:46 +0530157 auto responseData = reinterpret_cast<GetReadingResponse*>(response.data());
158
Patrick Venture0b02be92018-08-31 11:55:55 -0700159 auto service = ipmi::getService(bus, sensorInfo.sensorInterface,
Tom Joseph295f17e2017-09-07 00:09:46 +0530160 sensorInfo.sensorPath);
161
162 auto propValue = ipmi::getDbusProperty(
Patrick Venture0b02be92018-08-31 11:55:55 -0700163 bus, service, sensorInfo.sensorPath,
164 sensorInfo.propertyInterfaces.begin()->first,
165 sensorInfo.propertyInterfaces.begin()->second.begin()->first);
Tom Joseph295f17e2017-09-07 00:09:46 +0530166
Vernon Maueryf442e112019-04-09 11:44:36 -0700167 setAssertionBytes(static_cast<uint16_t>(std::get<T>(propValue)),
William A. Kennington III4c008022018-10-12 17:18:14 -0700168 responseData);
Tom Joseph295f17e2017-09-07 00:09:46 +0530169
170 return response;
171}
172
Tom Josephe05b2922017-09-07 00:43:16 +0530173/** @brief Map the Dbus info to the reading field in the Get sensor reading
174 * command response
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 Josephe05b2922017-09-07 00:43:16 +0530182GetSensorResponse readingData(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 Josephe05b2922017-09-07 00:43:16 +0530186 auto responseData = reinterpret_cast<GetReadingResponse*>(response.data());
187
188 enableScanning(responseData);
189
Patrick Venture0b02be92018-08-31 11:55:55 -0700190 auto service = ipmi::getService(bus, sensorInfo.sensorInterface,
Tom Josephe05b2922017-09-07 00:43:16 +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 Josephe05b2922017-09-07 00:43:16 +0530197
Vernon Maueryf442e112019-04-09 11:44:36 -0700198 double value = std::get<T>(propValue) *
Patrick Venture586d35b2018-09-07 19:56:18 -0700199 std::pow(10, sensorInfo.scale - sensorInfo.exponentR);
Tom Josephe05b2922017-09-07 00:43:16 +0530200
Patrick Venture0b02be92018-08-31 11:55:55 -0700201 auto rawData = static_cast<uint8_t>((value - sensorInfo.scaledOffset) /
202 sensorInfo.coefficientM);
Tom Joseph13b87a32018-02-16 09:37:43 +0530203
204 setReading(rawData, responseData);
Tom Josephe05b2922017-09-07 00:43:16 +0530205
206 return response;
207}
208
Patrick Venture0b02be92018-08-31 11:55:55 -0700209} // namespace get
Tom Joseph816e92b2017-09-06 19:23:00 +0530210
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500211namespace set
212{
213
214/** @brief Make a DBus message for a Dbus call
215 * @param[in] updateInterface - Interface name
216 * @param[in] sensorPath - Path of the sensor
217 * @param[in] command - command to be executed
218 * @param[in] sensorInterface - DBus interface of sensor
219 * @return a dbus message
220 */
221IpmiUpdateData makeDbusMsg(const std::string& updateInterface,
222 const std::string& sensorPath,
223 const std::string& command,
224 const std::string& sensorInterface);
225
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500226/** @brief Update d-bus based on assertion type sensor data
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500227 * @param[in] cmdData - input sensor data
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500228 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500229 * @return a IPMI error code
230 */
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500231ipmi_ret_t assertion(const SetSensorReadingReq& cmdData,
232 const Info& sensorInfo);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500233
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500234/** @brief Update d-bus based on a reading assertion
235 * @tparam T - type of d-bus property mapping this sensor
236 * @param[in] cmdData - input sensor data
237 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500238 * @return a IPMI error code
239 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700240template <typename T>
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500241ipmi_ret_t readingAssertion(const SetSensorReadingReq& cmdData,
242 const Info& sensorInfo)
243{
Patrick Venture0b02be92018-08-31 11:55:55 -0700244 auto msg =
245 makeDbusMsg("org.freedesktop.DBus.Properties", sensorInfo.sensorPath,
246 "Set", sensorInfo.sensorInterface);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500247
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500248 const auto& interface = sensorInfo.propertyInterfaces.begin();
249 msg.append(interface->first);
250 for (const auto& property : interface->second)
251 {
252 msg.append(property.first);
Vernon Mauery16b86932019-05-01 08:36:11 -0700253 std::variant<T> value =
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500254 (cmdData.assertOffset8_14 << 8) | cmdData.assertOffset0_7;
255 msg.append(value);
256 }
257 return updateToDbus(msg);
258}
259
Emily Shaffercc941e12017-06-14 13:06:26 -0700260/** @brief Update d-bus based on a discrete reading
261 * @param[in] cmdData - input sensor data
262 * @param[in] sensorInfo - sensor d-bus info
263 * @return an IPMI error code
264 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700265template <typename T>
Emily Shaffercc941e12017-06-14 13:06:26 -0700266ipmi_ret_t readingData(const SetSensorReadingReq& cmdData,
267 const Info& sensorInfo)
268{
Patrick Venture0b02be92018-08-31 11:55:55 -0700269 T raw_value =
270 (sensorInfo.coefficientM * cmdData.reading) + sensorInfo.scaledOffset;
Tom Joseph22102152018-03-02 18:46:39 +0530271
Patrick Venture586d35b2018-09-07 19:56:18 -0700272 raw_value *= std::pow(10, sensorInfo.exponentR - sensorInfo.scale);
Tom Joseph22102152018-03-02 18:46:39 +0530273
Patrick Venture0b02be92018-08-31 11:55:55 -0700274 auto msg =
275 makeDbusMsg("org.freedesktop.DBus.Properties", sensorInfo.sensorPath,
276 "Set", sensorInfo.sensorInterface);
Emily Shaffercc941e12017-06-14 13:06:26 -0700277
278 const auto& interface = sensorInfo.propertyInterfaces.begin();
279 msg.append(interface->first);
280
Emily Shaffercc941e12017-06-14 13:06:26 -0700281 for (const auto& property : interface->second)
282 {
283 msg.append(property.first);
Vernon Mauery16b86932019-05-01 08:36:11 -0700284 std::variant<T> value = raw_value;
Emily Shaffercc941e12017-06-14 13:06:26 -0700285 msg.append(value);
286 }
287 return updateToDbus(msg);
288}
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500289
290/** @brief Update d-bus based on eventdata type sensor data
291 * @param[in] cmdData - input sensor data
292 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500293 * @return a IPMI error code
294 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700295ipmi_ret_t eventdata(const SetSensorReadingReq& cmdData, const Info& sensorInfo,
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500296 uint8_t data);
297
298/** @brief Update d-bus based on eventdata1 type sensor data
299 * @param[in] cmdData - input sensor data
300 * @param[in] sensorInfo - sensor d-bus info
301 * @return a IPMI error code
302 */
303inline ipmi_ret_t eventdata1(const SetSensorReadingReq& cmdData,
304 const Info& sensorInfo)
305{
306 return eventdata(cmdData, sensorInfo, cmdData.eventData1);
307}
308
309/** @brief Update d-bus based on eventdata2 type sensor data
310 * @param[in] cmdData - input sensor data
311 * @param[in] sensorInfo - sensor d-bus info
312 * @return a IPMI error code
313 */
314inline ipmi_ret_t eventdata2(const SetSensorReadingReq& cmdData,
315 const Info& sensorInfo)
316{
317 return eventdata(cmdData, sensorInfo, cmdData.eventData2);
318}
319
320/** @brief Update d-bus based on eventdata3 type sensor data
321 * @param[in] cmdData - input sensor data
322 * @param[in] sensorInfo - sensor d-bus info
323 * @return a IPMI error code
324 */
325inline ipmi_ret_t eventdata3(const SetSensorReadingReq& cmdData,
326 const Info& sensorInfo)
327{
328 return eventdata(cmdData, sensorInfo, cmdData.eventData3);
329}
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500330
Patrick Venture0b02be92018-08-31 11:55:55 -0700331} // namespace set
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500332
333namespace notify
334{
335
336/** @brief Make a DBus message for a Dbus call
337 * @param[in] updateInterface - Interface name
338 * @param[in] sensorPath - Path of the sensor
339 * @param[in] command - command to be executed
340 * @param[in] sensorInterface - DBus interface of sensor
341 * @return a dbus message
342 */
343IpmiUpdateData makeDbusMsg(const std::string& updateInterface,
344 const std::string& sensorPath,
345 const std::string& command,
346 const std::string& sensorInterface);
347
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500348/** @brief Update d-bus based on assertion type sensor data
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500349 * @param[in] interfaceMap - sensor interface
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500350 * @param[in] cmdData - input sensor data
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500351 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500352 * @return a IPMI error code
353 */
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500354ipmi_ret_t assertion(const SetSensorReadingReq& cmdData,
355 const Info& sensorInfo);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500356
Patrick Venture0b02be92018-08-31 11:55:55 -0700357} // namespace notify
Tom Joseph816e92b2017-09-06 19:23:00 +0530358
359namespace inventory
360{
361
362namespace get
363{
364
365/**
366 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
367 * reading command response.
368 *
369 * @param[in] sensorInfo - Dbus info related to sensor.
370 *
371 * @return Response for get sensor reading command.
372 */
373GetSensorResponse assertion(const Info& sensorInfo);
374
375} // namespace get
376
377} // namespace inventory
Patrick Venture0b02be92018-08-31 11:55:55 -0700378} // namespace sensor
379} // namespace ipmi