blob: eb08a8c4279a9129e9ce28b35edd00fd2d847b58 [file] [log] [blame]
Deepak Kodihalli557dfb02019-05-12 13:11:17 +05301
2#include "platform.hpp"
3
George Liua2870722020-02-11 11:09:30 +08004#include "pdr_state_effecter.hpp"
George Liu83409572019-12-24 18:42:54 +08005#include "utils.hpp"
6
Deepak Kodihalli557dfb02019-05-12 13:11:17 +05307namespace pldm
8{
Deepak Kodihalli557dfb02019-05-12 13:11:17 +05309namespace responder
10{
Sampa Misraa2fa0702019-05-31 01:28:55 -050011namespace platform
12{
13
Deepak Kodihallic682fe22020-03-04 00:42:54 -060014using InternalFailure =
15 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
16
George Liu1ec85d42020-02-12 16:05:32 +080017static const Json empty{};
18
Zahed Hossain75330f32020-03-24 02:15:03 -050019using EventEntryMap = std::map<EventEntry, DBusInfo>;
20
21const EventEntryMap eventEntryMap = {
22 {
23 0x01010007, // SensorID for VMI Port 0 ipv4 = 7, SensorOffset for the
24 // State Set ID 15 = 1 & PLDM State Set Enumeration List = 1
25 // (Valid Configuration)
26 {"/xyz/openbmc_project/network/vmi/intf0/ipv4/addr0",
27 "xyz.openbmc_project.Object.Enable", "Enabled", "bool", true},
28 },
29 {
30 0x02010007, // SensorID for VMI Port 0 ipv4 = 7, SensorOffset for the
31 // State Set ID 15 = 1 & PLDM State Set Enumeration List = 2
32 // (Invalid Configuration)
33 {"/xyz/openbmc_project/network/vmi/intf0/ipv4/addr0",
34 "xyz.openbmc_project.Object.Enable", "Enabled", "bool", false},
35 },
36 {
37 0x01010008, // SensorID for VMI Port 1 ipv4 = 8, SensorOffset for the
38 // State Set ID 15 = 1 & PLDM State Set Enumeration List = 1
39 // (Valid Configuration)
40 {"/xyz/openbmc_project/network/vmi/intf1/ipv4/addr0",
41 "xyz.openbmc_project.Object.Enable", "Enabled", "bool", true},
42 },
43 {
44 0x02010008, // SensorID for VMI Port 1 ipv4 = 8, SensorOffset for the
45 // State Set ID 15 = 1 & PLDM State Set Enumeration List = 2
46 // (Invalid Configuration)
47 {"/xyz/openbmc_project/network/vmi/intf1/ipv4/addr0",
48 "xyz.openbmc_project.Object.Enable", "Enabled", "bool", false},
49 }};
50
George Liua2870722020-02-11 11:09:30 +080051void Handler::addDbusObjMaps(
52 uint16_t effecterId,
53 std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps> dbusObj)
George Liu1ec85d42020-02-12 16:05:32 +080054{
55 dbusObjMaps.emplace(effecterId, dbusObj);
56}
57
George Liua2870722020-02-11 11:09:30 +080058const std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps>&
George Liu1ec85d42020-02-12 16:05:32 +080059 Handler::getDbusObjMaps(uint16_t effecterId) const
60{
61 return dbusObjMaps.at(effecterId);
62}
63
Deepak Kodihallic682fe22020-03-04 00:42:54 -060064void Handler::generate(const std::string& dir, Repo& repo)
65{
66 // A map of PDR type to a lambda that handles creation of that PDR type.
67 // The lambda essentially would parse the platform specific PDR JSONs to
68 // generate the PDR structures. This function iterates through the map to
69 // invoke all lambdas, so that all PDR types can be created.
George Liua2870722020-02-11 11:09:30 +080070
71 const std::map<Type, generatePDR> generateHandlers = {
72 {PLDM_STATE_EFFECTER_PDR,
73 [this](const auto& json, RepoInterface& repo) {
74 pdr_state_effecter::generateStateEffecterPDR<Handler>(json, *this,
75 repo);
76 }}};
Deepak Kodihallic682fe22020-03-04 00:42:54 -060077
78 Type pdrType{};
79 for (const auto& dirEntry : fs::directory_iterator(dir))
80 {
81 try
82 {
83 auto json = readJson(dirEntry.path().string());
84 if (!json.empty())
85 {
George Liu1ec85d42020-02-12 16:05:32 +080086 auto effecterPDRs = json.value("effecterPDRs", empty);
87 for (const auto& effecter : effecterPDRs)
88 {
89 pdrType = effecter.value("pdrType", 0);
George Liua2870722020-02-11 11:09:30 +080090 generateHandlers.at(pdrType)(effecter, repo);
George Liu1ec85d42020-02-12 16:05:32 +080091 }
Deepak Kodihallic682fe22020-03-04 00:42:54 -060092 }
93 }
94 catch (const InternalFailure& e)
95 {
96 std::cerr << "PDR config directory does not exist or empty, TYPE= "
97 << pdrType << "PATH= " << dirEntry
98 << " ERROR=" << e.what() << "\n";
99 }
100 catch (const Json::exception& e)
101 {
102 std::cerr << "Failed parsing PDR JSON file, TYPE= " << pdrType
103 << " ERROR=" << e.what() << "\n";
104 pldm::utils::reportError(
105 "xyz.openbmc_project.bmc.pldm.InternalFailure");
106 }
107 catch (const std::exception& e)
108 {
109 std::cerr << "Failed parsing PDR JSON file, TYPE= " << pdrType
110 << " ERROR=" << e.what() << "\n";
111 pldm::utils::reportError(
112 "xyz.openbmc_project.bmc.pldm.InternalFailure");
113 }
114 }
115}
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530116
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600117Response Handler::getPDR(const pldm_msg* request, size_t payloadLength)
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530118{
119 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_PDR_MIN_RESP_BYTES, 0);
120 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
121
122 if (payloadLength != PLDM_GET_PDR_REQ_BYTES)
123 {
George Liufb8611d2019-12-06 10:14:15 +0800124 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530125 }
126
127 uint32_t recordHandle{};
128 uint32_t dataTransferHandle{};
129 uint8_t transferOpFlag{};
130 uint16_t reqSizeBytes{};
131 uint16_t recordChangeNum{};
132
George Liufb8611d2019-12-06 10:14:15 +0800133 auto rc = decode_get_pdr_req(request, payloadLength, &recordHandle,
134 &dataTransferHandle, &transferOpFlag,
135 &reqSizeBytes, &recordChangeNum);
136 if (rc != PLDM_SUCCESS)
137 {
138 return CmdHandler::ccOnlyResponse(request, rc);
139 }
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530140
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530141 uint16_t respSizeBytes{};
142 uint8_t* recordData = nullptr;
143 try
144 {
George Liue53193f2020-02-24 09:23:26 +0800145 pdr_utils::PdrEntry e;
146 auto record = pdr::getRecordByHandle(pdrRepo, recordHandle, e);
147 if (record == NULL)
148 {
149 return CmdHandler::ccOnlyResponse(
150 request, PLDM_PLATFORM_INVALID_RECORD_HANDLE);
151 }
152
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530153 if (reqSizeBytes)
154 {
George Liue53193f2020-02-24 09:23:26 +0800155 respSizeBytes = e.size;
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530156 if (respSizeBytes > reqSizeBytes)
157 {
158 respSizeBytes = reqSizeBytes;
159 }
George Liue53193f2020-02-24 09:23:26 +0800160 recordData = e.data;
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530161 }
162 response.resize(sizeof(pldm_msg_hdr) + PLDM_GET_PDR_MIN_RESP_BYTES +
163 respSizeBytes,
164 0);
165 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
Deepak Kodihalli22b5a7d2020-03-17 23:28:41 -0500166 rc = encode_get_pdr_resp(
167 request->hdr.instance_id, PLDM_SUCCESS, e.handle.nextRecordHandle,
168 0, PLDM_START_AND_END, respSizeBytes, recordData, 0, responsePtr);
George Liufb8611d2019-12-06 10:14:15 +0800169 if (rc != PLDM_SUCCESS)
170 {
171 return ccOnlyResponse(request, rc);
172 }
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530173 }
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530174 catch (const std::exception& e)
175 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600176 std::cerr << "Error accessing PDR, HANDLE=" << recordHandle
177 << " ERROR=" << e.what() << "\n";
George Liufb8611d2019-12-06 10:14:15 +0800178 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR);
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530179 }
180 return response;
181}
182
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600183Response Handler::setStateEffecterStates(const pldm_msg* request,
184 size_t payloadLength)
Sampa Misraa2fa0702019-05-31 01:28:55 -0500185{
186 Response response(
187 sizeof(pldm_msg_hdr) + PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES, 0);
188 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
189 uint16_t effecterId;
190 uint8_t compEffecterCnt;
191 constexpr auto maxCompositeEffecterCnt = 8;
192 std::vector<set_effecter_state_field> stateField(maxCompositeEffecterCnt,
193 {0, 0});
194
195 if ((payloadLength > PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES) ||
196 (payloadLength < sizeof(effecterId) + sizeof(compEffecterCnt) +
197 sizeof(set_effecter_state_field)))
198 {
George Liufb8611d2019-12-06 10:14:15 +0800199 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
Sampa Misraa2fa0702019-05-31 01:28:55 -0500200 }
201
202 int rc = decode_set_state_effecter_states_req(request, payloadLength,
203 &effecterId, &compEffecterCnt,
204 stateField.data());
205
George Liufb8611d2019-12-06 10:14:15 +0800206 if (rc != PLDM_SUCCESS)
Sampa Misraa2fa0702019-05-31 01:28:55 -0500207 {
George Liufb8611d2019-12-06 10:14:15 +0800208 return CmdHandler::ccOnlyResponse(request, rc);
Sampa Misraa2fa0702019-05-31 01:28:55 -0500209 }
210
George Liufb8611d2019-12-06 10:14:15 +0800211 stateField.resize(compEffecterCnt);
212 const pldm::utils::DBusHandler dBusIntf;
213 rc = setStateEffecterStatesHandler<pldm::utils::DBusHandler>(
214 dBusIntf, effecterId, stateField);
215 if (rc != PLDM_SUCCESS)
216 {
217 return CmdHandler::ccOnlyResponse(request, rc);
218 }
219
220 rc = encode_set_state_effecter_states_resp(request->hdr.instance_id, rc,
221 responsePtr);
222 if (rc != PLDM_SUCCESS)
223 {
224 return ccOnlyResponse(request, rc);
225 }
226
Sampa Misraa2fa0702019-05-31 01:28:55 -0500227 return response;
228}
229
Tom Joseph56e45c52020-03-16 10:01:45 +0530230Response Handler::platformEventMessage(const pldm_msg* request,
231 size_t payloadLength)
232{
233 uint8_t formatVersion{};
234 uint8_t tid{};
235 uint8_t eventClass{};
236 size_t offset{};
237
238 auto rc = decode_platform_event_message_req(
239 request, payloadLength, &formatVersion, &tid, &eventClass, &offset);
240 if (rc != PLDM_SUCCESS)
241 {
242 return CmdHandler::ccOnlyResponse(request, rc);
243 }
244
245 try
246 {
247 const auto& handlers = eventHandlers.at(eventClass);
248 for (const auto& handler : handlers)
249 {
250 auto rc =
251 handler(request, payloadLength, formatVersion, tid, offset);
252 if (rc != PLDM_SUCCESS)
253 {
254 return CmdHandler::ccOnlyResponse(request, rc);
255 }
256 }
257 }
258 catch (const std::out_of_range& e)
259 {
260 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_DATA);
261 }
262
263 Response response(
264 sizeof(pldm_msg_hdr) + PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES, 0);
265 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
266
267 rc = encode_platform_event_message_resp(request->hdr.instance_id, rc,
268 PLDM_EVENT_NO_LOGGING, responsePtr);
269 if (rc != PLDM_SUCCESS)
270 {
271 return ccOnlyResponse(request, rc);
272 }
273
274 return response;
275}
276
277int Handler::sensorEvent(const pldm_msg* request, size_t payloadLength,
278 uint8_t /*formatVersion*/, uint8_t /*tid*/,
279 size_t eventDataOffset)
280{
281 uint16_t sensorId{};
282 uint8_t eventClass{};
283 size_t eventClassDataOffset{};
284 auto eventData =
285 reinterpret_cast<const uint8_t*>(request->payload) + eventDataOffset;
286 auto eventDataSize = payloadLength - eventDataOffset;
287
288 auto rc = decode_sensor_event_data(eventData, eventDataSize, &sensorId,
289 &eventClass, &eventClassDataOffset);
290 if (rc != PLDM_SUCCESS)
291 {
292 return rc;
293 }
294
Zahed Hossain75330f32020-03-24 02:15:03 -0500295 auto eventClassData = reinterpret_cast<const uint8_t*>(request->payload) +
296 eventDataOffset + eventClassDataOffset;
297 auto eventClassDataSize =
298 payloadLength - eventDataOffset - eventClassDataOffset;
299
Tom Joseph56e45c52020-03-16 10:01:45 +0530300 if (eventClass == PLDM_STATE_SENSOR_STATE)
301 {
302 uint8_t sensorOffset{};
303 uint8_t eventState{};
304 uint8_t previousEventState{};
305
Zahed Hossain75330f32020-03-24 02:15:03 -0500306 rc = decode_state_sensor_data(eventClassData, eventClassDataSize,
Tom Joseph56e45c52020-03-16 10:01:45 +0530307 &sensorOffset, &eventState,
308 &previousEventState);
Zahed Hossain75330f32020-03-24 02:15:03 -0500309 if (rc != PLDM_SUCCESS)
310 {
311 return PLDM_ERROR;
312 }
313
314 rc = setSensorEventData(sensorId, sensorOffset, eventState);
315
316 if (rc != PLDM_SUCCESS)
317 {
318 return PLDM_ERROR;
319 }
Tom Joseph56e45c52020-03-16 10:01:45 +0530320 }
321 else
322 {
323 return PLDM_ERROR_INVALID_DATA;
324 }
325
326 return PLDM_SUCCESS;
327}
328
Zahed Hossain75330f32020-03-24 02:15:03 -0500329int Handler::setSensorEventData(uint16_t sensorId, uint8_t sensorOffset,
330 uint8_t eventState)
331{
332 EventEntry eventEntry = ((static_cast<uint32_t>(eventState)) << 24) +
333 ((static_cast<uint32_t>(sensorOffset)) << 16) +
334 sensorId;
335 auto iter = eventEntryMap.find(eventEntry);
336 if (iter == eventEntryMap.end())
337 {
338 return PLDM_SUCCESS;
339 }
340
341 const auto& dBusInfo = iter->second;
342 try
343 {
344 pldm::utils::DBusMapping dbusMapping{
345 dBusInfo.dBusValues.objectPath, dBusInfo.dBusValues.interface,
346 dBusInfo.dBusValues.propertyName, dBusInfo.dBusValues.propertyType};
347 pldm::utils::DBusHandler().setDbusProperty(dbusMapping,
348 dBusInfo.dBusPropertyValue);
349 }
350 catch (std::exception& e)
351 {
352
353 std::cerr
354 << "Error Setting dbus property,SensorID=" << eventEntry
355 << "DBusInfo=" << dBusInfo.dBusValues.objectPath
356 << dBusInfo.dBusValues.interface << dBusInfo.dBusValues.propertyName
357 << "ERROR=" << e.what() << "\n";
358 return PLDM_ERROR;
359 }
360 return PLDM_SUCCESS;
361}
362
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500363int Handler::pldmPDRRepositoryChgEvent(const pldm_msg* request,
364 size_t payloadLength,
365 uint8_t /*formatVersion*/,
366 uint8_t /*tid*/, size_t eventDataOffset)
367{
368 uint8_t eventDataFormat{};
369 uint8_t numberOfChangeRecords{};
370 size_t dataOffset{};
371
372 auto eventData =
373 reinterpret_cast<const uint8_t*>(request->payload) + eventDataOffset;
374 auto eventDataSize = payloadLength - eventDataOffset;
375
376 auto rc = decode_pldm_pdr_repository_chg_event_data(
377 eventData, eventDataSize, &eventDataFormat, &numberOfChangeRecords,
378 &dataOffset);
379 if (rc != PLDM_SUCCESS)
380 {
381 return rc;
382 }
383
384 PDRRecordHandles pdrRecordHandles;
385 if (eventDataFormat == FORMAT_IS_PDR_HANDLES)
386 {
387 uint8_t eventDataOperation{};
388 uint8_t numberOfChangeEntries{};
389
390 auto changeRecordData = eventData + dataOffset;
391 auto changeRecordDataSize = eventDataSize - dataOffset;
392
393 while (changeRecordDataSize)
394 {
395 rc = decode_pldm_pdr_repository_change_record_data(
396 changeRecordData, changeRecordDataSize, &eventDataOperation,
397 &numberOfChangeEntries, &dataOffset);
398
399 if (rc != PLDM_SUCCESS)
400 {
401 return rc;
402 }
403
404 if (eventDataOperation == PLDM_RECORDS_ADDED)
405 {
406 rc = getPDRRecordHandles(
407 reinterpret_cast<const ChangeEntry*>(changeRecordData +
408 dataOffset),
409 changeRecordDataSize - dataOffset,
410 static_cast<size_t>(numberOfChangeEntries),
411 pdrRecordHandles);
412
413 if (rc != PLDM_SUCCESS)
414 {
415 return rc;
416 }
417 }
418
419 changeRecordData +=
420 dataOffset + (numberOfChangeEntries * sizeof(ChangeEntry));
421 changeRecordDataSize -=
422 dataOffset + (numberOfChangeEntries * sizeof(ChangeEntry));
423 }
424
425 if (hostPDRHandler && !pdrRecordHandles.empty())
426 {
427 hostPDRHandler->fetchPDR(std::move(pdrRecordHandles));
428 }
429 }
430 else
431 {
432 return PLDM_ERROR_INVALID_DATA;
433 }
434
435 return PLDM_SUCCESS;
436}
437
438int Handler::getPDRRecordHandles(const ChangeEntry* changeEntryData,
439 size_t changeEntryDataSize,
440 size_t numberOfChangeEntries,
441 PDRRecordHandles& pdrRecordHandles)
442{
443 if (numberOfChangeEntries > (changeEntryDataSize / sizeof(ChangeEntry)))
444 {
445 return PLDM_ERROR_INVALID_DATA;
446 }
447 for (size_t i = 0; i < numberOfChangeEntries; i++)
448 {
449 pdrRecordHandles.push_back(changeEntryData[i]);
450 }
451 return PLDM_SUCCESS;
452}
453
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600454} // namespace platform
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530455} // namespace responder
456} // namespace pldm