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