blob: 1b053426ec70746064a30a59db64d309398a2762 [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
52/**
53 * @brief Helper function to map the dbus info to sensor's assertion status
54 * for the get sensor reading command.
55 *
56 * @param[in] sensorInfo - Dbus info related to sensor.
57 * @param[in] path - Dbus object path.
58 * @param[in] interface - Dbus interface.
59 *
60 * @return Response for get sensor reading command.
61 */
62GetSensorResponse mapDbusToAssertion(const Info& sensorInfo,
63 const InstancePath& path,
64 const DbusInterface& interface);
65
66/**
67 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
68 * reading command response.
69 *
70 * @param[in] sensorInfo - Dbus info related to sensor.
71 *
72 * @return Response for get sensor reading command.
73 */
74GetSensorResponse assertion(const Info& sensorInfo);
75
Tom Josephe4014fc2017-09-06 23:57:36 +053076/**
77 * @brief Maps the Dbus info to the reading field in the Get sensor reading
78 * command response.
79 *
80 * @param[in] sensorInfo - Dbus info related to sensor.
81 *
82 * @return Response for get sensor reading command.
83 */
84GetSensorResponse eventdata2(const Info& sensorInfo);
85
Tom Joseph295f17e2017-09-07 00:09:46 +053086/**
87 * @brief readingAssertion is a case where the entire assertion state field
88 * serves as the sensor value.
89 *
90 * @tparam T - type of the dbus property related to sensor.
91 * @param[in] sensorInfo - Dbus info related to sensor.
92 *
93 * @return Response for get sensor reading command.
94 */
95template<typename T>
96GetSensorResponse readingAssertion(const Info& sensorInfo)
97{
98 sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
99 GetSensorResponse response {};
100 auto responseData = reinterpret_cast<GetReadingResponse*>(response.data());
101
102 auto service = ipmi::getService(bus,
103 sensorInfo.sensorInterface,
104 sensorInfo.sensorPath);
105
106 auto propValue = ipmi::getDbusProperty(
107 bus,
108 service,
109 sensorInfo.sensorPath,
110 sensorInfo.propertyInterfaces.begin()->first,
111 sensorInfo.propertyInterfaces.begin()->second.begin()->first);
112
113 setAssertionBytes(static_cast<uint16_t>(propValue.get<T>()), responseData);
114
115 return response;
116}
117
Tom Josephe05b2922017-09-07 00:43:16 +0530118/** @brief Map the Dbus info to the reading field in the Get sensor reading
119 * command response
120 *
121 * @tparam T - type of the dbus property related to sensor.
122 * @param[in] sensorInfo - Dbus info related to sensor.
123 *
124 * @return Response for get sensor reading command.
125 */
126template<typename T>
127GetSensorResponse readingData(const Info& sensorInfo)
128{
129 sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
130 GetSensorResponse response {};
131 auto responseData = reinterpret_cast<GetReadingResponse*>(response.data());
132
133 enableScanning(responseData);
134
135 auto service = ipmi::getService(bus,
136 sensorInfo.sensorInterface,
137 sensorInfo.sensorPath);
138
139 auto propValue = ipmi::getDbusProperty(
140 bus,
141 service,
142 sensorInfo.sensorPath,
143 sensorInfo.propertyInterfaces.begin()->first,
144 sensorInfo.propertyInterfaces.begin()->second.begin()->first);
145
146 auto value = static_cast<uint8_t>(
147 (propValue.get<T>() - sensorInfo.scaledOffset) /
148 (sensorInfo.coefficientM ? sensorInfo.coefficientM : 1));
149
150 setReading(value, responseData);
151
152 return response;
153}
154
Tom Joseph816e92b2017-09-06 19:23:00 +0530155} //namespace get
156
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500157namespace set
158{
159
160/** @brief Make a DBus message for a Dbus call
161 * @param[in] updateInterface - Interface name
162 * @param[in] sensorPath - Path of the sensor
163 * @param[in] command - command to be executed
164 * @param[in] sensorInterface - DBus interface of sensor
165 * @return a dbus message
166 */
167IpmiUpdateData makeDbusMsg(const std::string& updateInterface,
168 const std::string& sensorPath,
169 const std::string& command,
170 const std::string& sensorInterface);
171
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500172/** @brief Update d-bus based on assertion type sensor data
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500173 * @param[in] cmdData - input sensor data
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500174 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500175 * @return a IPMI error code
176 */
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500177ipmi_ret_t assertion(const SetSensorReadingReq& cmdData,
178 const Info& sensorInfo);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500179
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500180/** @brief Update d-bus based on a reading assertion
181 * @tparam T - type of d-bus property mapping this sensor
182 * @param[in] cmdData - input sensor data
183 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500184 * @return a IPMI error code
185 */
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500186template<typename T>
187ipmi_ret_t readingAssertion(const SetSensorReadingReq& cmdData,
188 const Info& sensorInfo)
189{
190 auto msg = makeDbusMsg(
191 "org.freedesktop.DBus.Properties",
192 sensorInfo.sensorPath,
193 "Set",
194 sensorInfo.sensorInterface);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500195
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500196 const auto& interface = sensorInfo.propertyInterfaces.begin();
197 msg.append(interface->first);
198 for (const auto& property : interface->second)
199 {
200 msg.append(property.first);
201 sdbusplus::message::variant<T> value =
202 (cmdData.assertOffset8_14 << 8) | cmdData.assertOffset0_7;
203 msg.append(value);
204 }
205 return updateToDbus(msg);
206}
207
Emily Shaffercc941e12017-06-14 13:06:26 -0700208/** @brief Update d-bus based on a discrete reading
209 * @param[in] cmdData - input sensor data
210 * @param[in] sensorInfo - sensor d-bus info
211 * @return an IPMI error code
212 */
213template<typename T>
214ipmi_ret_t readingData(const SetSensorReadingReq& cmdData,
215 const Info& sensorInfo)
216{
217 auto msg = makeDbusMsg(
218 "org.freedesktop.DBus.Properties",
219 sensorInfo.sensorPath,
220 "Set",
221 sensorInfo.sensorInterface);
222
223 const auto& interface = sensorInfo.propertyInterfaces.begin();
224 msg.append(interface->first);
225
226 ipmi::sensor::Multiplier m = sensorInfo.coefficientM;
227 if (0 == m)
228 {
229 m = 1; // Avoid * 0
230 }
231
232 // TODO: Refactor this into a generated function depending on the type
233 // of conversion for the value between IPMI and dbus.
234 T raw_value = (m * cmdData.reading) + sensorInfo.scaledOffset;
235
236 for (const auto& property : interface->second)
237 {
238 msg.append(property.first);
239 sdbusplus::message::variant<T> value = raw_value;
240 msg.append(value);
241 }
242 return updateToDbus(msg);
243}
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500244
245/** @brief Update d-bus based on eventdata type sensor data
246 * @param[in] cmdData - input sensor data
247 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500248 * @return a IPMI error code
249 */
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500250ipmi_ret_t eventdata(const SetSensorReadingReq& cmdData,
251 const Info& sensorInfo,
252 uint8_t data);
253
254/** @brief Update d-bus based on eventdata1 type sensor data
255 * @param[in] cmdData - input sensor data
256 * @param[in] sensorInfo - sensor d-bus info
257 * @return a IPMI error code
258 */
259inline ipmi_ret_t eventdata1(const SetSensorReadingReq& cmdData,
260 const Info& sensorInfo)
261{
262 return eventdata(cmdData, sensorInfo, cmdData.eventData1);
263}
264
265/** @brief Update d-bus based on eventdata2 type sensor data
266 * @param[in] cmdData - input sensor data
267 * @param[in] sensorInfo - sensor d-bus info
268 * @return a IPMI error code
269 */
270inline ipmi_ret_t eventdata2(const SetSensorReadingReq& cmdData,
271 const Info& sensorInfo)
272{
273 return eventdata(cmdData, sensorInfo, cmdData.eventData2);
274}
275
276/** @brief Update d-bus based on eventdata3 type sensor data
277 * @param[in] cmdData - input sensor data
278 * @param[in] sensorInfo - sensor d-bus info
279 * @return a IPMI error code
280 */
281inline ipmi_ret_t eventdata3(const SetSensorReadingReq& cmdData,
282 const Info& sensorInfo)
283{
284 return eventdata(cmdData, sensorInfo, cmdData.eventData3);
285}
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500286
287}//namespace set
288
289namespace notify
290{
291
292/** @brief Make a DBus message for a Dbus call
293 * @param[in] updateInterface - Interface name
294 * @param[in] sensorPath - Path of the sensor
295 * @param[in] command - command to be executed
296 * @param[in] sensorInterface - DBus interface of sensor
297 * @return a dbus message
298 */
299IpmiUpdateData makeDbusMsg(const std::string& updateInterface,
300 const std::string& sensorPath,
301 const std::string& command,
302 const std::string& sensorInterface);
303
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500304/** @brief Update d-bus based on assertion type sensor data
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500305 * @param[in] interfaceMap - sensor interface
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500306 * @param[in] cmdData - input sensor data
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500307 * @param[in] sensorInfo - sensor d-bus info
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500308 * @return a IPMI error code
309 */
Deepak Kodihalli1bb0d382017-08-12 02:01:27 -0500310ipmi_ret_t assertion(const SetSensorReadingReq& cmdData,
311 const Info& sensorInfo);
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500312
313}//namespace notify
Tom Joseph816e92b2017-09-06 19:23:00 +0530314
315namespace inventory
316{
317
318namespace get
319{
320
321/**
322 * @brief Map the Dbus info to sensor's assertion status in the Get sensor
323 * reading command response.
324 *
325 * @param[in] sensorInfo - Dbus info related to sensor.
326 *
327 * @return Response for get sensor reading command.
328 */
329GetSensorResponse assertion(const Info& sensorInfo);
330
331} // namespace get
332
333} // namespace inventory
Dhruvaraj Subhashchandrane0af7202017-07-12 06:35:20 -0500334}//namespace sensor
335}//namespace ipmi