blob: df0f2d1942b7be97c4709e0acb98ead05a8a78d7 [file] [log] [blame]
Deepak Kodihalli557dfb02019-05-12 13:11:17 +05301
2#include "platform.hpp"
3
George Liu456c9a22020-01-13 11:36:22 +08004#include "pdr_numeric_effecter.hpp"
George Liua2870722020-02-11 11:09:30 +08005#include "pdr_state_effecter.hpp"
George Liu0d7aca82020-03-30 15:01:36 +08006#include "platform_state_effecter.hpp"
George Liu83409572019-12-24 18:42:54 +08007#include "utils.hpp"
8
Deepak Kodihalli557dfb02019-05-12 13:11:17 +05309namespace pldm
10{
Deepak Kodihalli557dfb02019-05-12 13:11:17 +053011namespace responder
12{
Sampa Misraa2fa0702019-05-31 01:28:55 -050013namespace platform
14{
15
Deepak Kodihallic682fe22020-03-04 00:42:54 -060016using InternalFailure =
17 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
18
George Liu1ec85d42020-02-12 16:05:32 +080019static const Json empty{};
20
Zahed Hossain75330f32020-03-24 02:15:03 -050021using EventEntryMap = std::map<EventEntry, DBusInfo>;
22
23const EventEntryMap eventEntryMap = {
24 {
25 0x01010007, // SensorID for VMI Port 0 ipv4 = 7, SensorOffset for the
26 // State Set ID 15 = 1 & PLDM State Set Enumeration List = 1
27 // (Valid Configuration)
28 {"/xyz/openbmc_project/network/vmi/intf0/ipv4/addr0",
29 "xyz.openbmc_project.Object.Enable", "Enabled", "bool", true},
30 },
31 {
32 0x02010007, // SensorID for VMI Port 0 ipv4 = 7, SensorOffset for the
33 // State Set ID 15 = 1 & PLDM State Set Enumeration List = 2
34 // (Invalid Configuration)
35 {"/xyz/openbmc_project/network/vmi/intf0/ipv4/addr0",
36 "xyz.openbmc_project.Object.Enable", "Enabled", "bool", false},
37 },
38 {
39 0x01010008, // SensorID for VMI Port 1 ipv4 = 8, SensorOffset for the
40 // State Set ID 15 = 1 & PLDM State Set Enumeration List = 1
41 // (Valid Configuration)
42 {"/xyz/openbmc_project/network/vmi/intf1/ipv4/addr0",
43 "xyz.openbmc_project.Object.Enable", "Enabled", "bool", true},
44 },
45 {
46 0x02010008, // SensorID for VMI Port 1 ipv4 = 8, SensorOffset for the
47 // State Set ID 15 = 1 & PLDM State Set Enumeration List = 2
48 // (Invalid Configuration)
49 {"/xyz/openbmc_project/network/vmi/intf1/ipv4/addr0",
50 "xyz.openbmc_project.Object.Enable", "Enabled", "bool", false},
51 }};
52
George Liua2870722020-02-11 11:09:30 +080053void Handler::addDbusObjMaps(
54 uint16_t effecterId,
55 std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps> dbusObj)
George Liu1ec85d42020-02-12 16:05:32 +080056{
57 dbusObjMaps.emplace(effecterId, dbusObj);
58}
59
George Liua2870722020-02-11 11:09:30 +080060const std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps>&
George Liu1ec85d42020-02-12 16:05:32 +080061 Handler::getDbusObjMaps(uint16_t effecterId) const
62{
63 return dbusObjMaps.at(effecterId);
64}
65
Deepak Kodihallic682fe22020-03-04 00:42:54 -060066void Handler::generate(const std::string& dir, Repo& repo)
67{
68 // A map of PDR type to a lambda that handles creation of that PDR type.
69 // The lambda essentially would parse the platform specific PDR JSONs to
70 // generate the PDR structures. This function iterates through the map to
71 // invoke all lambdas, so that all PDR types can be created.
George Liua2870722020-02-11 11:09:30 +080072
73 const std::map<Type, generatePDR> generateHandlers = {
74 {PLDM_STATE_EFFECTER_PDR,
75 [this](const auto& json, RepoInterface& repo) {
76 pdr_state_effecter::generateStateEffecterPDR<Handler>(json, *this,
77 repo);
George Liu456c9a22020-01-13 11:36:22 +080078 }},
79 {PLDM_NUMERIC_EFFECTER_PDR,
80 [this](const auto& json, RepoInterface& repo) {
81 pdr_numeric_effecter::generateNumericEffecterPDR<Handler>(
82 json, *this, repo);
George Liua2870722020-02-11 11:09:30 +080083 }}};
Deepak Kodihallic682fe22020-03-04 00:42:54 -060084
85 Type pdrType{};
86 for (const auto& dirEntry : fs::directory_iterator(dir))
87 {
88 try
89 {
90 auto json = readJson(dirEntry.path().string());
91 if (!json.empty())
92 {
George Liu1ec85d42020-02-12 16:05:32 +080093 auto effecterPDRs = json.value("effecterPDRs", empty);
94 for (const auto& effecter : effecterPDRs)
95 {
96 pdrType = effecter.value("pdrType", 0);
George Liua2870722020-02-11 11:09:30 +080097 generateHandlers.at(pdrType)(effecter, repo);
George Liu1ec85d42020-02-12 16:05:32 +080098 }
Deepak Kodihallic682fe22020-03-04 00:42:54 -060099 }
100 }
101 catch (const InternalFailure& e)
102 {
103 std::cerr << "PDR config directory does not exist or empty, TYPE= "
104 << pdrType << "PATH= " << dirEntry
105 << " ERROR=" << e.what() << "\n";
106 }
107 catch (const Json::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 catch (const std::exception& e)
115 {
116 std::cerr << "Failed parsing PDR JSON file, TYPE= " << pdrType
117 << " ERROR=" << e.what() << "\n";
118 pldm::utils::reportError(
119 "xyz.openbmc_project.bmc.pldm.InternalFailure");
120 }
121 }
122}
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530123
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600124Response Handler::getPDR(const pldm_msg* request, size_t payloadLength)
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530125{
126 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_PDR_MIN_RESP_BYTES, 0);
127 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
128
129 if (payloadLength != PLDM_GET_PDR_REQ_BYTES)
130 {
George Liufb8611d2019-12-06 10:14:15 +0800131 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530132 }
133
134 uint32_t recordHandle{};
135 uint32_t dataTransferHandle{};
136 uint8_t transferOpFlag{};
137 uint16_t reqSizeBytes{};
138 uint16_t recordChangeNum{};
139
George Liufb8611d2019-12-06 10:14:15 +0800140 auto rc = decode_get_pdr_req(request, payloadLength, &recordHandle,
141 &dataTransferHandle, &transferOpFlag,
142 &reqSizeBytes, &recordChangeNum);
143 if (rc != PLDM_SUCCESS)
144 {
145 return CmdHandler::ccOnlyResponse(request, rc);
146 }
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530147
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530148 uint16_t respSizeBytes{};
149 uint8_t* recordData = nullptr;
150 try
151 {
George Liue53193f2020-02-24 09:23:26 +0800152 pdr_utils::PdrEntry e;
153 auto record = pdr::getRecordByHandle(pdrRepo, recordHandle, e);
154 if (record == NULL)
155 {
156 return CmdHandler::ccOnlyResponse(
157 request, PLDM_PLATFORM_INVALID_RECORD_HANDLE);
158 }
159
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530160 if (reqSizeBytes)
161 {
George Liue53193f2020-02-24 09:23:26 +0800162 respSizeBytes = e.size;
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530163 if (respSizeBytes > reqSizeBytes)
164 {
165 respSizeBytes = reqSizeBytes;
166 }
George Liue53193f2020-02-24 09:23:26 +0800167 recordData = e.data;
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530168 }
169 response.resize(sizeof(pldm_msg_hdr) + PLDM_GET_PDR_MIN_RESP_BYTES +
170 respSizeBytes,
171 0);
172 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
Deepak Kodihalli22b5a7d2020-03-17 23:28:41 -0500173 rc = encode_get_pdr_resp(
174 request->hdr.instance_id, PLDM_SUCCESS, e.handle.nextRecordHandle,
175 0, PLDM_START_AND_END, respSizeBytes, recordData, 0, responsePtr);
George Liufb8611d2019-12-06 10:14:15 +0800176 if (rc != PLDM_SUCCESS)
177 {
178 return ccOnlyResponse(request, rc);
179 }
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530180 }
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530181 catch (const std::exception& e)
182 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600183 std::cerr << "Error accessing PDR, HANDLE=" << recordHandle
184 << " ERROR=" << e.what() << "\n";
George Liufb8611d2019-12-06 10:14:15 +0800185 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR);
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530186 }
187 return response;
188}
189
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600190Response Handler::setStateEffecterStates(const pldm_msg* request,
191 size_t payloadLength)
Sampa Misraa2fa0702019-05-31 01:28:55 -0500192{
193 Response response(
194 sizeof(pldm_msg_hdr) + PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES, 0);
195 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
196 uint16_t effecterId;
197 uint8_t compEffecterCnt;
198 constexpr auto maxCompositeEffecterCnt = 8;
199 std::vector<set_effecter_state_field> stateField(maxCompositeEffecterCnt,
200 {0, 0});
201
202 if ((payloadLength > PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES) ||
203 (payloadLength < sizeof(effecterId) + sizeof(compEffecterCnt) +
204 sizeof(set_effecter_state_field)))
205 {
George Liufb8611d2019-12-06 10:14:15 +0800206 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
Sampa Misraa2fa0702019-05-31 01:28:55 -0500207 }
208
209 int rc = decode_set_state_effecter_states_req(request, payloadLength,
210 &effecterId, &compEffecterCnt,
211 stateField.data());
212
George Liufb8611d2019-12-06 10:14:15 +0800213 if (rc != PLDM_SUCCESS)
Sampa Misraa2fa0702019-05-31 01:28:55 -0500214 {
George Liufb8611d2019-12-06 10:14:15 +0800215 return CmdHandler::ccOnlyResponse(request, rc);
Sampa Misraa2fa0702019-05-31 01:28:55 -0500216 }
217
George Liufb8611d2019-12-06 10:14:15 +0800218 stateField.resize(compEffecterCnt);
219 const pldm::utils::DBusHandler dBusIntf;
George Liu0d7aca82020-03-30 15:01:36 +0800220 rc = platform_state_effecter::setStateEffecterStatesHandler<
221 pldm::utils::DBusHandler, Handler>(dBusIntf, *this, effecterId,
222 stateField);
George Liufb8611d2019-12-06 10:14:15 +0800223 if (rc != PLDM_SUCCESS)
224 {
225 return CmdHandler::ccOnlyResponse(request, rc);
226 }
227
228 rc = encode_set_state_effecter_states_resp(request->hdr.instance_id, rc,
229 responsePtr);
230 if (rc != PLDM_SUCCESS)
231 {
232 return ccOnlyResponse(request, rc);
233 }
234
Sampa Misraa2fa0702019-05-31 01:28:55 -0500235 return response;
236}
237
Tom Joseph56e45c52020-03-16 10:01:45 +0530238Response Handler::platformEventMessage(const pldm_msg* request,
239 size_t payloadLength)
240{
241 uint8_t formatVersion{};
242 uint8_t tid{};
243 uint8_t eventClass{};
244 size_t offset{};
245
246 auto rc = decode_platform_event_message_req(
247 request, payloadLength, &formatVersion, &tid, &eventClass, &offset);
248 if (rc != PLDM_SUCCESS)
249 {
250 return CmdHandler::ccOnlyResponse(request, rc);
251 }
252
253 try
254 {
255 const auto& handlers = eventHandlers.at(eventClass);
256 for (const auto& handler : handlers)
257 {
258 auto rc =
259 handler(request, payloadLength, formatVersion, tid, offset);
260 if (rc != PLDM_SUCCESS)
261 {
262 return CmdHandler::ccOnlyResponse(request, rc);
263 }
264 }
265 }
266 catch (const std::out_of_range& e)
267 {
268 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_DATA);
269 }
270
271 Response response(
272 sizeof(pldm_msg_hdr) + PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES, 0);
273 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
274
275 rc = encode_platform_event_message_resp(request->hdr.instance_id, rc,
276 PLDM_EVENT_NO_LOGGING, responsePtr);
277 if (rc != PLDM_SUCCESS)
278 {
279 return ccOnlyResponse(request, rc);
280 }
281
282 return response;
283}
284
285int Handler::sensorEvent(const pldm_msg* request, size_t payloadLength,
286 uint8_t /*formatVersion*/, uint8_t /*tid*/,
287 size_t eventDataOffset)
288{
289 uint16_t sensorId{};
290 uint8_t eventClass{};
291 size_t eventClassDataOffset{};
292 auto eventData =
293 reinterpret_cast<const uint8_t*>(request->payload) + eventDataOffset;
294 auto eventDataSize = payloadLength - eventDataOffset;
295
296 auto rc = decode_sensor_event_data(eventData, eventDataSize, &sensorId,
297 &eventClass, &eventClassDataOffset);
298 if (rc != PLDM_SUCCESS)
299 {
300 return rc;
301 }
302
Zahed Hossain75330f32020-03-24 02:15:03 -0500303 auto eventClassData = reinterpret_cast<const uint8_t*>(request->payload) +
304 eventDataOffset + eventClassDataOffset;
305 auto eventClassDataSize =
306 payloadLength - eventDataOffset - eventClassDataOffset;
307
Tom Joseph56e45c52020-03-16 10:01:45 +0530308 if (eventClass == PLDM_STATE_SENSOR_STATE)
309 {
310 uint8_t sensorOffset{};
311 uint8_t eventState{};
312 uint8_t previousEventState{};
313
Zahed Hossain75330f32020-03-24 02:15:03 -0500314 rc = decode_state_sensor_data(eventClassData, eventClassDataSize,
Tom Joseph56e45c52020-03-16 10:01:45 +0530315 &sensorOffset, &eventState,
316 &previousEventState);
Zahed Hossain75330f32020-03-24 02:15:03 -0500317 if (rc != PLDM_SUCCESS)
318 {
319 return PLDM_ERROR;
320 }
321
322 rc = setSensorEventData(sensorId, sensorOffset, eventState);
323
324 if (rc != PLDM_SUCCESS)
325 {
326 return PLDM_ERROR;
327 }
Tom Joseph56e45c52020-03-16 10:01:45 +0530328 }
329 else
330 {
331 return PLDM_ERROR_INVALID_DATA;
332 }
333
334 return PLDM_SUCCESS;
335}
336
Zahed Hossain75330f32020-03-24 02:15:03 -0500337int Handler::setSensorEventData(uint16_t sensorId, uint8_t sensorOffset,
338 uint8_t eventState)
339{
340 EventEntry eventEntry = ((static_cast<uint32_t>(eventState)) << 24) +
341 ((static_cast<uint32_t>(sensorOffset)) << 16) +
342 sensorId;
343 auto iter = eventEntryMap.find(eventEntry);
344 if (iter == eventEntryMap.end())
345 {
346 return PLDM_SUCCESS;
347 }
348
349 const auto& dBusInfo = iter->second;
350 try
351 {
352 pldm::utils::DBusMapping dbusMapping{
353 dBusInfo.dBusValues.objectPath, dBusInfo.dBusValues.interface,
354 dBusInfo.dBusValues.propertyName, dBusInfo.dBusValues.propertyType};
355 pldm::utils::DBusHandler().setDbusProperty(dbusMapping,
356 dBusInfo.dBusPropertyValue);
357 }
358 catch (std::exception& e)
359 {
360
361 std::cerr
362 << "Error Setting dbus property,SensorID=" << eventEntry
363 << "DBusInfo=" << dBusInfo.dBusValues.objectPath
364 << dBusInfo.dBusValues.interface << dBusInfo.dBusValues.propertyName
365 << "ERROR=" << e.what() << "\n";
366 return PLDM_ERROR;
367 }
368 return PLDM_SUCCESS;
369}
370
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500371int Handler::pldmPDRRepositoryChgEvent(const pldm_msg* request,
372 size_t payloadLength,
373 uint8_t /*formatVersion*/,
374 uint8_t /*tid*/, size_t eventDataOffset)
375{
376 uint8_t eventDataFormat{};
377 uint8_t numberOfChangeRecords{};
378 size_t dataOffset{};
379
380 auto eventData =
381 reinterpret_cast<const uint8_t*>(request->payload) + eventDataOffset;
382 auto eventDataSize = payloadLength - eventDataOffset;
383
384 auto rc = decode_pldm_pdr_repository_chg_event_data(
385 eventData, eventDataSize, &eventDataFormat, &numberOfChangeRecords,
386 &dataOffset);
387 if (rc != PLDM_SUCCESS)
388 {
389 return rc;
390 }
391
392 PDRRecordHandles pdrRecordHandles;
393 if (eventDataFormat == FORMAT_IS_PDR_HANDLES)
394 {
395 uint8_t eventDataOperation{};
396 uint8_t numberOfChangeEntries{};
397
398 auto changeRecordData = eventData + dataOffset;
399 auto changeRecordDataSize = eventDataSize - dataOffset;
400
401 while (changeRecordDataSize)
402 {
403 rc = decode_pldm_pdr_repository_change_record_data(
404 changeRecordData, changeRecordDataSize, &eventDataOperation,
405 &numberOfChangeEntries, &dataOffset);
406
407 if (rc != PLDM_SUCCESS)
408 {
409 return rc;
410 }
411
412 if (eventDataOperation == PLDM_RECORDS_ADDED)
413 {
414 rc = getPDRRecordHandles(
415 reinterpret_cast<const ChangeEntry*>(changeRecordData +
416 dataOffset),
417 changeRecordDataSize - dataOffset,
418 static_cast<size_t>(numberOfChangeEntries),
419 pdrRecordHandles);
420
421 if (rc != PLDM_SUCCESS)
422 {
423 return rc;
424 }
425 }
426
427 changeRecordData +=
428 dataOffset + (numberOfChangeEntries * sizeof(ChangeEntry));
429 changeRecordDataSize -=
430 dataOffset + (numberOfChangeEntries * sizeof(ChangeEntry));
431 }
432
433 if (hostPDRHandler && !pdrRecordHandles.empty())
434 {
435 hostPDRHandler->fetchPDR(std::move(pdrRecordHandles));
436 }
437 }
438 else
439 {
440 return PLDM_ERROR_INVALID_DATA;
441 }
442
443 return PLDM_SUCCESS;
444}
445
446int Handler::getPDRRecordHandles(const ChangeEntry* changeEntryData,
447 size_t changeEntryDataSize,
448 size_t numberOfChangeEntries,
449 PDRRecordHandles& pdrRecordHandles)
450{
451 if (numberOfChangeEntries > (changeEntryDataSize / sizeof(ChangeEntry)))
452 {
453 return PLDM_ERROR_INVALID_DATA;
454 }
455 for (size_t i = 0; i < numberOfChangeEntries; i++)
456 {
457 pdrRecordHandles.push_back(changeEntryData[i]);
458 }
459 return PLDM_SUCCESS;
460}
461
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600462} // namespace platform
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530463} // namespace responder
464} // namespace pldm