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