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