1 2 #include "platform.hpp" 3 4 #include "libpldm/entity.h" 5 #include "libpldm/state_set.h" 6 7 #include "common/types.hpp" 8 #include "common/utils.hpp" 9 #include "event_parser.hpp" 10 #include "pdr.hpp" 11 #include "pdr_numeric_effecter.hpp" 12 #include "pdr_state_effecter.hpp" 13 #include "pdr_state_sensor.hpp" 14 #include "pdr_utils.hpp" 15 #include "platform_numeric_effecter.hpp" 16 #include "platform_state_effecter.hpp" 17 #include "platform_state_sensor.hpp" 18 19 using namespace pldm::utils; 20 using namespace pldm::responder::pdr; 21 using namespace pldm::responder::pdr_utils; 22 23 namespace pldm 24 { 25 namespace responder 26 { 27 namespace platform 28 { 29 30 using InternalFailure = 31 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; 32 33 static const Json empty{}; 34 35 void Handler::addDbusObjMaps( 36 uint16_t id, 37 std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps> dbusObj, 38 TypeId typeId) 39 { 40 if (typeId == TypeId::PLDM_SENSOR_ID) 41 { 42 sensorDbusObjMaps.emplace(id, dbusObj); 43 } 44 else 45 { 46 effecterDbusObjMaps.emplace(id, dbusObj); 47 } 48 } 49 50 const std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps>& 51 Handler::getDbusObjMaps(uint16_t id, TypeId typeId) const 52 { 53 if (typeId == TypeId::PLDM_SENSOR_ID) 54 { 55 return sensorDbusObjMaps.at(id); 56 } 57 else 58 { 59 return effecterDbusObjMaps.at(id); 60 } 61 } 62 63 void Handler::generate(const pldm::utils::DBusHandler& dBusIntf, 64 const std::string& dir, Repo& repo) 65 { 66 if (!fs::exists(dir)) 67 { 68 return; 69 } 70 71 // A map of PDR type to a lambda that handles creation of that PDR type. 72 // The lambda essentially would parse the platform specific PDR JSONs to 73 // generate the PDR structures. This function iterates through the map to 74 // invoke all lambdas, so that all PDR types can be created. 75 76 const std::map<Type, generatePDR> generateHandlers = { 77 {PLDM_STATE_EFFECTER_PDR, 78 [this](const DBusHandler& dBusIntf, const auto& json, 79 RepoInterface& repo) { 80 pdr_state_effecter::generateStateEffecterPDR< 81 pldm::utils::DBusHandler, Handler>(dBusIntf, json, *this, 82 repo); 83 }}, 84 {PLDM_NUMERIC_EFFECTER_PDR, 85 [this](const DBusHandler& dBusIntf, const auto& json, 86 RepoInterface& repo) { 87 pdr_numeric_effecter::generateNumericEffecterPDR< 88 pldm::utils::DBusHandler, Handler>(dBusIntf, json, *this, 89 repo); 90 }}, 91 {PLDM_STATE_SENSOR_PDR, [this](const DBusHandler& dBusIntf, 92 const auto& json, RepoInterface& repo) { 93 pdr_state_sensor::generateStateSensorPDR<pldm::utils::DBusHandler, 94 Handler>(dBusIntf, json, 95 *this, repo); 96 }}}; 97 98 Type pdrType{}; 99 for (const auto& dirEntry : fs::directory_iterator(dir)) 100 { 101 try 102 { 103 auto json = readJson(dirEntry.path().string()); 104 if (!json.empty()) 105 { 106 auto effecterPDRs = json.value("effecterPDRs", empty); 107 for (const auto& effecter : effecterPDRs) 108 { 109 pdrType = effecter.value("pdrType", 0); 110 generateHandlers.at(pdrType)(dBusIntf, effecter, repo); 111 } 112 113 auto sensorPDRs = json.value("sensorPDRs", empty); 114 for (const auto& sensor : sensorPDRs) 115 { 116 pdrType = sensor.value("pdrType", 0); 117 generateHandlers.at(pdrType)(dBusIntf, sensor, repo); 118 } 119 } 120 } 121 catch (const InternalFailure& e) 122 { 123 std::cerr << "PDR config directory does not exist or empty, TYPE= " 124 << pdrType << "PATH= " << dirEntry 125 << " ERROR=" << e.what() << "\n"; 126 } 127 catch (const Json::exception& e) 128 { 129 std::cerr << "Failed parsing PDR JSON file, TYPE= " << pdrType 130 << " ERROR=" << e.what() << "\n"; 131 pldm::utils::reportError( 132 "xyz.openbmc_project.bmc.pldm.InternalFailure"); 133 } 134 catch (const std::exception& e) 135 { 136 std::cerr << "Failed parsing PDR JSON file, TYPE= " << pdrType 137 << " ERROR=" << e.what() << "\n"; 138 pldm::utils::reportError( 139 "xyz.openbmc_project.bmc.pldm.InternalFailure"); 140 } 141 } 142 } 143 144 Response Handler::getPDR(const pldm_msg* request, size_t payloadLength) 145 { 146 // Build FRU table if not built, since entity association PDR's are built 147 // when the FRU table is constructed. 148 if (fruHandler) 149 { 150 fruHandler->buildFRUTable(); 151 } 152 153 if (!pdrCreated) 154 { 155 generateTerminusLocatorPDR(pdrRepo); 156 generate(*dBusIntf, pdrJsonsDir, pdrRepo); 157 if (oemPlatformHandler != nullptr) 158 { 159 oemPlatformHandler->buildOEMPDR(pdrRepo); 160 } 161 162 pdrCreated = true; 163 164 if (dbusToPLDMEventHandler) 165 { 166 deferredGetPDREvent = std::make_unique<sdeventplus::source::Defer>( 167 event, 168 std::bind(std::mem_fn(&pldm::responder::platform::Handler:: 169 _processPostGetPDRActions), 170 this, std::placeholders::_1)); 171 } 172 } 173 174 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_PDR_MIN_RESP_BYTES, 0); 175 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 176 177 if (payloadLength != PLDM_GET_PDR_REQ_BYTES) 178 { 179 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH); 180 } 181 182 uint32_t recordHandle{}; 183 uint32_t dataTransferHandle{}; 184 uint8_t transferOpFlag{}; 185 uint16_t reqSizeBytes{}; 186 uint16_t recordChangeNum{}; 187 188 auto rc = decode_get_pdr_req(request, payloadLength, &recordHandle, 189 &dataTransferHandle, &transferOpFlag, 190 &reqSizeBytes, &recordChangeNum); 191 if (rc != PLDM_SUCCESS) 192 { 193 return CmdHandler::ccOnlyResponse(request, rc); 194 } 195 196 uint16_t respSizeBytes{}; 197 uint8_t* recordData = nullptr; 198 try 199 { 200 pdr_utils::PdrEntry e; 201 auto record = pdr::getRecordByHandle(pdrRepo, recordHandle, e); 202 if (record == NULL) 203 { 204 return CmdHandler::ccOnlyResponse( 205 request, PLDM_PLATFORM_INVALID_RECORD_HANDLE); 206 } 207 208 if (reqSizeBytes) 209 { 210 respSizeBytes = e.size; 211 if (respSizeBytes > reqSizeBytes) 212 { 213 respSizeBytes = reqSizeBytes; 214 } 215 recordData = e.data; 216 } 217 response.resize(sizeof(pldm_msg_hdr) + PLDM_GET_PDR_MIN_RESP_BYTES + 218 respSizeBytes, 219 0); 220 responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 221 rc = encode_get_pdr_resp( 222 request->hdr.instance_id, PLDM_SUCCESS, e.handle.nextRecordHandle, 223 0, PLDM_START_AND_END, respSizeBytes, recordData, 0, responsePtr); 224 if (rc != PLDM_SUCCESS) 225 { 226 return ccOnlyResponse(request, rc); 227 } 228 } 229 catch (const std::exception& e) 230 { 231 std::cerr << "Error accessing PDR, HANDLE=" << recordHandle 232 << " ERROR=" << e.what() << "\n"; 233 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR); 234 } 235 return response; 236 } 237 238 Response Handler::setStateEffecterStates(const pldm_msg* request, 239 size_t payloadLength) 240 { 241 Response response( 242 sizeof(pldm_msg_hdr) + PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES, 0); 243 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 244 uint16_t effecterId; 245 uint8_t compEffecterCnt; 246 constexpr auto maxCompositeEffecterCnt = 8; 247 std::vector<set_effecter_state_field> stateField(maxCompositeEffecterCnt, 248 {0, 0}); 249 250 if ((payloadLength > PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES) || 251 (payloadLength < sizeof(effecterId) + sizeof(compEffecterCnt) + 252 sizeof(set_effecter_state_field))) 253 { 254 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH); 255 } 256 257 int rc = decode_set_state_effecter_states_req(request, payloadLength, 258 &effecterId, &compEffecterCnt, 259 stateField.data()); 260 261 if (rc != PLDM_SUCCESS) 262 { 263 return CmdHandler::ccOnlyResponse(request, rc); 264 } 265 266 stateField.resize(compEffecterCnt); 267 const pldm::utils::DBusHandler dBusIntf; 268 uint16_t entityType{}; 269 uint16_t entityInstance{}; 270 uint16_t stateSetId{}; 271 272 if (isOemStateEffecter(*this, effecterId, compEffecterCnt, entityType, 273 entityInstance, stateSetId) && 274 oemPlatformHandler != nullptr) 275 { 276 rc = oemPlatformHandler->oemSetStateEffecterStatesHandler( 277 entityType, entityInstance, stateSetId, compEffecterCnt, stateField, 278 effecterId); 279 } 280 else 281 { 282 rc = platform_state_effecter::setStateEffecterStatesHandler< 283 pldm::utils::DBusHandler, Handler>(dBusIntf, *this, effecterId, 284 stateField); 285 } 286 if (rc != PLDM_SUCCESS) 287 { 288 return CmdHandler::ccOnlyResponse(request, rc); 289 } 290 291 rc = encode_set_state_effecter_states_resp(request->hdr.instance_id, rc, 292 responsePtr); 293 if (rc != PLDM_SUCCESS) 294 { 295 return ccOnlyResponse(request, rc); 296 } 297 298 return response; 299 } 300 301 Response Handler::platformEventMessage(const pldm_msg* request, 302 size_t payloadLength) 303 { 304 uint8_t formatVersion{}; 305 uint8_t tid{}; 306 uint8_t eventClass{}; 307 size_t offset{}; 308 309 auto rc = decode_platform_event_message_req( 310 request, payloadLength, &formatVersion, &tid, &eventClass, &offset); 311 if (rc != PLDM_SUCCESS) 312 { 313 return CmdHandler::ccOnlyResponse(request, rc); 314 } 315 316 if (eventClass == PLDM_HEARTBEAT_TIMER_ELAPSED_EVENT) 317 { 318 rc = PLDM_SUCCESS; 319 if (oemPlatformHandler) 320 { 321 oemPlatformHandler->resetWatchDogTimer(); 322 } 323 } 324 else 325 { 326 try 327 { 328 const auto& handlers = eventHandlers.at(eventClass); 329 for (const auto& handler : handlers) 330 { 331 auto rc = 332 handler(request, payloadLength, formatVersion, tid, offset); 333 if (rc != PLDM_SUCCESS) 334 { 335 return CmdHandler::ccOnlyResponse(request, rc); 336 } 337 } 338 } 339 catch (const std::out_of_range& e) 340 { 341 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_DATA); 342 } 343 } 344 Response response( 345 sizeof(pldm_msg_hdr) + PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES, 0); 346 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 347 348 rc = encode_platform_event_message_resp(request->hdr.instance_id, rc, 349 PLDM_EVENT_NO_LOGGING, responsePtr); 350 if (rc != PLDM_SUCCESS) 351 { 352 return ccOnlyResponse(request, rc); 353 } 354 355 return response; 356 } 357 358 int Handler::sensorEvent(const pldm_msg* request, size_t payloadLength, 359 uint8_t /*formatVersion*/, uint8_t tid, 360 size_t eventDataOffset) 361 { 362 uint16_t sensorId{}; 363 uint8_t eventClass{}; 364 size_t eventClassDataOffset{}; 365 auto eventData = 366 reinterpret_cast<const uint8_t*>(request->payload) + eventDataOffset; 367 auto eventDataSize = payloadLength - eventDataOffset; 368 369 auto rc = decode_sensor_event_data(eventData, eventDataSize, &sensorId, 370 &eventClass, &eventClassDataOffset); 371 if (rc != PLDM_SUCCESS) 372 { 373 return rc; 374 } 375 376 auto eventClassData = reinterpret_cast<const uint8_t*>(request->payload) + 377 eventDataOffset + eventClassDataOffset; 378 auto eventClassDataSize = 379 payloadLength - eventDataOffset - eventClassDataOffset; 380 381 if (eventClass == PLDM_STATE_SENSOR_STATE) 382 { 383 uint8_t sensorOffset{}; 384 uint8_t eventState{}; 385 uint8_t previousEventState{}; 386 387 rc = decode_state_sensor_data(eventClassData, eventClassDataSize, 388 &sensorOffset, &eventState, 389 &previousEventState); 390 if (rc != PLDM_SUCCESS) 391 { 392 return PLDM_ERROR; 393 } 394 395 // Emitting state sensor event signal 396 emitStateSensorEventSignal(tid, sensorId, sensorOffset, eventState, 397 previousEventState); 398 399 // If there are no HOST PDR's, there is no further action 400 if (hostPDRHandler == NULL) 401 { 402 return PLDM_SUCCESS; 403 } 404 405 // Handle PLDM events for which PDR is available 406 SensorEntry sensorEntry{tid, sensorId}; 407 408 pldm::pdr::EntityInfo entityInfo{}; 409 pldm::pdr::CompositeSensorStates compositeSensorStates{}; 410 411 try 412 { 413 std::tie(entityInfo, compositeSensorStates) = 414 hostPDRHandler->lookupSensorInfo(sensorEntry); 415 } 416 catch (const std::out_of_range& e) 417 { 418 // If there is no mapping for tid, sensorId combination, try 419 // PLDM_TID_RESERVED, sensorId for terminus that is yet to 420 // implement TL PDR. 421 try 422 { 423 sensorEntry.terminusID = PLDM_TID_RESERVED; 424 std::tie(entityInfo, compositeSensorStates) = 425 hostPDRHandler->lookupSensorInfo(sensorEntry); 426 } 427 // If there is no mapping for events return PLDM_SUCCESS 428 catch (const std::out_of_range& e) 429 { 430 return PLDM_SUCCESS; 431 } 432 } 433 434 if (sensorOffset >= compositeSensorStates.size()) 435 { 436 return PLDM_ERROR_INVALID_DATA; 437 } 438 439 const auto& possibleStates = compositeSensorStates[sensorOffset]; 440 if (possibleStates.find(eventState) == possibleStates.end()) 441 { 442 return PLDM_ERROR_INVALID_DATA; 443 } 444 445 const auto& [containerId, entityType, entityInstance] = entityInfo; 446 events::StateSensorEntry stateSensorEntry{containerId, entityType, 447 entityInstance, sensorOffset}; 448 return hostPDRHandler->handleStateSensorEvent(stateSensorEntry, 449 eventState); 450 } 451 else 452 { 453 return PLDM_ERROR_INVALID_DATA; 454 } 455 456 return PLDM_SUCCESS; 457 } 458 459 int Handler::pldmPDRRepositoryChgEvent(const pldm_msg* request, 460 size_t payloadLength, 461 uint8_t /*formatVersion*/, 462 uint8_t /*tid*/, size_t eventDataOffset) 463 { 464 uint8_t eventDataFormat{}; 465 uint8_t numberOfChangeRecords{}; 466 size_t dataOffset{}; 467 468 auto eventData = 469 reinterpret_cast<const uint8_t*>(request->payload) + eventDataOffset; 470 auto eventDataSize = payloadLength - eventDataOffset; 471 472 auto rc = decode_pldm_pdr_repository_chg_event_data( 473 eventData, eventDataSize, &eventDataFormat, &numberOfChangeRecords, 474 &dataOffset); 475 if (rc != PLDM_SUCCESS) 476 { 477 return rc; 478 } 479 480 PDRRecordHandles pdrRecordHandles; 481 482 if (eventDataFormat == FORMAT_IS_PDR_TYPES) 483 { 484 return PLDM_ERROR_INVALID_DATA; 485 } 486 487 if (eventDataFormat == FORMAT_IS_PDR_HANDLES) 488 { 489 uint8_t eventDataOperation{}; 490 uint8_t numberOfChangeEntries{}; 491 492 auto changeRecordData = eventData + dataOffset; 493 auto changeRecordDataSize = eventDataSize - dataOffset; 494 495 while (changeRecordDataSize) 496 { 497 rc = decode_pldm_pdr_repository_change_record_data( 498 changeRecordData, changeRecordDataSize, &eventDataOperation, 499 &numberOfChangeEntries, &dataOffset); 500 501 if (rc != PLDM_SUCCESS) 502 { 503 return rc; 504 } 505 506 if (eventDataOperation == PLDM_RECORDS_ADDED) 507 { 508 rc = getPDRRecordHandles( 509 reinterpret_cast<const ChangeEntry*>(changeRecordData + 510 dataOffset), 511 changeRecordDataSize - dataOffset, 512 static_cast<size_t>(numberOfChangeEntries), 513 pdrRecordHandles); 514 515 if (rc != PLDM_SUCCESS) 516 { 517 return rc; 518 } 519 } 520 521 if (eventDataOperation == PLDM_RECORDS_MODIFIED) 522 { 523 return PLDM_ERROR_UNSUPPORTED_PLDM_CMD; 524 } 525 526 changeRecordData += 527 dataOffset + (numberOfChangeEntries * sizeof(ChangeEntry)); 528 changeRecordDataSize -= 529 dataOffset + (numberOfChangeEntries * sizeof(ChangeEntry)); 530 } 531 } 532 if (hostPDRHandler) 533 { 534 hostPDRHandler->fetchPDR(std::move(pdrRecordHandles)); 535 } 536 537 return PLDM_SUCCESS; 538 } 539 540 int Handler::getPDRRecordHandles(const ChangeEntry* changeEntryData, 541 size_t changeEntryDataSize, 542 size_t numberOfChangeEntries, 543 PDRRecordHandles& pdrRecordHandles) 544 { 545 if (numberOfChangeEntries > (changeEntryDataSize / sizeof(ChangeEntry))) 546 { 547 return PLDM_ERROR_INVALID_DATA; 548 } 549 for (size_t i = 0; i < numberOfChangeEntries; i++) 550 { 551 pdrRecordHandles.push_back(changeEntryData[i]); 552 } 553 return PLDM_SUCCESS; 554 } 555 556 Response Handler::setNumericEffecterValue(const pldm_msg* request, 557 size_t payloadLength) 558 { 559 Response response(sizeof(pldm_msg_hdr) + 560 PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES); 561 uint16_t effecterId{}; 562 uint8_t effecterDataSize{}; 563 uint8_t effecterValue[4] = {}; 564 565 if ((payloadLength > sizeof(effecterId) + sizeof(effecterDataSize) + 566 sizeof(union_effecter_data_size)) || 567 (payloadLength < sizeof(effecterId) + sizeof(effecterDataSize) + 1)) 568 { 569 return ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH); 570 } 571 572 int rc = decode_set_numeric_effecter_value_req( 573 request, payloadLength, &effecterId, &effecterDataSize, 574 reinterpret_cast<uint8_t*>(&effecterValue)); 575 576 if (rc == PLDM_SUCCESS) 577 { 578 const pldm::utils::DBusHandler dBusIntf; 579 rc = platform_numeric_effecter::setNumericEffecterValueHandler< 580 pldm::utils::DBusHandler, Handler>(dBusIntf, *this, effecterId, 581 effecterDataSize, effecterValue, 582 sizeof(effecterValue)); 583 } 584 585 return ccOnlyResponse(request, rc); 586 } 587 588 void Handler::generateTerminusLocatorPDR(Repo& repo) 589 { 590 std::vector<uint8_t> pdrBuffer(sizeof(pldm_terminus_locator_pdr)); 591 592 auto pdr = reinterpret_cast<pldm_terminus_locator_pdr*>(pdrBuffer.data()); 593 594 pdr->hdr.record_handle = 0; 595 pdr->hdr.version = 1; 596 pdr->hdr.type = PLDM_TERMINUS_LOCATOR_PDR; 597 pdr->hdr.record_change_num = 0; 598 pdr->hdr.length = sizeof(pldm_terminus_locator_pdr) - sizeof(pldm_pdr_hdr); 599 pdr->terminus_handle = BmcPldmTerminusHandle; 600 pdr->validity = PLDM_TL_PDR_VALID; 601 pdr->tid = BmcTerminusId; 602 pdr->container_id = 0x0; 603 pdr->terminus_locator_type = PLDM_TERMINUS_LOCATOR_TYPE_MCTP_EID; 604 pdr->terminus_locator_value_size = 605 sizeof(pldm_terminus_locator_type_mctp_eid); 606 auto locatorValue = reinterpret_cast<pldm_terminus_locator_type_mctp_eid*>( 607 pdr->terminus_locator_value); 608 locatorValue->eid = BmcMctpEid; 609 610 PdrEntry pdrEntry{}; 611 pdrEntry.data = pdrBuffer.data(); 612 pdrEntry.size = pdrBuffer.size(); 613 repo.addRecord(pdrEntry); 614 } 615 616 Response Handler::getStateSensorReadings(const pldm_msg* request, 617 size_t payloadLength) 618 { 619 uint16_t sensorId{}; 620 bitfield8_t sensorRearm{}; 621 uint8_t reserved{}; 622 623 if (payloadLength != PLDM_GET_SENSOR_READING_REQ_BYTES) 624 { 625 return ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH); 626 } 627 628 int rc = decode_get_state_sensor_readings_req( 629 request, payloadLength, &sensorId, &sensorRearm, &reserved); 630 631 if (rc != PLDM_SUCCESS) 632 { 633 return ccOnlyResponse(request, rc); 634 } 635 636 // 0x01 to 0x08 637 uint8_t sensorRearmCount = std::popcount(sensorRearm.byte); 638 std::vector<get_sensor_state_field> stateField(sensorRearmCount); 639 uint8_t comSensorCnt{}; 640 const pldm::utils::DBusHandler dBusIntf; 641 642 uint16_t entityType{}; 643 uint16_t entityInstance{}; 644 uint16_t stateSetId{}; 645 646 if (isOemStateSensor(*this, sensorId, sensorRearmCount, comSensorCnt, 647 entityType, entityInstance, stateSetId) && 648 oemPlatformHandler != nullptr) 649 { 650 rc = oemPlatformHandler->getOemStateSensorReadingsHandler( 651 entityType, entityInstance, stateSetId, comSensorCnt, stateField); 652 } 653 else 654 { 655 rc = platform_state_sensor::getStateSensorReadingsHandler< 656 pldm::utils::DBusHandler, Handler>(dBusIntf, *this, sensorId, 657 sensorRearmCount, comSensorCnt, 658 stateField); 659 } 660 661 if (rc != PLDM_SUCCESS) 662 { 663 return ccOnlyResponse(request, rc); 664 } 665 666 Response response(sizeof(pldm_msg_hdr) + 667 PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES + 668 sizeof(get_sensor_state_field) * comSensorCnt); 669 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 670 rc = encode_get_state_sensor_readings_resp(request->hdr.instance_id, rc, 671 comSensorCnt, stateField.data(), 672 responsePtr); 673 if (rc != PLDM_SUCCESS) 674 { 675 return ccOnlyResponse(request, rc); 676 } 677 678 return response; 679 } 680 681 void Handler::_processPostGetPDRActions( 682 sdeventplus::source::EventBase& /*source */) 683 { 684 deferredGetPDREvent.reset(); 685 dbusToPLDMEventHandler->listenSensorEvent(pdrRepo, sensorDbusObjMaps); 686 } 687 688 bool isOemStateSensor(Handler& handler, uint16_t sensorId, 689 uint8_t sensorRearmCount, uint8_t& compSensorCnt, 690 uint16_t& entityType, uint16_t& entityInstance, 691 uint16_t& stateSetId) 692 { 693 pldm_state_sensor_pdr* pdr = nullptr; 694 695 std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)> stateSensorPdrRepo( 696 pldm_pdr_init(), pldm_pdr_destroy); 697 Repo stateSensorPDRs(stateSensorPdrRepo.get()); 698 getRepoByType(handler.getRepo(), stateSensorPDRs, PLDM_STATE_SENSOR_PDR); 699 if (stateSensorPDRs.empty()) 700 { 701 std::cerr << "Failed to get record by PDR type\n"; 702 return false; 703 } 704 705 PdrEntry pdrEntry{}; 706 auto pdrRecord = stateSensorPDRs.getFirstRecord(pdrEntry); 707 while (pdrRecord) 708 { 709 pdr = reinterpret_cast<pldm_state_sensor_pdr*>(pdrEntry.data); 710 assert(pdr != NULL); 711 if (pdr->sensor_id != sensorId) 712 { 713 pdr = nullptr; 714 pdrRecord = stateSensorPDRs.getNextRecord(pdrRecord, pdrEntry); 715 continue; 716 } 717 auto tmpEntityType = pdr->entity_type; 718 auto tmpEntityInstance = pdr->entity_instance; 719 auto tmpCompSensorCnt = pdr->composite_sensor_count; 720 auto tmpPossibleStates = 721 reinterpret_cast<state_sensor_possible_states*>( 722 pdr->possible_states); 723 auto tmpStateSetId = tmpPossibleStates->state_set_id; 724 725 if (sensorRearmCount > tmpCompSensorCnt) 726 { 727 std::cerr << "The requester sent wrong sensorRearm" 728 << " count for the sensor, SENSOR_ID=" << sensorId 729 << "SENSOR_REARM_COUNT=" << (uint16_t)sensorRearmCount 730 << "\n"; 731 break; 732 } 733 734 if ((tmpEntityType >= PLDM_OEM_ENTITY_TYPE_START && 735 tmpEntityType <= PLDM_OEM_ENTITY_TYPE_END) || 736 (tmpStateSetId >= PLDM_OEM_STATE_SET_ID_START && 737 tmpStateSetId < PLDM_OEM_STATE_SET_ID_END)) 738 { 739 entityType = tmpEntityType; 740 entityInstance = tmpEntityInstance; 741 stateSetId = tmpStateSetId; 742 compSensorCnt = tmpCompSensorCnt; 743 return true; 744 } 745 else 746 { 747 return false; 748 } 749 } 750 return false; 751 } 752 753 bool isOemStateEffecter(Handler& handler, uint16_t effecterId, 754 uint8_t compEffecterCnt, uint16_t& entityType, 755 uint16_t& entityInstance, uint16_t& stateSetId) 756 { 757 pldm_state_effecter_pdr* pdr = nullptr; 758 759 std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)> stateEffecterPdrRepo( 760 pldm_pdr_init(), pldm_pdr_destroy); 761 Repo stateEffecterPDRs(stateEffecterPdrRepo.get()); 762 getRepoByType(handler.getRepo(), stateEffecterPDRs, 763 PLDM_STATE_EFFECTER_PDR); 764 if (stateEffecterPDRs.empty()) 765 { 766 std::cerr << "Failed to get record by PDR type\n"; 767 return false; 768 } 769 770 PdrEntry pdrEntry{}; 771 auto pdrRecord = stateEffecterPDRs.getFirstRecord(pdrEntry); 772 while (pdrRecord) 773 { 774 pdr = reinterpret_cast<pldm_state_effecter_pdr*>(pdrEntry.data); 775 assert(pdr != NULL); 776 if (pdr->effecter_id != effecterId) 777 { 778 pdr = nullptr; 779 pdrRecord = stateEffecterPDRs.getNextRecord(pdrRecord, pdrEntry); 780 continue; 781 } 782 783 auto tmpEntityType = pdr->entity_type; 784 auto tmpEntityInstance = pdr->entity_instance; 785 auto tmpPossibleStates = 786 reinterpret_cast<state_effecter_possible_states*>( 787 pdr->possible_states); 788 auto tmpStateSetId = tmpPossibleStates->state_set_id; 789 790 if (compEffecterCnt > pdr->composite_effecter_count) 791 { 792 std::cerr << "The requester sent wrong composite effecter" 793 << " count for the effecter, EFFECTER_ID=" << effecterId 794 << "COMP_EFF_CNT=" << (uint16_t)compEffecterCnt << "\n"; 795 return false; 796 } 797 798 if ((tmpEntityType >= PLDM_OEM_ENTITY_TYPE_START && 799 tmpEntityType <= PLDM_OEM_ENTITY_TYPE_END) || 800 (tmpStateSetId >= PLDM_OEM_STATE_SET_ID_START && 801 tmpStateSetId < PLDM_OEM_STATE_SET_ID_END)) 802 { 803 entityType = tmpEntityType; 804 entityInstance = tmpEntityInstance; 805 stateSetId = tmpStateSetId; 806 return true; 807 } 808 else 809 { 810 return false; 811 } 812 } 813 return false; 814 } 815 816 } // namespace platform 817 } // namespace responder 818 } // namespace pldm 819