blob: 9c32da903ad6b9cd195e1d569b5cf5ca1bbc0abe [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"
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -05004#include "types.hpp"
Tom Joseph295f17e2017-09-07 00:09:46 +05305#include "utils.hpp"
Patrick Venture0b02be92018-08-31 11:55:55 -07006
William A. Kennington III194375f2018-12-14 02:14:33 -08007#include <ipmid/api.h>
Patrick Venture586d35b2018-09-07 19:56:18 -07008
9#include <cmath>
William A. Kennington III4c008022018-10-12 17:18:14 -070010#include <sdbusplus/message/types.hpp>
Patrick Venture0b02be92018-08-31 11:55:55 -070011
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -050012namespace ipmi
13{
14namespace sensor
15{
16
William A. Kennington III4c008022018-10-12 17:18:14 -070017namespace variant_ns = sdbusplus::message::variant_ns;
18
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -050019using Assertion = uint16_t;
20using Deassertion = uint16_t;
21using AssertionSet = std::pair<Assertion, Deassertion>;
22
23using Service = std::string;
24using Path = std::string;
25using Interface = std::string;
26
27using ServicePath = std::pair<Path, Service>;
28
29using Interfaces = std::vector<Interface>;
30
31using MapperResponseType = std::map<Path, std::map<Service, Interfaces>>;
32
33/** @brief get the D-Bus service and service path
34 * @param[in] bus - The Dbus bus object
35 * @param[in] interface - interface to the service
36 * @param[in] path - interested path in the list of objects
37 * @return pair of service path and service
38 */
39ServicePath getServiceAndPath(sdbusplus::bus::bus& bus,
40 const std::string& interface,
41 const std::string& path = std::string());
42
43/** @brief Make assertion set from input data
44 * @param[in] cmdData - Input sensor data
45 * @return pair of assertion and deassertion set
46 */
47AssertionSet getAssertionSet(const SetSensorReadingReq& cmdData);
48
49/** @brief send the message to DBus
50 * @param[in] msg - message to send
51 * @return failure status in IPMI error code
52 */
Dhruvaraj Subhashchandran2a444d02017-08-07 01:45:14 -050053ipmi_ret_t updateToDbus(IpmiUpdateData& msg);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -050054
Tom Joseph816e92b2017-09-06 19:23:00 +053055namespace get
56{
57
Tom Josephb0adbcd2018-01-24 11:51:29 +053058/** @brief Populate sensor name from the D-Bus property associated with the
59 * sensor. In the example entry from the yaml, the name of the D-bus
60 * property "AttemptsLeft" is the sensor name.
61 *
62 * 0x07:
63 * sensorType: 195
64 * path: /xyz/openbmc_project/state/host0
65 * sensorReadingType: 0x6F
66 * serviceInterface: org.freedesktop.DBus.Properties
67 * readingType: readingAssertion
68 * sensorNamePattern: nameProperty
69 * interfaces:
70 * xyz.openbmc_project.Control.Boot.RebootAttempts:
71 * AttemptsLeft:
72 * Offsets:
73 * 0xFF:
74 * type: uint32_t
75 *
76 *
77 * @param[in] sensorInfo - Dbus info related to sensor.
78 *
79 * @return On success return the sensor name for the sensor.
80 */
81inline SensorName nameProperty(const Info& sensorInfo)
82{
83 return sensorInfo.propertyInterfaces.begin()->second.begin()->first;
84}
85
86/** @brief Populate sensor name from the D-Bus object associated with the
87 * sensor. If the object path is /system/chassis/motherboard/dimm0 then
88 * the leaf dimm0 is considered as the sensor name.
89 *
90 * @param[in] sensorInfo - Dbus info related to sensor.
91 *
92 * @return On success return the sensor name for the sensor.
93 */
94inline SensorName nameLeaf(const Info& sensorInfo)
95{
96 return sensorInfo.sensorPath.substr(
Patrick Venture0b02be92018-08-31 11:55:55 -070097 sensorInfo.sensorPath.find_last_of('/') + 1,
98 sensorInfo.sensorPath.length());
Tom Josephb0adbcd2018-01-24 11:51:29 +053099}
100
101/** @brief Populate sensor name from the D-Bus object associated with the
102 * sensor. If the object path is /system/chassis/motherboard/cpu0/core0
103 * then the sensor name is cpu0_core0. The leaf and the parent is put
104 * together to get the sensor name.
105 *
106 * @param[in] sensorInfo - Dbus info related to sensor.
107 *
108 * @return On success return the sensor name for the sensor.
109 */
110SensorName nameParentLeaf(const Info& sensorInfo);
111
Tom Joseph816e92b2017-09-06 19:23:00 +0530112/**
113 * @brief Helper function to map the dbus info to sensor's assertion status
114 * for the get sensor reading command.
115 *
116 * @param[in] sensorInfo - Dbus info related to sensor.
117 * @param[in] path - Dbus object path.
118 * @param[in] interface - Dbus interface.
119 *
120 * @return Response for get sensor reading command.
121 */
122GetSensorResponse mapDbusToAssertion(const Info& sensorInfo,
123 const InstancePath& path,
124 const DbusInterface& interface);
125
126/**
127 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
128 * reading command response.
129 *
130 * @param[in] sensorInfo - Dbus info related to sensor.
131 *
132 * @return Response for get sensor reading command.
133 */
134GetSensorResponse assertion(const Info& sensorInfo);
135
Tom Josephe4014fc2017-09-06 23:57:36 +0530136/**
137 * @brief Maps the Dbus info to the reading field in the Get sensor reading
138 * command response.
139 *
140 * @param[in] sensorInfo - Dbus info related to sensor.
141 *
142 * @return Response for get sensor reading command.
143 */
144GetSensorResponse eventdata2(const Info& sensorInfo);
145
Tom Joseph295f17e2017-09-07 00:09:46 +0530146/**
147 * @brief readingAssertion is a case where the entire assertion state field
148 * serves as the sensor value.
149 *
150 * @tparam T - type of the dbus property related to sensor.
151 * @param[in] sensorInfo - Dbus info related to sensor.
152 *
153 * @return Response for get sensor reading command.
154 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700155template <typename T>
Tom Joseph295f17e2017-09-07 00:09:46 +0530156GetSensorResponse readingAssertion(const Info& sensorInfo)
157{
158 sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
Patrick Venture0b02be92018-08-31 11:55:55 -0700159 GetSensorResponse response{};
Tom Joseph295f17e2017-09-07 00:09:46 +0530160 auto responseData = reinterpret_cast<GetReadingResponse*>(response.data());
161
Patrick Venture0b02be92018-08-31 11:55:55 -0700162 auto service = ipmi::getService(bus, sensorInfo.sensorInterface,
Tom Joseph295f17e2017-09-07 00:09:46 +0530163 sensorInfo.sensorPath);
164
165 auto propValue = ipmi::getDbusProperty(
Patrick Venture0b02be92018-08-31 11:55:55 -0700166 bus, service, sensorInfo.sensorPath,
167 sensorInfo.propertyInterfaces.begin()->first,
168 sensorInfo.propertyInterfaces.begin()->second.begin()->first);
Tom Joseph295f17e2017-09-07 00:09:46 +0530169
William A. Kennington III4c008022018-10-12 17:18:14 -0700170 setAssertionBytes(static_cast<uint16_t>(variant_ns::get<T>(propValue)),
171 responseData);
Tom Joseph295f17e2017-09-07 00:09:46 +0530172
173 return response;
174}
175
Tom Josephe05b2922017-09-07 00:43:16 +0530176/** @brief Map the Dbus info to the reading field in the Get sensor reading
177 * command response
178 *
179 * @tparam T - type of the dbus property related to sensor.
180 * @param[in] sensorInfo - Dbus info related to sensor.
181 *
182 * @return Response for get sensor reading command.
183 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700184template <typename T>
Tom Josephe05b2922017-09-07 00:43:16 +0530185GetSensorResponse readingData(const Info& sensorInfo)
186{
187 sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
Patrick Venture0b02be92018-08-31 11:55:55 -0700188 GetSensorResponse response{};
Tom Josephe05b2922017-09-07 00:43:16 +0530189 auto responseData = reinterpret_cast<GetReadingResponse*>(response.data());
190
191 enableScanning(responseData);
192
Patrick Venture0b02be92018-08-31 11:55:55 -0700193 auto service = ipmi::getService(bus, sensorInfo.sensorInterface,
Tom Josephe05b2922017-09-07 00:43:16 +0530194 sensorInfo.sensorPath);
195
196 auto propValue = ipmi::getDbusProperty(
Patrick Venture0b02be92018-08-31 11:55:55 -0700197 bus, service, sensorInfo.sensorPath,
198 sensorInfo.propertyInterfaces.begin()->first,
199 sensorInfo.propertyInterfaces.begin()->second.begin()->first);
Tom Josephe05b2922017-09-07 00:43:16 +0530200
William A. Kennington III4c008022018-10-12 17:18:14 -0700201 double value = variant_ns::get<T>(propValue) *
Patrick Venture586d35b2018-09-07 19:56:18 -0700202 std::pow(10, sensorInfo.scale - sensorInfo.exponentR);
Tom Josephe05b2922017-09-07 00:43:16 +0530203
Patrick Venture0b02be92018-08-31 11:55:55 -0700204 auto rawData = static_cast<uint8_t>((value - sensorInfo.scaledOffset) /
205 sensorInfo.coefficientM);
Tom Joseph13b87a32018-02-16 09:37:43 +0530206
207 setReading(rawData, responseData);
Tom Josephe05b2922017-09-07 00:43:16 +0530208
209 return response;
210}
211
Patrick Venture0b02be92018-08-31 11:55:55 -0700212} // namespace get
Tom Joseph816e92b2017-09-06 19:23:00 +0530213
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 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700243template <typename T>
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500244ipmi_ret_t readingAssertion(const SetSensorReadingReq& cmdData,
245 const Info& sensorInfo)
246{
Patrick Venture0b02be92018-08-31 11:55:55 -0700247 auto msg =
248 makeDbusMsg("org.freedesktop.DBus.Properties", sensorInfo.sensorPath,
249 "Set", sensorInfo.sensorInterface);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500250
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500251 const auto& interface = sensorInfo.propertyInterfaces.begin();
252 msg.append(interface->first);
253 for (const auto& property : interface->second)
254 {
255 msg.append(property.first);
256 sdbusplus::message::variant<T> value =
257 (cmdData.assertOffset8_14 << 8) | cmdData.assertOffset0_7;
258 msg.append(value);
259 }
260 return updateToDbus(msg);
261}
262
Emily Shaffercc941e12017-06-14 13:06:26 -0700263/** @brief Update d-bus based on a discrete reading
264 * @param[in] cmdData - input sensor data
265 * @param[in] sensorInfo - sensor d-bus info
266 * @return an IPMI error code
267 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700268template <typename T>
Emily Shaffercc941e12017-06-14 13:06:26 -0700269ipmi_ret_t readingData(const SetSensorReadingReq& cmdData,
270 const Info& sensorInfo)
271{
Patrick Venture0b02be92018-08-31 11:55:55 -0700272 T raw_value =
273 (sensorInfo.coefficientM * cmdData.reading) + sensorInfo.scaledOffset;
Tom Joseph22102152018-03-02 18:46:39 +0530274
Patrick Venture586d35b2018-09-07 19:56:18 -0700275 raw_value *= std::pow(10, sensorInfo.exponentR - sensorInfo.scale);
Tom Joseph22102152018-03-02 18:46:39 +0530276
Patrick Venture0b02be92018-08-31 11:55:55 -0700277 auto msg =
278 makeDbusMsg("org.freedesktop.DBus.Properties", sensorInfo.sensorPath,
279 "Set", sensorInfo.sensorInterface);
Emily Shaffercc941e12017-06-14 13:06:26 -0700280
281 const auto& interface = sensorInfo.propertyInterfaces.begin();
282 msg.append(interface->first);
283
Emily Shaffercc941e12017-06-14 13:06:26 -0700284 for (const auto& property : interface->second)
285 {
286 msg.append(property.first);
287 sdbusplus::message::variant<T> value = raw_value;
288 msg.append(value);
289 }
290 return updateToDbus(msg);
291}
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500292
293/** @brief Update d-bus based on eventdata type sensor data
294 * @param[in] cmdData - input sensor data
295 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500296 * @return a IPMI error code
297 */
Patrick Venture0b02be92018-08-31 11:55:55 -0700298ipmi_ret_t eventdata(const SetSensorReadingReq& cmdData, const Info& sensorInfo,
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500299 uint8_t data);
300
301/** @brief Update d-bus based on eventdata1 type sensor data
302 * @param[in] cmdData - input sensor data
303 * @param[in] sensorInfo - sensor d-bus info
304 * @return a IPMI error code
305 */
306inline ipmi_ret_t eventdata1(const SetSensorReadingReq& cmdData,
307 const Info& sensorInfo)
308{
309 return eventdata(cmdData, sensorInfo, cmdData.eventData1);
310}
311
312/** @brief Update d-bus based on eventdata2 type sensor data
313 * @param[in] cmdData - input sensor data
314 * @param[in] sensorInfo - sensor d-bus info
315 * @return a IPMI error code
316 */
317inline ipmi_ret_t eventdata2(const SetSensorReadingReq& cmdData,
318 const Info& sensorInfo)
319{
320 return eventdata(cmdData, sensorInfo, cmdData.eventData2);
321}
322
323/** @brief Update d-bus based on eventdata3 type sensor data
324 * @param[in] cmdData - input sensor data
325 * @param[in] sensorInfo - sensor d-bus info
326 * @return a IPMI error code
327 */
328inline ipmi_ret_t eventdata3(const SetSensorReadingReq& cmdData,
329 const Info& sensorInfo)
330{
331 return eventdata(cmdData, sensorInfo, cmdData.eventData3);
332}
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500333
Patrick Venture0b02be92018-08-31 11:55:55 -0700334} // namespace set
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500335
336namespace notify
337{
338
339/** @brief Make a DBus message for a Dbus call
340 * @param[in] updateInterface - Interface name
341 * @param[in] sensorPath - Path of the sensor
342 * @param[in] command - command to be executed
343 * @param[in] sensorInterface - DBus interface of sensor
344 * @return a dbus message
345 */
346IpmiUpdateData makeDbusMsg(const std::string& updateInterface,
347 const std::string& sensorPath,
348 const std::string& command,
349 const std::string& sensorInterface);
350
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500351/** @brief Update d-bus based on assertion type sensor data
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500352 * @param[in] interfaceMap - sensor interface
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500353 * @param[in] cmdData - input sensor data
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500354 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500355 * @return a IPMI error code
356 */
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500357ipmi_ret_t assertion(const SetSensorReadingReq& cmdData,
358 const Info& sensorInfo);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500359
Patrick Venture0b02be92018-08-31 11:55:55 -0700360} // namespace notify
Tom Joseph816e92b2017-09-06 19:23:00 +0530361
362namespace inventory
363{
364
365namespace get
366{
367
368/**
369 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
370 * reading command response.
371 *
372 * @param[in] sensorInfo - Dbus info related to sensor.
373 *
374 * @return Response for get sensor reading command.
375 */
376GetSensorResponse assertion(const Info& sensorInfo);
377
378} // namespace get
379
380} // namespace inventory
Patrick Venture0b02be92018-08-31 11:55:55 -0700381} // namespace sensor
382} // namespace ipmi