1 #include "config.h" 2 3 #include "host_pdr_handler.hpp" 4 5 #include "libpldm/requester/pldm.h" 6 7 #include <assert.h> 8 9 #include <nlohmann/json.hpp> 10 #include <sdeventplus/clock.hpp> 11 #include <sdeventplus/exception.hpp> 12 #include <sdeventplus/source/io.hpp> 13 #include <sdeventplus/source/time.hpp> 14 15 #include <fstream> 16 17 namespace pldm 18 { 19 20 using namespace pldm::dbus_api; 21 using namespace pldm::responder::events; 22 using namespace pldm::utils; 23 using namespace sdbusplus::bus::match::rules; 24 using Json = nlohmann::json; 25 namespace fs = std::filesystem; 26 constexpr auto fruJson = "host_frus.json"; 27 const Json emptyJson{}; 28 const std::vector<Json> emptyJsonList{}; 29 30 HostPDRHandler::HostPDRHandler( 31 int mctp_fd, uint8_t mctp_eid, sdeventplus::Event& event, pldm_pdr* repo, 32 const std::string& eventsJsonsDir, pldm_entity_association_tree* entityTree, 33 pldm_entity_association_tree* bmcEntityTree, Requester& requester, 34 pldm::requester::Handler<pldm::requester::Request>* handler) : 35 mctp_fd(mctp_fd), 36 mctp_eid(mctp_eid), event(event), repo(repo), 37 stateSensorHandler(eventsJsonsDir), entityTree(entityTree), 38 bmcEntityTree(bmcEntityTree), requester(requester), handler(handler) 39 { 40 fs::path hostFruJson(fs::path(HOST_JSONS_DIR) / fruJson); 41 if (fs::exists(hostFruJson)) 42 { 43 // Note parent entities for entities sent down by the host firmware. 44 // This will enable a merge of entity associations. 45 try 46 { 47 std::ifstream jsonFile(hostFruJson); 48 auto data = Json::parse(jsonFile, nullptr, false); 49 if (data.is_discarded()) 50 { 51 std::cerr << "Parsing Host FRU json file failed" << std::endl; 52 } 53 else 54 { 55 auto entities = data.value("entities", emptyJsonList); 56 for (auto& entity : entities) 57 { 58 EntityType entityType = entity.value("entity_type", 0); 59 auto parent = entity.value("parent", emptyJson); 60 pldm_entity p{}; 61 p.entity_type = parent.value("entity_type", 0); 62 p.entity_instance_num = parent.value("entity_instance", 0); 63 parents.emplace(entityType, std::move(p)); 64 } 65 } 66 } 67 catch (const std::exception& e) 68 { 69 std::cerr << "Parsing Host FRU json file failed, exception = " 70 << e.what() << std::endl; 71 } 72 } 73 74 hostOffMatch = std::make_unique<sdbusplus::bus::match::match>( 75 pldm::utils::DBusHandler::getBus(), 76 propertiesChanged("/xyz/openbmc_project/state/host0", 77 "xyz.openbmc_project.State.Host"), 78 [this, repo, entityTree, 79 bmcEntityTree](sdbusplus::message::message& msg) { 80 DbusChangedProps props{}; 81 std::string intf; 82 msg.read(intf, props); 83 const auto itr = props.find("CurrentHostState"); 84 if (itr != props.end()) 85 { 86 PropertyValue value = itr->second; 87 auto propVal = std::get<std::string>(value); 88 if (propVal == "xyz.openbmc_project.State.Host.HostState.Off") 89 { 90 // Delete all the remote terminus information 91 std::erase_if(tlPDRInfo, [](const auto& item) { 92 auto const& [key, value] = item; 93 return key != TERMINUS_HANDLE; 94 }); 95 pldm_pdr_remove_remote_pdrs(repo); 96 pldm_entity_association_tree_destroy_root(entityTree); 97 pldm_entity_association_tree_copy_root(bmcEntityTree, 98 entityTree); 99 this->sensorMap.clear(); 100 this->responseReceived = false; 101 } 102 } 103 }); 104 } 105 106 void HostPDRHandler::fetchPDR(PDRRecordHandles&& recordHandles) 107 { 108 pdrRecordHandles.clear(); 109 pdrRecordHandles = std::move(recordHandles); 110 111 // Defer the actual fetch of PDRs from the host (by queuing the call on the 112 // main event loop). That way, we can respond to the platform event msg from 113 // the host firmware. 114 pdrFetchEvent = std::make_unique<sdeventplus::source::Defer>( 115 event, std::bind(std::mem_fn(&HostPDRHandler::_fetchPDR), this, 116 std::placeholders::_1)); 117 } 118 119 void HostPDRHandler::_fetchPDR(sdeventplus::source::EventBase& /*source*/) 120 { 121 getHostPDR(); 122 } 123 124 void HostPDRHandler::getHostPDR(uint32_t nextRecordHandle) 125 { 126 pdrFetchEvent.reset(); 127 128 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) + 129 PLDM_GET_PDR_REQ_BYTES); 130 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 131 uint32_t recordHandle{}; 132 if (!nextRecordHandle) 133 { 134 if (!pdrRecordHandles.empty()) 135 { 136 recordHandle = pdrRecordHandles.front(); 137 pdrRecordHandles.pop_front(); 138 } 139 } 140 else 141 { 142 recordHandle = nextRecordHandle; 143 } 144 auto instanceId = requester.getInstanceId(mctp_eid); 145 146 auto rc = 147 encode_get_pdr_req(instanceId, recordHandle, 0, PLDM_GET_FIRSTPART, 148 UINT16_MAX, 0, request, PLDM_GET_PDR_REQ_BYTES); 149 if (rc != PLDM_SUCCESS) 150 { 151 requester.markFree(mctp_eid, instanceId); 152 std::cerr << "Failed to encode_get_pdr_req, rc = " << rc << std::endl; 153 return; 154 } 155 156 rc = handler->registerRequest( 157 mctp_eid, instanceId, PLDM_PLATFORM, PLDM_GET_PDR, 158 std::move(requestMsg), 159 std::move(std::bind_front(&HostPDRHandler::processHostPDRs, this))); 160 if (rc) 161 { 162 std::cerr << "Failed to send the GetPDR request to Host \n"; 163 } 164 } 165 166 int HostPDRHandler::handleStateSensorEvent(const StateSensorEntry& entry, 167 pdr::EventState state) 168 { 169 auto rc = stateSensorHandler.eventAction(entry, state); 170 if (rc != PLDM_SUCCESS) 171 { 172 std::cerr << "Failed to fetch and update D-bus property, rc = " << rc 173 << std::endl; 174 return rc; 175 } 176 return PLDM_SUCCESS; 177 } 178 bool HostPDRHandler::getParent(EntityType type, pldm_entity& parent) 179 { 180 auto found = parents.find(type); 181 if (found != parents.end()) 182 { 183 parent.entity_type = found->second.entity_type; 184 parent.entity_instance_num = found->second.entity_instance_num; 185 return true; 186 } 187 188 return false; 189 } 190 191 void HostPDRHandler::mergeEntityAssociations(const std::vector<uint8_t>& pdr) 192 { 193 size_t numEntities{}; 194 pldm_entity* entities = nullptr; 195 bool merged = false; 196 auto entityPdr = reinterpret_cast<pldm_pdr_entity_association*>( 197 const_cast<uint8_t*>(pdr.data()) + sizeof(pldm_pdr_hdr)); 198 199 pldm_entity_association_pdr_extract(pdr.data(), pdr.size(), &numEntities, 200 &entities); 201 for (size_t i = 0; i < numEntities; ++i) 202 { 203 pldm_entity parent{}; 204 if (getParent(entities[i].entity_type, parent)) 205 { 206 auto node = pldm_entity_association_tree_find(entityTree, &parent); 207 if (node) 208 { 209 pldm_entity_association_tree_add(entityTree, &entities[i], 210 0xFFFF, node, 211 entityPdr->association_type); 212 merged = true; 213 } 214 } 215 } 216 217 if (merged) 218 { 219 // Update our PDR repo with the merged entity association PDRs 220 pldm_entity_node* node = nullptr; 221 pldm_find_entity_ref_in_tree(entityTree, entities[0], &node); 222 if (node == nullptr) 223 { 224 std::cerr 225 << "\ncould not find referrence of the entity in the tree \n"; 226 } 227 else 228 { 229 pldm_entity_association_pdr_add_from_node(node, repo, &entities, 230 numEntities, true); 231 } 232 } 233 free(entities); 234 } 235 236 void HostPDRHandler::sendPDRRepositoryChgEvent(std::vector<uint8_t>&& pdrTypes, 237 uint8_t eventDataFormat) 238 { 239 assert(eventDataFormat == FORMAT_IS_PDR_HANDLES); 240 241 // Extract from the PDR repo record handles of PDRs we want the host 242 // to pull up. 243 std::vector<uint8_t> eventDataOps{PLDM_RECORDS_ADDED}; 244 std::vector<uint8_t> numsOfChangeEntries(1); 245 std::vector<std::vector<ChangeEntry>> changeEntries( 246 numsOfChangeEntries.size()); 247 for (auto pdrType : pdrTypes) 248 { 249 const pldm_pdr_record* record{}; 250 do 251 { 252 record = pldm_pdr_find_record_by_type(repo, pdrType, record, 253 nullptr, nullptr); 254 if (record && pldm_pdr_record_is_remote(record)) 255 { 256 changeEntries[0].push_back( 257 pldm_pdr_get_record_handle(repo, record)); 258 } 259 } while (record); 260 } 261 if (changeEntries.empty()) 262 { 263 return; 264 } 265 numsOfChangeEntries[0] = changeEntries[0].size(); 266 267 // Encode PLDM platform event msg to indicate a PDR repo change. 268 size_t maxSize = PLDM_PDR_REPOSITORY_CHG_EVENT_MIN_LENGTH + 269 PLDM_PDR_REPOSITORY_CHANGE_RECORD_MIN_LENGTH + 270 changeEntries[0].size() * sizeof(uint32_t); 271 std::vector<uint8_t> eventDataVec{}; 272 eventDataVec.resize(maxSize); 273 auto eventData = 274 reinterpret_cast<struct pldm_pdr_repository_chg_event_data*>( 275 eventDataVec.data()); 276 size_t actualSize{}; 277 auto firstEntry = changeEntries[0].data(); 278 auto rc = encode_pldm_pdr_repository_chg_event_data( 279 eventDataFormat, 1, eventDataOps.data(), numsOfChangeEntries.data(), 280 &firstEntry, eventData, &actualSize, maxSize); 281 if (rc != PLDM_SUCCESS) 282 { 283 std::cerr 284 << "Failed to encode_pldm_pdr_repository_chg_event_data, rc = " 285 << rc << std::endl; 286 return; 287 } 288 auto instanceId = requester.getInstanceId(mctp_eid); 289 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) + 290 PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES + 291 actualSize); 292 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 293 rc = encode_platform_event_message_req( 294 instanceId, 1, 0, PLDM_PDR_REPOSITORY_CHG_EVENT, eventDataVec.data(), 295 actualSize, request, 296 actualSize + PLDM_PLATFORM_EVENT_MESSAGE_MIN_REQ_BYTES); 297 if (rc != PLDM_SUCCESS) 298 { 299 requester.markFree(mctp_eid, instanceId); 300 std::cerr << "Failed to encode_platform_event_message_req, rc = " << rc 301 << std::endl; 302 return; 303 } 304 305 auto platformEventMessageResponseHandler = [](mctp_eid_t /*eid*/, 306 const pldm_msg* response, 307 size_t respMsgLen) { 308 if (response == nullptr || !respMsgLen) 309 { 310 std::cerr << "Failed to receive response for the PDR repository " 311 "changed event" 312 << "\n"; 313 return; 314 } 315 316 uint8_t completionCode{}; 317 uint8_t status{}; 318 auto responsePtr = reinterpret_cast<const struct pldm_msg*>(response); 319 auto rc = decode_platform_event_message_resp(responsePtr, respMsgLen, 320 &completionCode, &status); 321 if (rc || completionCode) 322 { 323 std::cerr << "Failed to decode_platform_event_message_resp: " 324 << "rc=" << rc 325 << ", cc=" << static_cast<unsigned>(completionCode) 326 << std::endl; 327 } 328 }; 329 330 rc = handler->registerRequest( 331 mctp_eid, instanceId, PLDM_PLATFORM, PLDM_PLATFORM_EVENT_MESSAGE, 332 std::move(requestMsg), std::move(platformEventMessageResponseHandler)); 333 if (rc) 334 { 335 std::cerr << "Failed to send the PDR repository changed event request" 336 << "\n"; 337 } 338 } 339 340 void HostPDRHandler::parseStateSensorPDRs(const PDRList& stateSensorPDRs) 341 { 342 for (const auto& pdr : stateSensorPDRs) 343 { 344 SensorEntry sensorEntry{}; 345 const auto& [terminusHandle, sensorID, sensorInfo] = 346 responder::pdr_utils::parseStateSensorPDR(pdr); 347 sensorEntry.sensorID = sensorID; 348 try 349 { 350 sensorEntry.terminusID = std::get<0>(tlPDRInfo.at(terminusHandle)); 351 } 352 // If there is no mapping for terminusHandle assign the reserved TID 353 // value of 0xFF to indicate that. 354 catch (const std::out_of_range& e) 355 { 356 sensorEntry.terminusID = PLDM_TID_RESERVED; 357 } 358 sensorMap.emplace(sensorEntry, std::move(sensorInfo)); 359 } 360 } 361 362 void HostPDRHandler::processHostPDRs(mctp_eid_t /*eid*/, 363 const pldm_msg* response, 364 size_t respMsgLen) 365 { 366 static bool merged = false; 367 static PDRList stateSensorPDRs{}; 368 uint32_t nextRecordHandle{}; 369 uint8_t tlEid = 0; 370 bool tlValid = true; 371 uint32_t rh = 0; 372 uint16_t terminusHandle = 0; 373 uint8_t tid = 0; 374 375 uint8_t completionCode{}; 376 uint32_t nextDataTransferHandle{}; 377 uint8_t transferFlag{}; 378 uint16_t respCount{}; 379 uint8_t transferCRC{}; 380 if (response == nullptr || !respMsgLen) 381 { 382 std::cerr << "Failed to receive response for the GetPDR" 383 " command \n"; 384 return; 385 } 386 387 auto rc = decode_get_pdr_resp( 388 response, respMsgLen /*- sizeof(pldm_msg_hdr)*/, &completionCode, 389 &nextRecordHandle, &nextDataTransferHandle, &transferFlag, &respCount, 390 nullptr, 0, &transferCRC); 391 std::vector<uint8_t> responsePDRMsg; 392 responsePDRMsg.resize(respMsgLen + sizeof(pldm_msg_hdr)); 393 memcpy(responsePDRMsg.data(), response, respMsgLen + sizeof(pldm_msg_hdr)); 394 if (rc != PLDM_SUCCESS) 395 { 396 std::cerr << "Failed to decode_get_pdr_resp, rc = " << rc << std::endl; 397 return; 398 } 399 else 400 { 401 std::vector<uint8_t> pdr(respCount, 0); 402 rc = decode_get_pdr_resp(response, respMsgLen, &completionCode, 403 &nextRecordHandle, &nextDataTransferHandle, 404 &transferFlag, &respCount, pdr.data(), 405 respCount, &transferCRC); 406 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS) 407 { 408 std::cerr << "Failed to decode_get_pdr_resp: " 409 << "rc=" << rc 410 << ", cc=" << static_cast<unsigned>(completionCode) 411 << std::endl; 412 return; 413 } 414 else 415 { 416 // when nextRecordHandle is 0, we need the recordHandle of the last 417 // PDR and not 0-1. 418 if (!nextRecordHandle) 419 { 420 rh = nextRecordHandle; 421 } 422 else 423 { 424 rh = nextRecordHandle - 1; 425 } 426 427 auto pdrHdr = reinterpret_cast<pldm_pdr_hdr*>(pdr.data()); 428 if (!rh) 429 { 430 rh = pdrHdr->record_handle; 431 } 432 433 if (pdrHdr->type == PLDM_PDR_ENTITY_ASSOCIATION) 434 { 435 this->mergeEntityAssociations(pdr); 436 merged = true; 437 } 438 else 439 { 440 if (pdrHdr->type == PLDM_TERMINUS_LOCATOR_PDR) 441 { 442 auto tlpdr = 443 reinterpret_cast<const pldm_terminus_locator_pdr*>( 444 pdr.data()); 445 446 terminusHandle = tlpdr->terminus_handle; 447 tid = tlpdr->tid; 448 auto terminus_locator_type = tlpdr->terminus_locator_type; 449 if (terminus_locator_type == 450 PLDM_TERMINUS_LOCATOR_TYPE_MCTP_EID) 451 { 452 auto locatorValue = reinterpret_cast< 453 const pldm_terminus_locator_type_mctp_eid*>( 454 tlpdr->terminus_locator_value); 455 tlEid = static_cast<uint8_t>(locatorValue->eid); 456 } 457 if (tlpdr->validity == 0) 458 { 459 tlValid = false; 460 } 461 tlPDRInfo.insert_or_assign( 462 tlpdr->terminus_handle, 463 std::make_tuple(tlpdr->tid, tlEid, tlpdr->validity)); 464 } 465 else if (pdrHdr->type == PLDM_STATE_SENSOR_PDR) 466 { 467 stateSensorPDRs.emplace_back(pdr); 468 } 469 470 // if the TLPDR is invalid update the repo accordingly 471 if (!tlValid) 472 { 473 pldm_pdr_update_TL_pdr(repo, terminusHandle, tid, tlEid, 474 tlValid); 475 } 476 else 477 { 478 pldm_pdr_add(repo, pdr.data(), respCount, rh, true); 479 } 480 } 481 } 482 } 483 if (!nextRecordHandle) 484 { 485 /*received last record*/ 486 this->parseStateSensorPDRs(stateSensorPDRs); 487 if (isHostUp()) 488 { 489 this->setHostSensorState(stateSensorPDRs); 490 } 491 stateSensorPDRs.clear(); 492 if (merged) 493 { 494 merged = false; 495 deferredPDRRepoChgEvent = 496 std::make_unique<sdeventplus::source::Defer>( 497 event, 498 std::bind( 499 std::mem_fn((&HostPDRHandler::_processPDRRepoChgEvent)), 500 this, std::placeholders::_1)); 501 } 502 } 503 else 504 { 505 deferredFetchPDREvent = std::make_unique<sdeventplus::source::Defer>( 506 event, 507 std::bind(std::mem_fn((&HostPDRHandler::_processFetchPDREvent)), 508 this, nextRecordHandle, std::placeholders::_1)); 509 } 510 } 511 512 void HostPDRHandler::_processPDRRepoChgEvent( 513 sdeventplus::source::EventBase& /*source */) 514 { 515 deferredPDRRepoChgEvent.reset(); 516 this->sendPDRRepositoryChgEvent( 517 std::move(std::vector<uint8_t>(1, PLDM_PDR_ENTITY_ASSOCIATION)), 518 FORMAT_IS_PDR_HANDLES); 519 } 520 521 void HostPDRHandler::_processFetchPDREvent( 522 uint32_t nextRecordHandle, sdeventplus::source::EventBase& /*source */) 523 { 524 deferredFetchPDREvent.reset(); 525 if (!this->pdrRecordHandles.empty()) 526 { 527 nextRecordHandle = this->pdrRecordHandles.front(); 528 this->pdrRecordHandles.pop_front(); 529 } 530 this->getHostPDR(nextRecordHandle); 531 } 532 533 void HostPDRHandler::setHostFirmwareCondition() 534 { 535 responseReceived = false; 536 auto instanceId = requester.getInstanceId(mctp_eid); 537 std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) + 538 PLDM_GET_VERSION_REQ_BYTES); 539 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 540 auto rc = encode_get_version_req(instanceId, 0, PLDM_GET_FIRSTPART, 541 PLDM_BASE, request); 542 if (rc != PLDM_SUCCESS) 543 { 544 std::cerr << "GetPLDMVersion encode failure. PLDM error code = " 545 << std::hex << std::showbase << rc << "\n"; 546 requester.markFree(mctp_eid, instanceId); 547 return; 548 } 549 550 auto getPLDMVersionHandler = [this](mctp_eid_t /*eid*/, 551 const pldm_msg* response, 552 size_t respMsgLen) { 553 if (response == nullptr || !respMsgLen) 554 { 555 std::cerr << "Failed to receive response for " 556 << "getPLDMVersion command, Host seems to be off \n"; 557 return; 558 } 559 std::cout << "Getting the response. PLDM RC = " << std::hex 560 << std::showbase 561 << static_cast<uint16_t>(response->payload[0]) << "\n"; 562 this->responseReceived = true; 563 getHostPDR(); 564 }; 565 rc = handler->registerRequest(mctp_eid, instanceId, PLDM_BASE, 566 PLDM_GET_PLDM_VERSION, std::move(requestMsg), 567 std::move(getPLDMVersionHandler)); 568 if (rc) 569 { 570 std::cerr << "Failed to discover Host state. Assuming Host as off \n"; 571 } 572 } 573 574 bool HostPDRHandler::isHostUp() 575 { 576 return responseReceived; 577 } 578 579 void HostPDRHandler::setHostSensorState(const PDRList& stateSensorPDRs) 580 { 581 for (const auto& stateSensorPDR : stateSensorPDRs) 582 { 583 auto pdr = reinterpret_cast<const pldm_state_sensor_pdr*>( 584 stateSensorPDR.data()); 585 586 if (!pdr) 587 { 588 std::cerr << "Failed to get State sensor PDR" << std::endl; 589 pldm::utils::reportError( 590 "xyz.openbmc_project.bmc.pldm.InternalFailure"); 591 return; 592 } 593 594 uint16_t sensorId = pdr->sensor_id; 595 596 for (const auto& [terminusHandle, terminusInfo] : tlPDRInfo) 597 { 598 if (terminusHandle == pdr->terminus_handle) 599 { 600 if (std::get<2>(terminusInfo) == PLDM_TL_PDR_VALID) 601 { 602 mctp_eid = std::get<1>(terminusInfo); 603 } 604 605 bitfield8_t sensorRearm; 606 sensorRearm.byte = 0; 607 uint8_t tid = std::get<0>(terminusInfo); 608 609 auto instanceId = requester.getInstanceId(mctp_eid); 610 std::vector<uint8_t> requestMsg( 611 sizeof(pldm_msg_hdr) + 612 PLDM_GET_STATE_SENSOR_READINGS_REQ_BYTES); 613 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 614 auto rc = encode_get_state_sensor_readings_req( 615 instanceId, sensorId, sensorRearm, 0, request); 616 617 if (rc != PLDM_SUCCESS) 618 { 619 requester.markFree(mctp_eid, instanceId); 620 std::cerr << "Failed to " 621 "encode_get_state_sensor_readings_req, rc = " 622 << rc << std::endl; 623 pldm::utils::reportError( 624 "xyz.openbmc_project.bmc.pldm.InternalFailure"); 625 return; 626 } 627 628 auto getStateSensorReadingRespHandler = [=, this]( 629 mctp_eid_t /*eid*/, 630 const pldm_msg* 631 response, 632 size_t respMsgLen) { 633 if (response == nullptr || !respMsgLen) 634 { 635 std::cerr << "Failed to receive response for " 636 "getStateSensorReading command \n"; 637 return; 638 } 639 std::array<get_sensor_state_field, 8> stateField{}; 640 uint8_t completionCode = 0; 641 uint8_t comp_sensor_count = 0; 642 643 auto rc = decode_get_state_sensor_readings_resp( 644 response, respMsgLen, &completionCode, 645 &comp_sensor_count, stateField.data()); 646 647 if (rc != PLDM_SUCCESS || completionCode != PLDM_SUCCESS) 648 { 649 std::cerr 650 << "Failed to " 651 "decode_get_state_sensor_readings_resp, rc = " 652 << rc 653 << " cc=" << static_cast<unsigned>(completionCode) 654 << std::endl; 655 pldm::utils::reportError( 656 "xyz.openbmc_project.bmc.pldm.InternalFailure"); 657 } 658 659 uint8_t eventState; 660 uint8_t previousEventState; 661 uint8_t sensorOffset = comp_sensor_count - 1; 662 663 for (size_t i = 0; i < comp_sensor_count; i++) 664 { 665 eventState = stateField[i].present_state; 666 previousEventState = stateField[i].previous_state; 667 668 emitStateSensorEventSignal(tid, sensorId, sensorOffset, 669 eventState, 670 previousEventState); 671 672 SensorEntry sensorEntry{tid, sensorId}; 673 674 pldm::pdr::EntityInfo entityInfo{}; 675 pldm::pdr::CompositeSensorStates 676 compositeSensorStates{}; 677 678 try 679 { 680 std::tie(entityInfo, compositeSensorStates) = 681 lookupSensorInfo(sensorEntry); 682 } 683 catch (const std::out_of_range& e) 684 { 685 try 686 { 687 sensorEntry.terminusID = PLDM_TID_RESERVED; 688 std::tie(entityInfo, compositeSensorStates) = 689 lookupSensorInfo(sensorEntry); 690 } 691 catch (const std::out_of_range& e) 692 { 693 std::cerr << "No mapping for the events" 694 << std::endl; 695 } 696 } 697 698 if (sensorOffset > compositeSensorStates.size()) 699 { 700 std::cerr 701 << " Error Invalid data, Invalid sensor offset" 702 << std::endl; 703 return; 704 } 705 706 const auto& possibleStates = 707 compositeSensorStates[sensorOffset]; 708 if (possibleStates.find(eventState) == 709 possibleStates.end()) 710 { 711 std::cerr 712 << " Error invalid_data, Invalid event state" 713 << std::endl; 714 return; 715 } 716 const auto& [containerId, entityType, entityInstance] = 717 entityInfo; 718 pldm::responder::events::StateSensorEntry 719 stateSensorEntry{containerId, entityType, 720 entityInstance, sensorOffset}; 721 handleStateSensorEvent(stateSensorEntry, eventState); 722 } 723 }; 724 725 rc = handler->registerRequest( 726 mctp_eid, instanceId, PLDM_PLATFORM, 727 PLDM_GET_STATE_SENSOR_READINGS, std::move(requestMsg), 728 std::move(getStateSensorReadingRespHandler)); 729 730 if (rc != PLDM_SUCCESS) 731 { 732 std::cerr << " Failed to send request to get State sensor " 733 "reading on Host " 734 << std::endl; 735 } 736 } 737 } 738 } 739 } 740 } // namespace pldm 741