blob: a3253b97c3ba17ebc9b7c63dc57988f37453b1eb [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{
274 auto msg = makeDbusMsg(
275 "org.freedesktop.DBus.Properties",
276 sensorInfo.sensorPath,
277 "Set",
278 sensorInfo.sensorInterface);
279
280 const auto& interface = sensorInfo.propertyInterfaces.begin();
281 msg.append(interface->first);
282
283 ipmi::sensor::Multiplier m = sensorInfo.coefficientM;
284 if (0 == m)
285 {
286 m = 1; // Avoid * 0
287 }
288
289 // TODO: Refactor this into a generated function depending on the type
290 // of conversion for the value between IPMI and dbus.
291 T raw_value = (m * cmdData.reading) + sensorInfo.scaledOffset;
292
293 for (const auto& property : interface->second)
294 {
295 msg.append(property.first);
296 sdbusplus::message::variant<T> value = raw_value;
297 msg.append(value);
298 }
299 return updateToDbus(msg);
300}
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500301
302/** @brief Update d-bus based on eventdata type sensor data
303 * @param[in] cmdData - input sensor data
304 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500305 * @return a IPMI error code
306 */
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500307ipmi_ret_t eventdata(const SetSensorReadingReq& cmdData,
308 const Info& sensorInfo,
309 uint8_t data);
310
311/** @brief Update d-bus based on eventdata1 type sensor data
312 * @param[in] cmdData - input sensor data
313 * @param[in] sensorInfo - sensor d-bus info
314 * @return a IPMI error code
315 */
316inline ipmi_ret_t eventdata1(const SetSensorReadingReq& cmdData,
317 const Info& sensorInfo)
318{
319 return eventdata(cmdData, sensorInfo, cmdData.eventData1);
320}
321
322/** @brief Update d-bus based on eventdata2 type sensor data
323 * @param[in] cmdData - input sensor data
324 * @param[in] sensorInfo - sensor d-bus info
325 * @return a IPMI error code
326 */
327inline ipmi_ret_t eventdata2(const SetSensorReadingReq& cmdData,
328 const Info& sensorInfo)
329{
330 return eventdata(cmdData, sensorInfo, cmdData.eventData2);
331}
332
333/** @brief Update d-bus based on eventdata3 type sensor data
334 * @param[in] cmdData - input sensor data
335 * @param[in] sensorInfo - sensor d-bus info
336 * @return a IPMI error code
337 */
338inline ipmi_ret_t eventdata3(const SetSensorReadingReq& cmdData,
339 const Info& sensorInfo)
340{
341 return eventdata(cmdData, sensorInfo, cmdData.eventData3);
342}
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500343
344}//namespace set
345
346namespace notify
347{
348
349/** @brief Make a DBus message for a Dbus call
350 * @param[in] updateInterface - Interface name
351 * @param[in] sensorPath - Path of the sensor
352 * @param[in] command - command to be executed
353 * @param[in] sensorInterface - DBus interface of sensor
354 * @return a dbus message
355 */
356IpmiUpdateData makeDbusMsg(const std::string& updateInterface,
357 const std::string& sensorPath,
358 const std::string& command,
359 const std::string& sensorInterface);
360
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500361/** @brief Update d-bus based on assertion type sensor data
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500362 * @param[in] interfaceMap - sensor interface
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500363 * @param[in] cmdData - input sensor data
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500364 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500365 * @return a IPMI error code
366 */
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500367ipmi_ret_t assertion(const SetSensorReadingReq& cmdData,
368 const Info& sensorInfo);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500369
370}//namespace notify
Tom Joseph816e92b2017-09-06 19:23:00 +0530371
372namespace inventory
373{
374
375namespace get
376{
377
378/**
379 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
380 * reading command response.
381 *
382 * @param[in] sensorInfo - Dbus info related to sensor.
383 *
384 * @return Response for get sensor reading command.
385 */
386GetSensorResponse assertion(const Info& sensorInfo);
387
388} // namespace get
389
390} // namespace inventory
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500391}//namespace sensor
392}//namespace ipmi