blob: 01b8e4f2caca65a3e3a921543a0bc58d10c68fd4 [file] [log] [blame]
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -05001#pragma once
2
Tom Joseph295f17e2017-09-07 00:09:46 +05303#include "sensorhandler.h"
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -05004#include "types.hpp"
Tom Joseph295f17e2017-09-07 00:09:46 +05305#include "utils.hpp"
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -05006#include "host-ipmid/ipmid-api.h"
7
8namespace ipmi
9{
10namespace sensor
11{
12
13using Assertion = uint16_t;
14using Deassertion = uint16_t;
15using AssertionSet = std::pair<Assertion, Deassertion>;
16
17using Service = std::string;
18using Path = std::string;
19using Interface = std::string;
20
21using ServicePath = std::pair<Path, Service>;
22
23using Interfaces = std::vector<Interface>;
24
25using MapperResponseType = std::map<Path, std::map<Service, Interfaces>>;
26
27/** @brief get the D-Bus service and service path
28 * @param[in] bus - The Dbus bus object
29 * @param[in] interface - interface to the service
30 * @param[in] path - interested path in the list of objects
31 * @return pair of service path and service
32 */
33ServicePath getServiceAndPath(sdbusplus::bus::bus& bus,
34 const std::string& interface,
35 const std::string& path = std::string());
36
37/** @brief Make assertion set from input data
38 * @param[in] cmdData - Input sensor data
39 * @return pair of assertion and deassertion set
40 */
41AssertionSet getAssertionSet(const SetSensorReadingReq& cmdData);
42
43/** @brief send the message to DBus
44 * @param[in] msg - message to send
45 * @return failure status in IPMI error code
46 */
Dhruvaraj Subhashchandran2a444d02017-08-07 01:45:14 -050047ipmi_ret_t updateToDbus(IpmiUpdateData& msg);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -050048
Tom Joseph816e92b2017-09-06 19:23:00 +053049namespace get
50{
51
Tom Josephb0adbcd2018-01-24 11:51:29 +053052/** @brief Populate sensor name from the D-Bus property associated with the
53 * sensor. In the example entry from the yaml, the name of the D-bus
54 * property "AttemptsLeft" is the sensor name.
55 *
56 * 0x07:
57 * sensorType: 195
58 * path: /xyz/openbmc_project/state/host0
59 * sensorReadingType: 0x6F
60 * serviceInterface: org.freedesktop.DBus.Properties
61 * readingType: readingAssertion
62 * sensorNamePattern: nameProperty
63 * interfaces:
64 * xyz.openbmc_project.Control.Boot.RebootAttempts:
65 * AttemptsLeft:
66 * Offsets:
67 * 0xFF:
68 * type: uint32_t
69 *
70 *
71 * @param[in] sensorInfo - Dbus info related to sensor.
72 *
73 * @return On success return the sensor name for the sensor.
74 */
75inline SensorName nameProperty(const Info& sensorInfo)
76{
77 return sensorInfo.propertyInterfaces.begin()->second.begin()->first;
78}
79
80/** @brief Populate sensor name from the D-Bus object associated with the
81 * sensor. If the object path is /system/chassis/motherboard/dimm0 then
82 * the leaf dimm0 is considered as the sensor name.
83 *
84 * @param[in] sensorInfo - Dbus info related to sensor.
85 *
86 * @return On success return the sensor name for the sensor.
87 */
88inline SensorName nameLeaf(const Info& sensorInfo)
89{
90 return sensorInfo.sensorPath.substr(
91 sensorInfo.sensorPath.find_last_of('/') + 1,
92 sensorInfo.sensorPath.length());
93}
94
95/** @brief Populate sensor name from the D-Bus object associated with the
96 * sensor. If the object path is /system/chassis/motherboard/cpu0/core0
97 * then the sensor name is cpu0_core0. The leaf and the parent is put
98 * together to get 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 */
104SensorName nameParentLeaf(const Info& sensorInfo);
105
Tom Joseph816e92b2017-09-06 19:23:00 +0530106/**
107 * @brief Helper function to map the dbus info to sensor's assertion status
108 * for the get sensor reading command.
109 *
110 * @param[in] sensorInfo - Dbus info related to sensor.
111 * @param[in] path - Dbus object path.
112 * @param[in] interface - Dbus interface.
113 *
114 * @return Response for get sensor reading command.
115 */
116GetSensorResponse mapDbusToAssertion(const Info& sensorInfo,
117 const InstancePath& path,
118 const DbusInterface& interface);
119
120/**
121 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
122 * reading command response.
123 *
124 * @param[in] sensorInfo - Dbus info related to sensor.
125 *
126 * @return Response for get sensor reading command.
127 */
128GetSensorResponse assertion(const Info& sensorInfo);
129
Tom Josephe4014fc2017-09-06 23:57:36 +0530130/**
131 * @brief Maps the Dbus info to the reading field in the Get sensor reading
132 * command response.
133 *
134 * @param[in] sensorInfo - Dbus info related to sensor.
135 *
136 * @return Response for get sensor reading command.
137 */
138GetSensorResponse eventdata2(const Info& sensorInfo);
139
Tom Joseph295f17e2017-09-07 00:09:46 +0530140/**
141 * @brief readingAssertion is a case where the entire assertion state field
142 * serves as the sensor value.
143 *
144 * @tparam T - type of the dbus property related to sensor.
145 * @param[in] sensorInfo - Dbus info related to sensor.
146 *
147 * @return Response for get sensor reading command.
148 */
149template<typename T>
150GetSensorResponse readingAssertion(const Info& sensorInfo)
151{
152 sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
153 GetSensorResponse response {};
154 auto responseData = reinterpret_cast<GetReadingResponse*>(response.data());
155
156 auto service = ipmi::getService(bus,
157 sensorInfo.sensorInterface,
158 sensorInfo.sensorPath);
159
160 auto propValue = ipmi::getDbusProperty(
161 bus,
162 service,
163 sensorInfo.sensorPath,
164 sensorInfo.propertyInterfaces.begin()->first,
165 sensorInfo.propertyInterfaces.begin()->second.begin()->first);
166
167 setAssertionBytes(static_cast<uint16_t>(propValue.get<T>()), responseData);
168
169 return response;
170}
171
Tom Josephe05b2922017-09-07 00:43:16 +0530172/** @brief Map the Dbus info to the reading field in the Get sensor reading
173 * command response
174 *
175 * @tparam T - type of the dbus property related to sensor.
176 * @param[in] sensorInfo - Dbus info related to sensor.
177 *
178 * @return Response for get sensor reading command.
179 */
180template<typename T>
181GetSensorResponse readingData(const Info& sensorInfo)
182{
183 sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
184 GetSensorResponse response {};
185 auto responseData = reinterpret_cast<GetReadingResponse*>(response.data());
186
187 enableScanning(responseData);
188
189 auto service = ipmi::getService(bus,
190 sensorInfo.sensorInterface,
191 sensorInfo.sensorPath);
192
193 auto propValue = ipmi::getDbusProperty(
194 bus,
195 service,
196 sensorInfo.sensorPath,
197 sensorInfo.propertyInterfaces.begin()->first,
198 sensorInfo.propertyInterfaces.begin()->second.begin()->first);
199
200 auto value = static_cast<uint8_t>(
201 (propValue.get<T>() - sensorInfo.scaledOffset) /
202 (sensorInfo.coefficientM ? sensorInfo.coefficientM : 1));
203
204 setReading(value, responseData);
205
206 return response;
207}
208
Tom Joseph816e92b2017-09-06 19:23:00 +0530209} //namespace get
210
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 */
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500240template<typename T>
241ipmi_ret_t readingAssertion(const SetSensorReadingReq& cmdData,
242 const Info& sensorInfo)
243{
244 auto msg = makeDbusMsg(
245 "org.freedesktop.DBus.Properties",
246 sensorInfo.sensorPath,
247 "Set",
248 sensorInfo.sensorInterface);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500249
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500250 const auto& interface = sensorInfo.propertyInterfaces.begin();
251 msg.append(interface->first);
252 for (const auto& property : interface->second)
253 {
254 msg.append(property.first);
255 sdbusplus::message::variant<T> value =
256 (cmdData.assertOffset8_14 << 8) | cmdData.assertOffset0_7;
257 msg.append(value);
258 }
259 return updateToDbus(msg);
260}
261
Emily Shaffercc941e12017-06-14 13:06:26 -0700262/** @brief Update d-bus based on a discrete reading
263 * @param[in] cmdData - input sensor data
264 * @param[in] sensorInfo - sensor d-bus info
265 * @return an IPMI error code
266 */
267template<typename T>
268ipmi_ret_t readingData(const SetSensorReadingReq& cmdData,
269 const Info& sensorInfo)
270{
271 auto msg = makeDbusMsg(
272 "org.freedesktop.DBus.Properties",
273 sensorInfo.sensorPath,
274 "Set",
275 sensorInfo.sensorInterface);
276
277 const auto& interface = sensorInfo.propertyInterfaces.begin();
278 msg.append(interface->first);
279
280 ipmi::sensor::Multiplier m = sensorInfo.coefficientM;
281 if (0 == m)
282 {
283 m = 1; // Avoid * 0
284 }
285
286 // TODO: Refactor this into a generated function depending on the type
287 // of conversion for the value between IPMI and dbus.
288 T raw_value = (m * cmdData.reading) + sensorInfo.scaledOffset;
289
290 for (const auto& property : interface->second)
291 {
292 msg.append(property.first);
293 sdbusplus::message::variant<T> value = raw_value;
294 msg.append(value);
295 }
296 return updateToDbus(msg);
297}
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500298
299/** @brief Update d-bus based on eventdata type sensor data
300 * @param[in] cmdData - input sensor data
301 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500302 * @return a IPMI error code
303 */
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500304ipmi_ret_t eventdata(const SetSensorReadingReq& cmdData,
305 const Info& sensorInfo,
306 uint8_t data);
307
308/** @brief Update d-bus based on eventdata1 type sensor data
309 * @param[in] cmdData - input sensor data
310 * @param[in] sensorInfo - sensor d-bus info
311 * @return a IPMI error code
312 */
313inline ipmi_ret_t eventdata1(const SetSensorReadingReq& cmdData,
314 const Info& sensorInfo)
315{
316 return eventdata(cmdData, sensorInfo, cmdData.eventData1);
317}
318
319/** @brief Update d-bus based on eventdata2 type sensor data
320 * @param[in] cmdData - input sensor data
321 * @param[in] sensorInfo - sensor d-bus info
322 * @return a IPMI error code
323 */
324inline ipmi_ret_t eventdata2(const SetSensorReadingReq& cmdData,
325 const Info& sensorInfo)
326{
327 return eventdata(cmdData, sensorInfo, cmdData.eventData2);
328}
329
330/** @brief Update d-bus based on eventdata3 type sensor data
331 * @param[in] cmdData - input sensor data
332 * @param[in] sensorInfo - sensor d-bus info
333 * @return a IPMI error code
334 */
335inline ipmi_ret_t eventdata3(const SetSensorReadingReq& cmdData,
336 const Info& sensorInfo)
337{
338 return eventdata(cmdData, sensorInfo, cmdData.eventData3);
339}
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500340
341}//namespace set
342
343namespace notify
344{
345
346/** @brief Make a DBus message for a Dbus call
347 * @param[in] updateInterface - Interface name
348 * @param[in] sensorPath - Path of the sensor
349 * @param[in] command - command to be executed
350 * @param[in] sensorInterface - DBus interface of sensor
351 * @return a dbus message
352 */
353IpmiUpdateData makeDbusMsg(const std::string& updateInterface,
354 const std::string& sensorPath,
355 const std::string& command,
356 const std::string& sensorInterface);
357
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500358/** @brief Update d-bus based on assertion type sensor data
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500359 * @param[in] interfaceMap - sensor interface
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500360 * @param[in] cmdData - input sensor data
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500361 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500362 * @return a IPMI error code
363 */
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500364ipmi_ret_t assertion(const SetSensorReadingReq& cmdData,
365 const Info& sensorInfo);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500366
367}//namespace notify
Tom Joseph816e92b2017-09-06 19:23:00 +0530368
369namespace inventory
370{
371
372namespace get
373{
374
375/**
376 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
377 * reading command response.
378 *
379 * @param[in] sensorInfo - Dbus info related to sensor.
380 *
381 * @return Response for get sensor reading command.
382 */
383GetSensorResponse assertion(const Info& sensorInfo);
384
385} // namespace get
386
387} // namespace inventory
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500388}//namespace sensor
389}//namespace ipmi