blob: 61d09ad061f5ecb2369f6d86bb72faadb1962418 [file] [log] [blame]
Deepak Kodihalli557dfb02019-05-12 13:11:17 +05301
2#include "platform.hpp"
3
Deepak Kodihallid130e1a2020-06-17 05:55:32 -05004#include "common/utils.hpp"
Tom Josephc4959c32020-04-20 19:50:16 +05305#include "event_parser.hpp"
Sampa Misra12afe112020-05-25 11:40:44 -05006#include "pdr.hpp"
George Liu456c9a22020-01-13 11:36:22 +08007#include "pdr_numeric_effecter.hpp"
George Liua2870722020-02-11 11:09:30 +08008#include "pdr_state_effecter.hpp"
George Liuadbe1722020-05-09 19:20:19 +08009#include "pdr_state_sensor.hpp"
George Liueccb0c52020-01-14 11:09:56 +080010#include "platform_numeric_effecter.hpp"
George Liu0d7aca82020-03-30 15:01:36 +080011#include "platform_state_effecter.hpp"
George Liu83409572019-12-24 18:42:54 +080012
Deepak Kodihalli557dfb02019-05-12 13:11:17 +053013namespace pldm
14{
Deepak Kodihalli557dfb02019-05-12 13:11:17 +053015namespace responder
16{
Sampa Misraa2fa0702019-05-31 01:28:55 -050017namespace platform
18{
19
Deepak Kodihallic682fe22020-03-04 00:42:54 -060020using InternalFailure =
21 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
22
George Liu1ec85d42020-02-12 16:05:32 +080023static const Json empty{};
24
Zahed Hossain75330f32020-03-24 02:15:03 -050025using EventEntryMap = std::map<EventEntry, DBusInfo>;
26
27const EventEntryMap eventEntryMap = {
28 {
29 0x01010007, // SensorID for VMI Port 0 ipv4 = 7, SensorOffset for the
30 // State Set ID 15 = 1 & PLDM State Set Enumeration List = 1
31 // (Valid Configuration)
Tom Joseph15bff552020-06-30 15:57:08 +053032 {"/xyz/openbmc_project/network/hypervisor/eth0/ipv4/addr0",
Zahed Hossain75330f32020-03-24 02:15:03 -050033 "xyz.openbmc_project.Object.Enable", "Enabled", "bool", true},
34 },
35 {
36 0x02010007, // SensorID for VMI Port 0 ipv4 = 7, SensorOffset for the
37 // State Set ID 15 = 1 & PLDM State Set Enumeration List = 2
38 // (Invalid Configuration)
Tom Joseph15bff552020-06-30 15:57:08 +053039 {"/xyz/openbmc_project/network/hypervisor/eth0/ipv4/addr0",
Zahed Hossain75330f32020-03-24 02:15:03 -050040 "xyz.openbmc_project.Object.Enable", "Enabled", "bool", false},
41 },
42 {
43 0x01010008, // SensorID for VMI Port 1 ipv4 = 8, SensorOffset for the
44 // State Set ID 15 = 1 & PLDM State Set Enumeration List = 1
45 // (Valid Configuration)
Tom Joseph15bff552020-06-30 15:57:08 +053046 {"/xyz/openbmc_project/network/hypervisor/eth1/ipv4/addr0",
Zahed Hossain75330f32020-03-24 02:15:03 -050047 "xyz.openbmc_project.Object.Enable", "Enabled", "bool", true},
48 },
49 {
50 0x02010008, // SensorID for VMI Port 1 ipv4 = 8, SensorOffset for the
51 // State Set ID 15 = 1 & PLDM State Set Enumeration List = 2
52 // (Invalid Configuration)
Tom Joseph15bff552020-06-30 15:57:08 +053053 {"/xyz/openbmc_project/network/hypervisor/eth1/ipv4/addr0",
Zahed Hossain75330f32020-03-24 02:15:03 -050054 "xyz.openbmc_project.Object.Enable", "Enabled", "bool", false},
55 }};
56
George Liua2870722020-02-11 11:09:30 +080057void Handler::addDbusObjMaps(
George Liuadbe1722020-05-09 19:20:19 +080058 uint16_t id,
59 std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps> dbusObj,
60 TypeId typeId)
George Liu1ec85d42020-02-12 16:05:32 +080061{
George Liuadbe1722020-05-09 19:20:19 +080062 if (typeId == TypeId::PLDM_SENSOR_ID)
63 {
64 sensorDbusObjMaps.emplace(id, dbusObj);
65 }
66 else
67 {
68 effecterDbusObjMaps.emplace(id, dbusObj);
69 }
George Liu1ec85d42020-02-12 16:05:32 +080070}
71
George Liua2870722020-02-11 11:09:30 +080072const std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps>&
George Liuadbe1722020-05-09 19:20:19 +080073 Handler::getDbusObjMaps(uint16_t id, TypeId typeId) const
George Liu1ec85d42020-02-12 16:05:32 +080074{
George Liuadbe1722020-05-09 19:20:19 +080075 if (typeId == TypeId::PLDM_SENSOR_ID)
76 {
77 return sensorDbusObjMaps.at(id);
78 }
79 else
80 {
81 return effecterDbusObjMaps.at(id);
82 }
George Liu1ec85d42020-02-12 16:05:32 +080083}
84
George Liu36e81352020-07-01 14:40:30 +080085void Handler::generate(const pldm::utils::DBusHandler& dBusIntf,
86 const std::string& dir, Repo& repo)
Deepak Kodihallic682fe22020-03-04 00:42:54 -060087{
Deepak Kodihallic6e49c42020-07-01 03:39:27 -050088 if (!fs::exists(dir))
89 {
90 return;
91 }
92
Deepak Kodihallic682fe22020-03-04 00:42:54 -060093 // A map of PDR type to a lambda that handles creation of that PDR type.
94 // The lambda essentially would parse the platform specific PDR JSONs to
95 // generate the PDR structures. This function iterates through the map to
96 // invoke all lambdas, so that all PDR types can be created.
George Liua2870722020-02-11 11:09:30 +080097
98 const std::map<Type, generatePDR> generateHandlers = {
99 {PLDM_STATE_EFFECTER_PDR,
George Liu36e81352020-07-01 14:40:30 +0800100 [this](const DBusHandler& dBusIntf, const auto& json,
101 RepoInterface& repo) {
102 pdr_state_effecter::generateStateEffecterPDR<
103 pldm::utils::DBusHandler, Handler>(dBusIntf, json, *this,
104 repo);
George Liu456c9a22020-01-13 11:36:22 +0800105 }},
106 {PLDM_NUMERIC_EFFECTER_PDR,
George Liu36e81352020-07-01 14:40:30 +0800107 [this](const DBusHandler& dBusIntf, const auto& json,
108 RepoInterface& repo) {
109 pdr_numeric_effecter::generateNumericEffecterPDR<
110 pldm::utils::DBusHandler, Handler>(dBusIntf, json, *this,
111 repo);
George Liuadbe1722020-05-09 19:20:19 +0800112 }},
113 {PLDM_STATE_SENSOR_PDR, [this](const DBusHandler& dBusIntf,
114 const auto& json, RepoInterface& repo) {
115 pdr_state_sensor::generateStateSensorPDR<pldm::utils::DBusHandler,
116 Handler>(dBusIntf, json,
117 *this, repo);
George Liua2870722020-02-11 11:09:30 +0800118 }}};
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600119
120 Type pdrType{};
121 for (const auto& dirEntry : fs::directory_iterator(dir))
122 {
123 try
124 {
125 auto json = readJson(dirEntry.path().string());
126 if (!json.empty())
127 {
George Liu1ec85d42020-02-12 16:05:32 +0800128 auto effecterPDRs = json.value("effecterPDRs", empty);
129 for (const auto& effecter : effecterPDRs)
130 {
131 pdrType = effecter.value("pdrType", 0);
George Liu36e81352020-07-01 14:40:30 +0800132 generateHandlers.at(pdrType)(dBusIntf, effecter, repo);
George Liu1ec85d42020-02-12 16:05:32 +0800133 }
George Liuadbe1722020-05-09 19:20:19 +0800134
135 auto sensorPDRs = json.value("sensorPDRs", empty);
136 for (const auto& sensor : sensorPDRs)
137 {
138 pdrType = sensor.value("pdrType", 0);
139 generateHandlers.at(pdrType)(dBusIntf, sensor, repo);
140 }
Deepak Kodihallic682fe22020-03-04 00:42:54 -0600141 }
142 }
143 catch (const InternalFailure& e)
144 {
145 std::cerr << "PDR config directory does not exist or empty, TYPE= "
146 << pdrType << "PATH= " << dirEntry
147 << " ERROR=" << e.what() << "\n";
148 }
149 catch (const Json::exception& e)
150 {
151 std::cerr << "Failed parsing PDR JSON file, TYPE= " << pdrType
152 << " ERROR=" << e.what() << "\n";
153 pldm::utils::reportError(
154 "xyz.openbmc_project.bmc.pldm.InternalFailure");
155 }
156 catch (const std::exception& e)
157 {
158 std::cerr << "Failed parsing PDR JSON file, TYPE= " << pdrType
159 << " ERROR=" << e.what() << "\n";
160 pldm::utils::reportError(
161 "xyz.openbmc_project.bmc.pldm.InternalFailure");
162 }
163 }
164}
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530165
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600166Response Handler::getPDR(const pldm_msg* request, size_t payloadLength)
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530167{
Deepak Kodihallib5c227e2020-07-13 06:58:34 -0500168 if (!pdrCreated)
169 {
Sampa Misra12afe112020-05-25 11:40:44 -0500170 generateTerminusLocatorPDR(pdrRepo);
Deepak Kodihallib5c227e2020-07-13 06:58:34 -0500171 generate(*dBusIntf, pdrJsonsDir, pdrRepo);
172 pdrCreated = true;
173 }
174
Tom Joseph33e9c7e2020-06-11 22:09:52 +0530175 // Build FRU table if not built, since entity association PDR's are built
176 // when the FRU table is constructed.
177 if (fruHandler)
178 {
179 fruHandler->buildFRUTable();
180 }
181
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530182 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_PDR_MIN_RESP_BYTES, 0);
183 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
184
185 if (payloadLength != PLDM_GET_PDR_REQ_BYTES)
186 {
George Liufb8611d2019-12-06 10:14:15 +0800187 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530188 }
189
190 uint32_t recordHandle{};
191 uint32_t dataTransferHandle{};
192 uint8_t transferOpFlag{};
193 uint16_t reqSizeBytes{};
194 uint16_t recordChangeNum{};
195
George Liufb8611d2019-12-06 10:14:15 +0800196 auto rc = decode_get_pdr_req(request, payloadLength, &recordHandle,
197 &dataTransferHandle, &transferOpFlag,
198 &reqSizeBytes, &recordChangeNum);
199 if (rc != PLDM_SUCCESS)
200 {
201 return CmdHandler::ccOnlyResponse(request, rc);
202 }
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530203
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530204 uint16_t respSizeBytes{};
205 uint8_t* recordData = nullptr;
206 try
207 {
George Liue53193f2020-02-24 09:23:26 +0800208 pdr_utils::PdrEntry e;
209 auto record = pdr::getRecordByHandle(pdrRepo, recordHandle, e);
210 if (record == NULL)
211 {
212 return CmdHandler::ccOnlyResponse(
213 request, PLDM_PLATFORM_INVALID_RECORD_HANDLE);
214 }
215
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530216 if (reqSizeBytes)
217 {
George Liue53193f2020-02-24 09:23:26 +0800218 respSizeBytes = e.size;
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530219 if (respSizeBytes > reqSizeBytes)
220 {
221 respSizeBytes = reqSizeBytes;
222 }
George Liue53193f2020-02-24 09:23:26 +0800223 recordData = e.data;
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530224 }
225 response.resize(sizeof(pldm_msg_hdr) + PLDM_GET_PDR_MIN_RESP_BYTES +
226 respSizeBytes,
227 0);
228 responsePtr = reinterpret_cast<pldm_msg*>(response.data());
Deepak Kodihalli22b5a7d2020-03-17 23:28:41 -0500229 rc = encode_get_pdr_resp(
230 request->hdr.instance_id, PLDM_SUCCESS, e.handle.nextRecordHandle,
231 0, PLDM_START_AND_END, respSizeBytes, recordData, 0, responsePtr);
George Liufb8611d2019-12-06 10:14:15 +0800232 if (rc != PLDM_SUCCESS)
233 {
234 return ccOnlyResponse(request, rc);
235 }
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530236 }
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530237 catch (const std::exception& e)
238 {
Sampa Misraaa8ae722019-12-12 03:20:40 -0600239 std::cerr << "Error accessing PDR, HANDLE=" << recordHandle
240 << " ERROR=" << e.what() << "\n";
George Liufb8611d2019-12-06 10:14:15 +0800241 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR);
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530242 }
243 return response;
244}
245
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600246Response Handler::setStateEffecterStates(const pldm_msg* request,
247 size_t payloadLength)
Sampa Misraa2fa0702019-05-31 01:28:55 -0500248{
249 Response response(
250 sizeof(pldm_msg_hdr) + PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES, 0);
251 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
252 uint16_t effecterId;
253 uint8_t compEffecterCnt;
254 constexpr auto maxCompositeEffecterCnt = 8;
255 std::vector<set_effecter_state_field> stateField(maxCompositeEffecterCnt,
256 {0, 0});
257
258 if ((payloadLength > PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES) ||
259 (payloadLength < sizeof(effecterId) + sizeof(compEffecterCnt) +
260 sizeof(set_effecter_state_field)))
261 {
George Liufb8611d2019-12-06 10:14:15 +0800262 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
Sampa Misraa2fa0702019-05-31 01:28:55 -0500263 }
264
265 int rc = decode_set_state_effecter_states_req(request, payloadLength,
266 &effecterId, &compEffecterCnt,
267 stateField.data());
268
George Liufb8611d2019-12-06 10:14:15 +0800269 if (rc != PLDM_SUCCESS)
Sampa Misraa2fa0702019-05-31 01:28:55 -0500270 {
George Liufb8611d2019-12-06 10:14:15 +0800271 return CmdHandler::ccOnlyResponse(request, rc);
Sampa Misraa2fa0702019-05-31 01:28:55 -0500272 }
273
George Liufb8611d2019-12-06 10:14:15 +0800274 stateField.resize(compEffecterCnt);
275 const pldm::utils::DBusHandler dBusIntf;
George Liu0d7aca82020-03-30 15:01:36 +0800276 rc = platform_state_effecter::setStateEffecterStatesHandler<
277 pldm::utils::DBusHandler, Handler>(dBusIntf, *this, effecterId,
278 stateField);
George Liufb8611d2019-12-06 10:14:15 +0800279 if (rc != PLDM_SUCCESS)
280 {
281 return CmdHandler::ccOnlyResponse(request, rc);
282 }
283
284 rc = encode_set_state_effecter_states_resp(request->hdr.instance_id, rc,
285 responsePtr);
286 if (rc != PLDM_SUCCESS)
287 {
288 return ccOnlyResponse(request, rc);
289 }
290
Sampa Misraa2fa0702019-05-31 01:28:55 -0500291 return response;
292}
293
Tom Joseph56e45c52020-03-16 10:01:45 +0530294Response Handler::platformEventMessage(const pldm_msg* request,
295 size_t payloadLength)
296{
297 uint8_t formatVersion{};
298 uint8_t tid{};
299 uint8_t eventClass{};
300 size_t offset{};
301
302 auto rc = decode_platform_event_message_req(
303 request, payloadLength, &formatVersion, &tid, &eventClass, &offset);
304 if (rc != PLDM_SUCCESS)
305 {
306 return CmdHandler::ccOnlyResponse(request, rc);
307 }
308
309 try
310 {
311 const auto& handlers = eventHandlers.at(eventClass);
312 for (const auto& handler : handlers)
313 {
314 auto rc =
315 handler(request, payloadLength, formatVersion, tid, offset);
316 if (rc != PLDM_SUCCESS)
317 {
318 return CmdHandler::ccOnlyResponse(request, rc);
319 }
320 }
321 }
322 catch (const std::out_of_range& e)
323 {
324 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_DATA);
325 }
326
327 Response response(
328 sizeof(pldm_msg_hdr) + PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES, 0);
329 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data());
330
331 rc = encode_platform_event_message_resp(request->hdr.instance_id, rc,
332 PLDM_EVENT_NO_LOGGING, responsePtr);
333 if (rc != PLDM_SUCCESS)
334 {
335 return ccOnlyResponse(request, rc);
336 }
337
338 return response;
339}
340
341int Handler::sensorEvent(const pldm_msg* request, size_t payloadLength,
Tom Josephc4959c32020-04-20 19:50:16 +0530342 uint8_t /*formatVersion*/, uint8_t tid,
Tom Joseph56e45c52020-03-16 10:01:45 +0530343 size_t eventDataOffset)
344{
345 uint16_t sensorId{};
346 uint8_t eventClass{};
347 size_t eventClassDataOffset{};
348 auto eventData =
349 reinterpret_cast<const uint8_t*>(request->payload) + eventDataOffset;
350 auto eventDataSize = payloadLength - eventDataOffset;
351
352 auto rc = decode_sensor_event_data(eventData, eventDataSize, &sensorId,
353 &eventClass, &eventClassDataOffset);
354 if (rc != PLDM_SUCCESS)
355 {
356 return rc;
357 }
358
Zahed Hossain75330f32020-03-24 02:15:03 -0500359 auto eventClassData = reinterpret_cast<const uint8_t*>(request->payload) +
360 eventDataOffset + eventClassDataOffset;
361 auto eventClassDataSize =
362 payloadLength - eventDataOffset - eventClassDataOffset;
363
Tom Joseph56e45c52020-03-16 10:01:45 +0530364 if (eventClass == PLDM_STATE_SENSOR_STATE)
365 {
366 uint8_t sensorOffset{};
367 uint8_t eventState{};
368 uint8_t previousEventState{};
369
Zahed Hossain75330f32020-03-24 02:15:03 -0500370 rc = decode_state_sensor_data(eventClassData, eventClassDataSize,
Tom Joseph56e45c52020-03-16 10:01:45 +0530371 &sensorOffset, &eventState,
372 &previousEventState);
Zahed Hossain75330f32020-03-24 02:15:03 -0500373 if (rc != PLDM_SUCCESS)
374 {
375 return PLDM_ERROR;
376 }
377
Chicago Duanfe4d88b2020-06-12 16:44:13 +0800378 // Emitting state sensor event signal
379 emitStateSensorEventSignal(tid, sensorId, sensorOffset, eventState,
380 previousEventState);
381
Tom Josephc4959c32020-04-20 19:50:16 +0530382 // Handle PLDM events for which PDR is not available, setSensorEventData
383 // will return PLDM_ERROR_INVALID_DATA if the sensorID is not found in
384 // the hardcoded sensor list.
Zahed Hossain75330f32020-03-24 02:15:03 -0500385 rc = setSensorEventData(sensorId, sensorOffset, eventState);
Tom Josephc4959c32020-04-20 19:50:16 +0530386 if (rc != PLDM_ERROR_INVALID_DATA)
Zahed Hossain75330f32020-03-24 02:15:03 -0500387 {
Tom Josephc4959c32020-04-20 19:50:16 +0530388 return rc;
389 }
390
391 // If there are no HOST PDR's, there is no further action
392 if (hostPDRHandler == NULL)
393 {
394 return PLDM_SUCCESS;
395 }
396
397 // Handle PLDM events for which PDR is available
398 SensorEntry sensorEntry{tid, sensorId};
399 try
400 {
401 const auto& [entityInfo, compositeSensorStates] =
402 hostPDRHandler->lookupSensorInfo(sensorEntry);
403 if (sensorOffset >= compositeSensorStates.size())
404 {
405 return PLDM_ERROR_INVALID_DATA;
406 }
407
408 const auto& possibleStates = compositeSensorStates[sensorOffset];
409 if (possibleStates.find(eventState) == possibleStates.end())
410 {
411 return PLDM_ERROR_INVALID_DATA;
412 }
413
414 const auto& [containerId, entityType, entityInstance] = entityInfo;
415 events::StateSensorEntry stateSensorEntry{
416 containerId, entityType, entityInstance, sensorOffset};
417 return stateSensorHandler.eventAction(stateSensorEntry, eventState);
418 }
419 // If there is no mapping for events return PLDM_SUCCESS
420 catch (const std::out_of_range& e)
421 {
422 return PLDM_SUCCESS;
Zahed Hossain75330f32020-03-24 02:15:03 -0500423 }
Tom Joseph56e45c52020-03-16 10:01:45 +0530424 }
425 else
426 {
427 return PLDM_ERROR_INVALID_DATA;
428 }
429
430 return PLDM_SUCCESS;
431}
432
Zahed Hossain75330f32020-03-24 02:15:03 -0500433int Handler::setSensorEventData(uint16_t sensorId, uint8_t sensorOffset,
434 uint8_t eventState)
435{
436 EventEntry eventEntry = ((static_cast<uint32_t>(eventState)) << 24) +
437 ((static_cast<uint32_t>(sensorOffset)) << 16) +
438 sensorId;
439 auto iter = eventEntryMap.find(eventEntry);
440 if (iter == eventEntryMap.end())
441 {
Tom Josephc4959c32020-04-20 19:50:16 +0530442 return PLDM_ERROR_INVALID_DATA;
Zahed Hossain75330f32020-03-24 02:15:03 -0500443 }
444
445 const auto& dBusInfo = iter->second;
446 try
447 {
448 pldm::utils::DBusMapping dbusMapping{
449 dBusInfo.dBusValues.objectPath, dBusInfo.dBusValues.interface,
450 dBusInfo.dBusValues.propertyName, dBusInfo.dBusValues.propertyType};
451 pldm::utils::DBusHandler().setDbusProperty(dbusMapping,
452 dBusInfo.dBusPropertyValue);
453 }
454 catch (std::exception& e)
455 {
Zahed Hossain75330f32020-03-24 02:15:03 -0500456 std::cerr
457 << "Error Setting dbus property,SensorID=" << eventEntry
458 << "DBusInfo=" << dBusInfo.dBusValues.objectPath
459 << dBusInfo.dBusValues.interface << dBusInfo.dBusValues.propertyName
460 << "ERROR=" << e.what() << "\n";
461 return PLDM_ERROR;
462 }
463 return PLDM_SUCCESS;
464}
465
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500466int Handler::pldmPDRRepositoryChgEvent(const pldm_msg* request,
467 size_t payloadLength,
468 uint8_t /*formatVersion*/,
469 uint8_t /*tid*/, size_t eventDataOffset)
470{
471 uint8_t eventDataFormat{};
472 uint8_t numberOfChangeRecords{};
473 size_t dataOffset{};
474
475 auto eventData =
476 reinterpret_cast<const uint8_t*>(request->payload) + eventDataOffset;
477 auto eventDataSize = payloadLength - eventDataOffset;
478
479 auto rc = decode_pldm_pdr_repository_chg_event_data(
480 eventData, eventDataSize, &eventDataFormat, &numberOfChangeRecords,
481 &dataOffset);
482 if (rc != PLDM_SUCCESS)
483 {
484 return rc;
485 }
486
487 PDRRecordHandles pdrRecordHandles;
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500488
489 if (eventDataFormat == FORMAT_IS_PDR_TYPES)
490 {
491 return PLDM_ERROR_INVALID_DATA;
492 }
493
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500494 if (eventDataFormat == FORMAT_IS_PDR_HANDLES)
495 {
496 uint8_t eventDataOperation{};
497 uint8_t numberOfChangeEntries{};
498
499 auto changeRecordData = eventData + dataOffset;
500 auto changeRecordDataSize = eventDataSize - dataOffset;
501
502 while (changeRecordDataSize)
503 {
504 rc = decode_pldm_pdr_repository_change_record_data(
505 changeRecordData, changeRecordDataSize, &eventDataOperation,
506 &numberOfChangeEntries, &dataOffset);
507
508 if (rc != PLDM_SUCCESS)
509 {
510 return rc;
511 }
512
513 if (eventDataOperation == PLDM_RECORDS_ADDED)
514 {
515 rc = getPDRRecordHandles(
516 reinterpret_cast<const ChangeEntry*>(changeRecordData +
517 dataOffset),
518 changeRecordDataSize - dataOffset,
519 static_cast<size_t>(numberOfChangeEntries),
520 pdrRecordHandles);
521
522 if (rc != PLDM_SUCCESS)
523 {
524 return rc;
525 }
526 }
527
528 changeRecordData +=
529 dataOffset + (numberOfChangeEntries * sizeof(ChangeEntry));
530 changeRecordDataSize -=
531 dataOffset + (numberOfChangeEntries * sizeof(ChangeEntry));
532 }
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500533 }
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500534 if (hostPDRHandler)
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500535 {
Deepak Kodihalli7246e0c2020-07-08 06:40:18 -0500536 hostPDRHandler->fetchPDR(std::move(pdrRecordHandles));
Deepak Kodihalli8cb6f662020-04-10 02:55:43 -0500537 }
538
539 return PLDM_SUCCESS;
540}
541
542int Handler::getPDRRecordHandles(const ChangeEntry* changeEntryData,
543 size_t changeEntryDataSize,
544 size_t numberOfChangeEntries,
545 PDRRecordHandles& pdrRecordHandles)
546{
547 if (numberOfChangeEntries > (changeEntryDataSize / sizeof(ChangeEntry)))
548 {
549 return PLDM_ERROR_INVALID_DATA;
550 }
551 for (size_t i = 0; i < numberOfChangeEntries; i++)
552 {
553 pdrRecordHandles.push_back(changeEntryData[i]);
554 }
555 return PLDM_SUCCESS;
556}
557
George Liueccb0c52020-01-14 11:09:56 +0800558Response Handler::setNumericEffecterValue(const pldm_msg* request,
559 size_t payloadLength)
560{
561 Response response(sizeof(pldm_msg_hdr) +
562 PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES);
563 uint16_t effecterId{};
564 uint8_t effecterDataSize{};
565 uint8_t effecterValue[4] = {};
566
567 if ((payloadLength > sizeof(effecterId) + sizeof(effecterDataSize) +
568 sizeof(union_effecter_data_size)) ||
569 (payloadLength < sizeof(effecterId) + sizeof(effecterDataSize) + 1))
570 {
571 return ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH);
572 }
573
574 int rc = decode_set_numeric_effecter_value_req(
575 request, payloadLength, &effecterId, &effecterDataSize,
576 reinterpret_cast<uint8_t*>(&effecterValue));
577
578 if (rc == PLDM_SUCCESS)
579 {
580 const pldm::utils::DBusHandler dBusIntf;
581 rc = platform_numeric_effecter::setNumericEffecterValueHandler<
582 pldm::utils::DBusHandler, Handler>(dBusIntf, *this, effecterId,
583 effecterDataSize, effecterValue,
584 sizeof(effecterValue));
585 }
586
587 return ccOnlyResponse(request, rc);
588}
589
Sampa Misra12afe112020-05-25 11:40:44 -0500590void Handler::generateTerminusLocatorPDR(Repo& repo)
591{
592 std::vector<uint8_t> pdrBuffer(sizeof(pldm_terminus_locator_pdr));
593
594 auto pdr = reinterpret_cast<pldm_terminus_locator_pdr*>(pdrBuffer.data());
595
596 pdr->hdr.record_handle = 0;
597 pdr->hdr.version = 1;
598 pdr->hdr.type = PLDM_TERMINUS_LOCATOR_PDR;
599 pdr->hdr.record_change_num = 0;
600 pdr->hdr.length = sizeof(pldm_terminus_locator_pdr) - sizeof(pldm_pdr_hdr);
601 pdr->terminus_handle = BmcPldmTerminusHandle;
602 pdr->validity = PLDM_TL_PDR_VALID;
603 pdr->tid = BmcTerminusId;
604 pdr->container_id = 0x0;
605 pdr->terminus_locator_type = PLDM_TERMINUS_LOCATOR_TYPE_MCTP_EID;
606 pdr->terminus_locator_value_size =
607 sizeof(pldm_terminus_locator_type_mctp_eid);
608 auto locatorValue = reinterpret_cast<pldm_terminus_locator_type_mctp_eid*>(
609 pdr->terminus_locator_value);
610 locatorValue->eid = BmcMctpEid;
611
612 PdrEntry pdrEntry{};
613 pdrEntry.data = pdrBuffer.data();
614 pdrEntry.size = pdrBuffer.size();
615 repo.addRecord(pdrEntry);
616}
Deepak Kodihallibc669f12019-11-28 08:52:07 -0600617} // namespace platform
Deepak Kodihalli557dfb02019-05-12 13:11:17 +0530618} // namespace responder
619} // namespace pldm