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 pdrCreated = true; 154 } 155 156 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_PDR_MIN_RESP_BYTES, 0); 157 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 158 159 if (payloadLength != PLDM_GET_PDR_REQ_BYTES) 160 { 161 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH); 162 } 163 164 uint32_t recordHandle{}; 165 uint32_t dataTransferHandle{}; 166 uint8_t transferOpFlag{}; 167 uint16_t reqSizeBytes{}; 168 uint16_t recordChangeNum{}; 169 170 auto rc = decode_get_pdr_req(request, payloadLength, &recordHandle, 171 &dataTransferHandle, &transferOpFlag, 172 &reqSizeBytes, &recordChangeNum); 173 if (rc != PLDM_SUCCESS) 174 { 175 return CmdHandler::ccOnlyResponse(request, rc); 176 } 177 178 uint16_t respSizeBytes{}; 179 uint8_t* recordData = nullptr; 180 try 181 { 182 pdr_utils::PdrEntry e; 183 auto record = pdr::getRecordByHandle(pdrRepo, recordHandle, e); 184 if (record == NULL) 185 { 186 return CmdHandler::ccOnlyResponse( 187 request, PLDM_PLATFORM_INVALID_RECORD_HANDLE); 188 } 189 190 if (reqSizeBytes) 191 { 192 respSizeBytes = e.size; 193 if (respSizeBytes > reqSizeBytes) 194 { 195 respSizeBytes = reqSizeBytes; 196 } 197 recordData = e.data; 198 } 199 response.resize(sizeof(pldm_msg_hdr) + PLDM_GET_PDR_MIN_RESP_BYTES + 200 respSizeBytes, 201 0); 202 responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 203 rc = encode_get_pdr_resp( 204 request->hdr.instance_id, PLDM_SUCCESS, e.handle.nextRecordHandle, 205 0, PLDM_START_AND_END, respSizeBytes, recordData, 0, responsePtr); 206 if (rc != PLDM_SUCCESS) 207 { 208 return ccOnlyResponse(request, rc); 209 } 210 } 211 catch (const std::exception& e) 212 { 213 std::cerr << "Error accessing PDR, HANDLE=" << recordHandle 214 << " ERROR=" << e.what() << "\n"; 215 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR); 216 } 217 return response; 218 } 219 220 Response Handler::setStateEffecterStates(const pldm_msg* request, 221 size_t payloadLength) 222 { 223 Response response( 224 sizeof(pldm_msg_hdr) + PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES, 0); 225 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 226 uint16_t effecterId; 227 uint8_t compEffecterCnt; 228 constexpr auto maxCompositeEffecterCnt = 8; 229 std::vector<set_effecter_state_field> stateField(maxCompositeEffecterCnt, 230 {0, 0}); 231 232 if ((payloadLength > PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES) || 233 (payloadLength < sizeof(effecterId) + sizeof(compEffecterCnt) + 234 sizeof(set_effecter_state_field))) 235 { 236 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH); 237 } 238 239 int rc = decode_set_state_effecter_states_req(request, payloadLength, 240 &effecterId, &compEffecterCnt, 241 stateField.data()); 242 243 if (rc != PLDM_SUCCESS) 244 { 245 return CmdHandler::ccOnlyResponse(request, rc); 246 } 247 248 stateField.resize(compEffecterCnt); 249 const pldm::utils::DBusHandler dBusIntf; 250 uint16_t entityType{}; 251 uint16_t entityInstance{}; 252 uint16_t stateSetId{}; 253 254 if (isOemStateEffecter(*this, effecterId, compEffecterCnt, entityType, 255 entityInstance, stateSetId) && 256 oemPlatformHandler != nullptr) 257 { 258 rc = oemPlatformHandler->oemSetStateEffecterStatesHandler( 259 entityType, entityInstance, stateSetId, compEffecterCnt, 260 stateField); 261 } 262 else 263 { 264 rc = platform_state_effecter::setStateEffecterStatesHandler< 265 pldm::utils::DBusHandler, Handler>(dBusIntf, *this, effecterId, 266 stateField); 267 } 268 if (rc != PLDM_SUCCESS) 269 { 270 return CmdHandler::ccOnlyResponse(request, rc); 271 } 272 273 rc = encode_set_state_effecter_states_resp(request->hdr.instance_id, rc, 274 responsePtr); 275 if (rc != PLDM_SUCCESS) 276 { 277 return ccOnlyResponse(request, rc); 278 } 279 280 return response; 281 } 282 283 Response Handler::platformEventMessage(const pldm_msg* request, 284 size_t payloadLength) 285 { 286 uint8_t formatVersion{}; 287 uint8_t tid{}; 288 uint8_t eventClass{}; 289 size_t offset{}; 290 291 auto rc = decode_platform_event_message_req( 292 request, payloadLength, &formatVersion, &tid, &eventClass, &offset); 293 if (rc != PLDM_SUCCESS) 294 { 295 return CmdHandler::ccOnlyResponse(request, rc); 296 } 297 298 try 299 { 300 const auto& handlers = eventHandlers.at(eventClass); 301 for (const auto& handler : handlers) 302 { 303 auto rc = 304 handler(request, payloadLength, formatVersion, tid, offset); 305 if (rc != PLDM_SUCCESS) 306 { 307 return CmdHandler::ccOnlyResponse(request, rc); 308 } 309 } 310 } 311 catch (const std::out_of_range& e) 312 { 313 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_DATA); 314 } 315 316 Response response( 317 sizeof(pldm_msg_hdr) + PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES, 0); 318 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 319 320 rc = encode_platform_event_message_resp(request->hdr.instance_id, rc, 321 PLDM_EVENT_NO_LOGGING, responsePtr); 322 if (rc != PLDM_SUCCESS) 323 { 324 return ccOnlyResponse(request, rc); 325 } 326 327 return response; 328 } 329 330 int Handler::sensorEvent(const pldm_msg* request, size_t payloadLength, 331 uint8_t /*formatVersion*/, uint8_t tid, 332 size_t eventDataOffset) 333 { 334 uint16_t sensorId{}; 335 uint8_t eventClass{}; 336 size_t eventClassDataOffset{}; 337 auto eventData = 338 reinterpret_cast<const uint8_t*>(request->payload) + eventDataOffset; 339 auto eventDataSize = payloadLength - eventDataOffset; 340 341 auto rc = decode_sensor_event_data(eventData, eventDataSize, &sensorId, 342 &eventClass, &eventClassDataOffset); 343 if (rc != PLDM_SUCCESS) 344 { 345 return rc; 346 } 347 348 auto eventClassData = reinterpret_cast<const uint8_t*>(request->payload) + 349 eventDataOffset + eventClassDataOffset; 350 auto eventClassDataSize = 351 payloadLength - eventDataOffset - eventClassDataOffset; 352 353 if (eventClass == PLDM_STATE_SENSOR_STATE) 354 { 355 uint8_t sensorOffset{}; 356 uint8_t eventState{}; 357 uint8_t previousEventState{}; 358 359 rc = decode_state_sensor_data(eventClassData, eventClassDataSize, 360 &sensorOffset, &eventState, 361 &previousEventState); 362 if (rc != PLDM_SUCCESS) 363 { 364 return PLDM_ERROR; 365 } 366 367 // Emitting state sensor event signal 368 emitStateSensorEventSignal(tid, sensorId, sensorOffset, eventState, 369 previousEventState); 370 371 // If there are no HOST PDR's, there is no further action 372 if (hostPDRHandler == NULL) 373 { 374 return PLDM_SUCCESS; 375 } 376 377 // Handle PLDM events for which PDR is available 378 SensorEntry sensorEntry{tid, sensorId}; 379 380 pldm::pdr::EntityInfo entityInfo{}; 381 pldm::pdr::CompositeSensorStates compositeSensorStates{}; 382 383 try 384 { 385 std::tie(entityInfo, compositeSensorStates) = 386 hostPDRHandler->lookupSensorInfo(sensorEntry); 387 } 388 catch (const std::out_of_range& e) 389 { 390 // If there is no mapping for tid, sensorId combination, try 391 // PLDM_TID_RESERVED, sensorId for terminus that is yet to 392 // implement TL PDR. 393 try 394 { 395 sensorEntry.terminusID = PLDM_TID_RESERVED; 396 std::tie(entityInfo, compositeSensorStates) = 397 hostPDRHandler->lookupSensorInfo(sensorEntry); 398 } 399 // If there is no mapping for events return PLDM_SUCCESS 400 catch (const std::out_of_range& e) 401 { 402 return PLDM_SUCCESS; 403 } 404 } 405 406 if (sensorOffset >= compositeSensorStates.size()) 407 { 408 return PLDM_ERROR_INVALID_DATA; 409 } 410 411 const auto& possibleStates = compositeSensorStates[sensorOffset]; 412 if (possibleStates.find(eventState) == possibleStates.end()) 413 { 414 return PLDM_ERROR_INVALID_DATA; 415 } 416 417 const auto& [containerId, entityType, entityInstance] = entityInfo; 418 events::StateSensorEntry stateSensorEntry{containerId, entityType, 419 entityInstance, sensorOffset}; 420 return hostPDRHandler->handleStateSensorEvent(stateSensorEntry, 421 eventState); 422 } 423 else 424 { 425 return PLDM_ERROR_INVALID_DATA; 426 } 427 428 return PLDM_SUCCESS; 429 } 430 431 int Handler::pldmPDRRepositoryChgEvent(const pldm_msg* request, 432 size_t payloadLength, 433 uint8_t /*formatVersion*/, 434 uint8_t /*tid*/, size_t eventDataOffset) 435 { 436 uint8_t eventDataFormat{}; 437 uint8_t numberOfChangeRecords{}; 438 size_t dataOffset{}; 439 440 auto eventData = 441 reinterpret_cast<const uint8_t*>(request->payload) + eventDataOffset; 442 auto eventDataSize = payloadLength - eventDataOffset; 443 444 auto rc = decode_pldm_pdr_repository_chg_event_data( 445 eventData, eventDataSize, &eventDataFormat, &numberOfChangeRecords, 446 &dataOffset); 447 if (rc != PLDM_SUCCESS) 448 { 449 return rc; 450 } 451 452 PDRRecordHandles pdrRecordHandles; 453 454 if (eventDataFormat == FORMAT_IS_PDR_TYPES) 455 { 456 return PLDM_ERROR_INVALID_DATA; 457 } 458 459 if (eventDataFormat == FORMAT_IS_PDR_HANDLES) 460 { 461 uint8_t eventDataOperation{}; 462 uint8_t numberOfChangeEntries{}; 463 464 auto changeRecordData = eventData + dataOffset; 465 auto changeRecordDataSize = eventDataSize - dataOffset; 466 467 while (changeRecordDataSize) 468 { 469 rc = decode_pldm_pdr_repository_change_record_data( 470 changeRecordData, changeRecordDataSize, &eventDataOperation, 471 &numberOfChangeEntries, &dataOffset); 472 473 if (rc != PLDM_SUCCESS) 474 { 475 return rc; 476 } 477 478 if (eventDataOperation == PLDM_RECORDS_ADDED) 479 { 480 rc = getPDRRecordHandles( 481 reinterpret_cast<const ChangeEntry*>(changeRecordData + 482 dataOffset), 483 changeRecordDataSize - dataOffset, 484 static_cast<size_t>(numberOfChangeEntries), 485 pdrRecordHandles); 486 487 if (rc != PLDM_SUCCESS) 488 { 489 return rc; 490 } 491 } 492 493 changeRecordData += 494 dataOffset + (numberOfChangeEntries * sizeof(ChangeEntry)); 495 changeRecordDataSize -= 496 dataOffset + (numberOfChangeEntries * sizeof(ChangeEntry)); 497 } 498 } 499 if (hostPDRHandler) 500 { 501 hostPDRHandler->fetchPDR(std::move(pdrRecordHandles)); 502 } 503 504 return PLDM_SUCCESS; 505 } 506 507 int Handler::getPDRRecordHandles(const ChangeEntry* changeEntryData, 508 size_t changeEntryDataSize, 509 size_t numberOfChangeEntries, 510 PDRRecordHandles& pdrRecordHandles) 511 { 512 if (numberOfChangeEntries > (changeEntryDataSize / sizeof(ChangeEntry))) 513 { 514 return PLDM_ERROR_INVALID_DATA; 515 } 516 for (size_t i = 0; i < numberOfChangeEntries; i++) 517 { 518 pdrRecordHandles.push_back(changeEntryData[i]); 519 } 520 return PLDM_SUCCESS; 521 } 522 523 Response Handler::setNumericEffecterValue(const pldm_msg* request, 524 size_t payloadLength) 525 { 526 Response response(sizeof(pldm_msg_hdr) + 527 PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES); 528 uint16_t effecterId{}; 529 uint8_t effecterDataSize{}; 530 uint8_t effecterValue[4] = {}; 531 532 if ((payloadLength > sizeof(effecterId) + sizeof(effecterDataSize) + 533 sizeof(union_effecter_data_size)) || 534 (payloadLength < sizeof(effecterId) + sizeof(effecterDataSize) + 1)) 535 { 536 return ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH); 537 } 538 539 int rc = decode_set_numeric_effecter_value_req( 540 request, payloadLength, &effecterId, &effecterDataSize, 541 reinterpret_cast<uint8_t*>(&effecterValue)); 542 543 if (rc == PLDM_SUCCESS) 544 { 545 const pldm::utils::DBusHandler dBusIntf; 546 rc = platform_numeric_effecter::setNumericEffecterValueHandler< 547 pldm::utils::DBusHandler, Handler>(dBusIntf, *this, effecterId, 548 effecterDataSize, effecterValue, 549 sizeof(effecterValue)); 550 } 551 552 return ccOnlyResponse(request, rc); 553 } 554 555 void Handler::generateTerminusLocatorPDR(Repo& repo) 556 { 557 std::vector<uint8_t> pdrBuffer(sizeof(pldm_terminus_locator_pdr)); 558 559 auto pdr = reinterpret_cast<pldm_terminus_locator_pdr*>(pdrBuffer.data()); 560 561 pdr->hdr.record_handle = 0; 562 pdr->hdr.version = 1; 563 pdr->hdr.type = PLDM_TERMINUS_LOCATOR_PDR; 564 pdr->hdr.record_change_num = 0; 565 pdr->hdr.length = sizeof(pldm_terminus_locator_pdr) - sizeof(pldm_pdr_hdr); 566 pdr->terminus_handle = BmcPldmTerminusHandle; 567 pdr->validity = PLDM_TL_PDR_VALID; 568 pdr->tid = BmcTerminusId; 569 pdr->container_id = 0x0; 570 pdr->terminus_locator_type = PLDM_TERMINUS_LOCATOR_TYPE_MCTP_EID; 571 pdr->terminus_locator_value_size = 572 sizeof(pldm_terminus_locator_type_mctp_eid); 573 auto locatorValue = reinterpret_cast<pldm_terminus_locator_type_mctp_eid*>( 574 pdr->terminus_locator_value); 575 locatorValue->eid = BmcMctpEid; 576 577 PdrEntry pdrEntry{}; 578 pdrEntry.data = pdrBuffer.data(); 579 pdrEntry.size = pdrBuffer.size(); 580 repo.addRecord(pdrEntry); 581 } 582 583 Response Handler::getStateSensorReadings(const pldm_msg* request, 584 size_t payloadLength) 585 { 586 uint16_t sensorId{}; 587 bitfield8_t sensorRearm{}; 588 uint8_t reserved{}; 589 590 if (payloadLength != PLDM_GET_SENSOR_READING_REQ_BYTES) 591 { 592 return ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH); 593 } 594 595 int rc = decode_get_state_sensor_readings_req( 596 request, payloadLength, &sensorId, &sensorRearm, &reserved); 597 598 if (rc != PLDM_SUCCESS) 599 { 600 return ccOnlyResponse(request, rc); 601 } 602 603 // 0x01 to 0x08 604 uint8_t sensorRearmCount = getBitfieldCount(sensorRearm); 605 std::vector<get_sensor_state_field> stateField(sensorRearmCount); 606 uint8_t comSensorCnt{}; 607 const pldm::utils::DBusHandler dBusIntf; 608 609 uint16_t entityType{}; 610 uint16_t entityInstance{}; 611 uint16_t stateSetId{}; 612 613 if (isOemStateSensor(*this, sensorId, sensorRearmCount, comSensorCnt, 614 entityType, entityInstance, stateSetId) && 615 oemPlatformHandler != nullptr) 616 { 617 rc = oemPlatformHandler->getOemStateSensorReadingsHandler( 618 entityType, entityInstance, stateSetId, comSensorCnt, stateField); 619 } 620 else 621 { 622 rc = platform_state_sensor::getStateSensorReadingsHandler< 623 pldm::utils::DBusHandler, Handler>(dBusIntf, *this, sensorId, 624 sensorRearmCount, comSensorCnt, 625 stateField); 626 } 627 628 if (rc != PLDM_SUCCESS) 629 { 630 return ccOnlyResponse(request, rc); 631 } 632 633 Response response(sizeof(pldm_msg_hdr) + 634 PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES + 635 sizeof(get_sensor_state_field) * comSensorCnt); 636 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 637 rc = encode_get_state_sensor_readings_resp(request->hdr.instance_id, rc, 638 comSensorCnt, stateField.data(), 639 responsePtr); 640 if (rc != PLDM_SUCCESS) 641 { 642 return ccOnlyResponse(request, rc); 643 } 644 645 return response; 646 } 647 648 bool isOemStateSensor(Handler& handler, uint16_t sensorId, 649 uint8_t sensorRearmCount, uint8_t& compSensorCnt, 650 uint16_t& entityType, uint16_t& entityInstance, 651 uint16_t& stateSetId) 652 { 653 pldm_state_sensor_pdr* pdr = nullptr; 654 655 std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)> stateSensorPdrRepo( 656 pldm_pdr_init(), pldm_pdr_destroy); 657 Repo stateSensorPDRs(stateSensorPdrRepo.get()); 658 getRepoByType(handler.getRepo(), stateSensorPDRs, PLDM_STATE_SENSOR_PDR); 659 if (stateSensorPDRs.empty()) 660 { 661 std::cerr << "Failed to get record by PDR type\n"; 662 return false; 663 } 664 665 PdrEntry pdrEntry{}; 666 auto pdrRecord = stateSensorPDRs.getFirstRecord(pdrEntry); 667 while (pdrRecord) 668 { 669 pdr = reinterpret_cast<pldm_state_sensor_pdr*>(pdrEntry.data); 670 assert(pdr != NULL); 671 if (pdr->sensor_id != sensorId) 672 { 673 pdr = nullptr; 674 pdrRecord = stateSensorPDRs.getNextRecord(pdrRecord, pdrEntry); 675 continue; 676 } 677 auto tmpEntityType = pdr->entity_type; 678 auto tmpEntityInstance = pdr->entity_instance; 679 auto tmpCompSensorCnt = pdr->composite_sensor_count; 680 auto tmpPossibleStates = 681 reinterpret_cast<state_sensor_possible_states*>( 682 pdr->possible_states); 683 auto tmpStateSetId = tmpPossibleStates->state_set_id; 684 685 if (sensorRearmCount > tmpCompSensorCnt) 686 { 687 std::cerr << "The requester sent wrong sensorRearm" 688 << " count for the sensor, SENSOR_ID=" << sensorId 689 << "SENSOR_REARM_COUNT=" << (uint16_t)sensorRearmCount 690 << "\n"; 691 break; 692 } 693 694 if ((tmpEntityType >= PLDM_OEM_ENTITY_TYPE_START && 695 tmpEntityType <= PLDM_OEM_ENTITY_TYPE_END) || 696 (tmpStateSetId >= PLDM_OEM_STATE_SET_ID_START && 697 tmpStateSetId < PLDM_OEM_STATE_SET_ID_END)) 698 { 699 entityType = tmpEntityType; 700 entityInstance = tmpEntityInstance; 701 stateSetId = tmpStateSetId; 702 compSensorCnt = tmpCompSensorCnt; 703 return true; 704 } 705 else 706 { 707 return false; 708 } 709 } 710 return false; 711 } 712 713 bool isOemStateEffecter(Handler& handler, uint16_t effecterId, 714 uint8_t compEffecterCnt, uint16_t& entityType, 715 uint16_t& entityInstance, uint16_t& stateSetId) 716 { 717 pldm_state_effecter_pdr* pdr = nullptr; 718 719 std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)> stateEffecterPdrRepo( 720 pldm_pdr_init(), pldm_pdr_destroy); 721 Repo stateEffecterPDRs(stateEffecterPdrRepo.get()); 722 getRepoByType(handler.getRepo(), stateEffecterPDRs, 723 PLDM_STATE_EFFECTER_PDR); 724 if (stateEffecterPDRs.empty()) 725 { 726 std::cerr << "Failed to get record by PDR type\n"; 727 return false; 728 } 729 730 PdrEntry pdrEntry{}; 731 auto pdrRecord = stateEffecterPDRs.getFirstRecord(pdrEntry); 732 while (pdrRecord) 733 { 734 pdr = reinterpret_cast<pldm_state_effecter_pdr*>(pdrEntry.data); 735 assert(pdr != NULL); 736 if (pdr->effecter_id != effecterId) 737 { 738 pdr = nullptr; 739 pdrRecord = stateEffecterPDRs.getNextRecord(pdrRecord, pdrEntry); 740 continue; 741 } 742 743 auto tmpEntityType = pdr->entity_type; 744 auto tmpEntityInstance = pdr->entity_instance; 745 auto tmpPossibleStates = 746 reinterpret_cast<state_effecter_possible_states*>( 747 pdr->possible_states); 748 auto tmpStateSetId = tmpPossibleStates->state_set_id; 749 750 if (compEffecterCnt > pdr->composite_effecter_count) 751 { 752 std::cerr << "The requester sent wrong composite effecter" 753 << " count for the effecter, EFFECTER_ID=" << effecterId 754 << "COMP_EFF_CNT=" << (uint16_t)compEffecterCnt << "\n"; 755 return false; 756 } 757 758 if ((tmpEntityType >= PLDM_OEM_ENTITY_TYPE_START && 759 tmpEntityType <= PLDM_OEM_ENTITY_TYPE_END) || 760 (tmpStateSetId >= PLDM_OEM_STATE_SET_ID_START && 761 tmpStateSetId < PLDM_OEM_STATE_SET_ID_END)) 762 { 763 entityType = tmpEntityType; 764 entityInstance = tmpEntityInstance; 765 stateSetId = tmpStateSetId; 766 return true; 767 } 768 else 769 { 770 return false; 771 } 772 } 773 return false; 774 } 775 776 } // namespace platform 777 } // namespace responder 778 } // namespace pldm 779