blob: e36b71ac70e91663323abba3fc6839dd942d7281 [file] [log] [blame]
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -05001#pragma once
2
Tom Joseph13b87a32018-02-16 09:37:43 +05303#include <math.h>
Tom Joseph295f17e2017-09-07 00:09:46 +05304#include "sensorhandler.h"
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -05005#include "types.hpp"
Tom Joseph295f17e2017-09-07 00:09:46 +05306#include "utils.hpp"
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -05007#include "host-ipmid/ipmid-api.h"
8
9namespace ipmi
10{
11namespace sensor
12{
13
14using Assertion = uint16_t;
15using Deassertion = uint16_t;
16using AssertionSet = std::pair<Assertion, Deassertion>;
17
18using Service = std::string;
19using Path = std::string;
20using Interface = std::string;
21
22using ServicePath = std::pair<Path, Service>;
23
24using Interfaces = std::vector<Interface>;
25
26using MapperResponseType = std::map<Path, std::map<Service, Interfaces>>;
27
28/** @brief get the D-Bus service and service path
29 * @param[in] bus - The Dbus bus object
30 * @param[in] interface - interface to the service
31 * @param[in] path - interested path in the list of objects
32 * @return pair of service path and service
33 */
34ServicePath getServiceAndPath(sdbusplus::bus::bus& bus,
35 const std::string& interface,
36 const std::string& path = std::string());
37
38/** @brief Make assertion set from input data
39 * @param[in] cmdData - Input sensor data
40 * @return pair of assertion and deassertion set
41 */
42AssertionSet getAssertionSet(const SetSensorReadingReq& cmdData);
43
44/** @brief send the message to DBus
45 * @param[in] msg - message to send
46 * @return failure status in IPMI error code
47 */
Dhruvaraj Subhashchandran2a444d02017-08-07 01:45:14 -050048ipmi_ret_t updateToDbus(IpmiUpdateData& msg);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -050049
Tom Joseph816e92b2017-09-06 19:23:00 +053050namespace get
51{
52
Tom Josephb0adbcd2018-01-24 11:51:29 +053053/** @brief Populate sensor name from the D-Bus property associated with the
54 * sensor. In the example entry from the yaml, the name of the D-bus
55 * property "AttemptsLeft" is the sensor name.
56 *
57 * 0x07:
58 * sensorType: 195
59 * path: /xyz/openbmc_project/state/host0
60 * sensorReadingType: 0x6F
61 * serviceInterface: org.freedesktop.DBus.Properties
62 * readingType: readingAssertion
63 * sensorNamePattern: nameProperty
64 * interfaces:
65 * xyz.openbmc_project.Control.Boot.RebootAttempts:
66 * AttemptsLeft:
67 * Offsets:
68 * 0xFF:
69 * type: uint32_t
70 *
71 *
72 * @param[in] sensorInfo - Dbus info related to sensor.
73 *
74 * @return On success return the sensor name for the sensor.
75 */
76inline SensorName nameProperty(const Info& sensorInfo)
77{
78 return sensorInfo.propertyInterfaces.begin()->second.begin()->first;
79}
80
81/** @brief Populate sensor name from the D-Bus object associated with the
82 * sensor. If the object path is /system/chassis/motherboard/dimm0 then
83 * the leaf dimm0 is considered as the sensor name.
84 *
85 * @param[in] sensorInfo - Dbus info related to sensor.
86 *
87 * @return On success return the sensor name for the sensor.
88 */
89inline SensorName nameLeaf(const Info& sensorInfo)
90{
91 return sensorInfo.sensorPath.substr(
92 sensorInfo.sensorPath.find_last_of('/') + 1,
93 sensorInfo.sensorPath.length());
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/cpu0/core0
98 * then the sensor name is cpu0_core0. The leaf and the parent is put
99 * together to get the sensor name.
100 *
101 * @param[in] sensorInfo - Dbus info related to sensor.
102 *
103 * @return On success return the sensor name for the sensor.
104 */
105SensorName nameParentLeaf(const Info& sensorInfo);
106
Tom Joseph816e92b2017-09-06 19:23:00 +0530107/**
108 * @brief Helper function to map the dbus info to sensor's assertion status
109 * for the get sensor reading command.
110 *
111 * @param[in] sensorInfo - Dbus info related to sensor.
112 * @param[in] path - Dbus object path.
113 * @param[in] interface - Dbus interface.
114 *
115 * @return Response for get sensor reading command.
116 */
117GetSensorResponse mapDbusToAssertion(const Info& sensorInfo,
118 const InstancePath& path,
119 const DbusInterface& interface);
120
121/**
122 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
123 * reading command response.
124 *
125 * @param[in] sensorInfo - Dbus info related to sensor.
126 *
127 * @return Response for get sensor reading command.
128 */
129GetSensorResponse assertion(const Info& sensorInfo);
130
Tom Josephe4014fc2017-09-06 23:57:36 +0530131/**
132 * @brief Maps the Dbus info to the reading field in the Get sensor reading
133 * command response.
134 *
135 * @param[in] sensorInfo - Dbus info related to sensor.
136 *
137 * @return Response for get sensor reading command.
138 */
139GetSensorResponse eventdata2(const Info& sensorInfo);
140
Tom Joseph295f17e2017-09-07 00:09:46 +0530141/**
142 * @brief readingAssertion is a case where the entire assertion state field
143 * serves as the sensor value.
144 *
145 * @tparam T - type of the dbus property related to sensor.
146 * @param[in] sensorInfo - Dbus info related to sensor.
147 *
148 * @return Response for get sensor reading command.
149 */
150template<typename T>
151GetSensorResponse readingAssertion(const Info& sensorInfo)
152{
153 sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
154 GetSensorResponse response {};
155 auto responseData = reinterpret_cast<GetReadingResponse*>(response.data());
156
157 auto service = ipmi::getService(bus,
158 sensorInfo.sensorInterface,
159 sensorInfo.sensorPath);
160
161 auto propValue = ipmi::getDbusProperty(
162 bus,
163 service,
164 sensorInfo.sensorPath,
165 sensorInfo.propertyInterfaces.begin()->first,
166 sensorInfo.propertyInterfaces.begin()->second.begin()->first);
167
168 setAssertionBytes(static_cast<uint16_t>(propValue.get<T>()), responseData);
169
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 */
181template<typename T>
182GetSensorResponse readingData(const Info& sensorInfo)
183{
184 sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
185 GetSensorResponse response {};
186 auto responseData = reinterpret_cast<GetReadingResponse*>(response.data());
187
188 enableScanning(responseData);
189
190 auto service = ipmi::getService(bus,
191 sensorInfo.sensorInterface,
192 sensorInfo.sensorPath);
193
194 auto propValue = ipmi::getDbusProperty(
195 bus,
196 service,
197 sensorInfo.sensorPath,
198 sensorInfo.propertyInterfaces.begin()->first,
199 sensorInfo.propertyInterfaces.begin()->second.begin()->first);
200
Tom Joseph13b87a32018-02-16 09:37:43 +0530201 double value = propValue.get<T>() * pow(10,
202 sensorInfo.scale - sensorInfo.exponentR);
Tom Josephe05b2922017-09-07 00:43:16 +0530203
Tom Joseph13b87a32018-02-16 09:37:43 +0530204 auto rawData = static_cast<uint8_t>(
205 (value - sensorInfo.scaledOffset) / sensorInfo.coefficientM);
206
207 setReading(rawData, responseData);
Tom Josephe05b2922017-09-07 00:43:16 +0530208
209 return response;
210}
211
Tom Joseph816e92b2017-09-06 19:23:00 +0530212} //namespace get
213
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500214namespace set
215{
216
217/** @brief Make a DBus message for a Dbus call
218 * @param[in] updateInterface - Interface name
219 * @param[in] sensorPath - Path of the sensor
220 * @param[in] command - command to be executed
221 * @param[in] sensorInterface - DBus interface of sensor
222 * @return a dbus message
223 */
224IpmiUpdateData makeDbusMsg(const std::string& updateInterface,
225 const std::string& sensorPath,
226 const std::string& command,
227 const std::string& sensorInterface);
228
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500229/** @brief Update d-bus based on assertion type sensor data
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500230 * @param[in] cmdData - input sensor data
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500231 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500232 * @return a IPMI error code
233 */
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500234ipmi_ret_t assertion(const SetSensorReadingReq& cmdData,
235 const Info& sensorInfo);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500236
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500237/** @brief Update d-bus based on a reading assertion
238 * @tparam T - type of d-bus property mapping this sensor
239 * @param[in] cmdData - input sensor data
240 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500241 * @return a IPMI error code
242 */
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500243template<typename T>
244ipmi_ret_t readingAssertion(const SetSensorReadingReq& cmdData,
245 const Info& sensorInfo)
246{
247 auto msg = makeDbusMsg(
248 "org.freedesktop.DBus.Properties",
249 sensorInfo.sensorPath,
250 "Set",
251 sensorInfo.sensorInterface);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500252
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500253 const auto& interface = sensorInfo.propertyInterfaces.begin();
254 msg.append(interface->first);
255 for (const auto& property : interface->second)
256 {
257 msg.append(property.first);
258 sdbusplus::message::variant<T> value =
259 (cmdData.assertOffset8_14 << 8) | cmdData.assertOffset0_7;
260 msg.append(value);
261 }
262 return updateToDbus(msg);
263}
264
Emily Shaffercc941e12017-06-14 13:06:26 -0700265/** @brief Update d-bus based on a discrete reading
266 * @param[in] cmdData - input sensor data
267 * @param[in] sensorInfo - sensor d-bus info
268 * @return an IPMI error code
269 */
270template<typename T>
271ipmi_ret_t readingData(const SetSensorReadingReq& cmdData,
272 const Info& sensorInfo)
273{
Tom Joseph22102152018-03-02 18:46:39 +0530274 T raw_value = (sensorInfo.coefficientM * cmdData.reading) +
275 sensorInfo.scaledOffset;
276
277 raw_value *= pow(10, sensorInfo.exponentR - sensorInfo.scale);
278
279 auto msg = makeDbusMsg("org.freedesktop.DBus.Properties",
280 sensorInfo.sensorPath,
281 "Set",
282 sensorInfo.sensorInterface);
Emily Shaffercc941e12017-06-14 13:06:26 -0700283
284 const auto& interface = sensorInfo.propertyInterfaces.begin();
285 msg.append(interface->first);
286
Emily Shaffercc941e12017-06-14 13:06:26 -0700287 for (const auto& property : interface->second)
288 {
289 msg.append(property.first);
290 sdbusplus::message::variant<T> value = raw_value;
291 msg.append(value);
292 }
293 return updateToDbus(msg);
294}
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500295
296/** @brief Update d-bus based on eventdata type sensor data
297 * @param[in] cmdData - input sensor data
298 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500299 * @return a IPMI error code
300 */
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500301ipmi_ret_t eventdata(const SetSensorReadingReq& cmdData,
302 const Info& sensorInfo,
303 uint8_t data);
304
305/** @brief Update d-bus based on eventdata1 type sensor data
306 * @param[in] cmdData - input sensor data
307 * @param[in] sensorInfo - sensor d-bus info
308 * @return a IPMI error code
309 */
310inline ipmi_ret_t eventdata1(const SetSensorReadingReq& cmdData,
311 const Info& sensorInfo)
312{
313 return eventdata(cmdData, sensorInfo, cmdData.eventData1);
314}
315
316/** @brief Update d-bus based on eventdata2 type sensor data
317 * @param[in] cmdData - input sensor data
318 * @param[in] sensorInfo - sensor d-bus info
319 * @return a IPMI error code
320 */
321inline ipmi_ret_t eventdata2(const SetSensorReadingReq& cmdData,
322 const Info& sensorInfo)
323{
324 return eventdata(cmdData, sensorInfo, cmdData.eventData2);
325}
326
327/** @brief Update d-bus based on eventdata3 type sensor data
328 * @param[in] cmdData - input sensor data
329 * @param[in] sensorInfo - sensor d-bus info
330 * @return a IPMI error code
331 */
332inline ipmi_ret_t eventdata3(const SetSensorReadingReq& cmdData,
333 const Info& sensorInfo)
334{
335 return eventdata(cmdData, sensorInfo, cmdData.eventData3);
336}
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500337
338}//namespace set
339
340namespace notify
341{
342
343/** @brief Make a DBus message for a Dbus call
344 * @param[in] updateInterface - Interface name
345 * @param[in] sensorPath - Path of the sensor
346 * @param[in] command - command to be executed
347 * @param[in] sensorInterface - DBus interface of sensor
348 * @return a dbus message
349 */
350IpmiUpdateData makeDbusMsg(const std::string& updateInterface,
351 const std::string& sensorPath,
352 const std::string& command,
353 const std::string& sensorInterface);
354
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500355/** @brief Update d-bus based on assertion type sensor data
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500356 * @param[in] interfaceMap - sensor interface
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500357 * @param[in] cmdData - input sensor data
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500358 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500359 * @return a IPMI error code
360 */
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500361ipmi_ret_t assertion(const SetSensorReadingReq& cmdData,
362 const Info& sensorInfo);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500363
364}//namespace notify
Tom Joseph816e92b2017-09-06 19:23:00 +0530365
366namespace inventory
367{
368
369namespace get
370{
371
372/**
373 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
374 * reading command response.
375 *
376 * @param[in] sensorInfo - Dbus info related to sensor.
377 *
378 * @return Response for get sensor reading command.
379 */
380GetSensorResponse assertion(const Info& sensorInfo);
381
382} // namespace get
383
384} // namespace inventory
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500385}//namespace sensor
386}//namespace ipmi