1 2 #include "platform.hpp" 3 4 #include "common/utils.hpp" 5 #include "event_parser.hpp" 6 #include "pdr.hpp" 7 #include "pdr_numeric_effecter.hpp" 8 #include "pdr_state_effecter.hpp" 9 #include "pdr_state_sensor.hpp" 10 #include "pdr_utils.hpp" 11 #include "platform_numeric_effecter.hpp" 12 #include "platform_state_effecter.hpp" 13 #include "platform_state_sensor.hpp" 14 15 namespace pldm 16 { 17 namespace responder 18 { 19 namespace platform 20 { 21 22 using InternalFailure = 23 sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; 24 25 static const Json empty{}; 26 27 using EventEntryMap = std::map<EventEntry, DBusInfo>; 28 29 const EventEntryMap eventEntryMap = { 30 { 31 0x01010007, // SensorID for VMI Port 0 ipv4 = 7, SensorOffset for the 32 // State Set ID 15 = 1 & PLDM State Set Enumeration List = 1 33 // (Valid Configuration) 34 {"/xyz/openbmc_project/network/hypervisor/eth0/ipv4/addr0", 35 "xyz.openbmc_project.Object.Enable", "Enabled", "bool", true}, 36 }, 37 { 38 0x02010007, // SensorID for VMI Port 0 ipv4 = 7, SensorOffset for the 39 // State Set ID 15 = 1 & PLDM State Set Enumeration List = 2 40 // (Invalid Configuration) 41 {"/xyz/openbmc_project/network/hypervisor/eth0/ipv4/addr0", 42 "xyz.openbmc_project.Object.Enable", "Enabled", "bool", false}, 43 }, 44 { 45 0x01010008, // SensorID for VMI Port 1 ipv4 = 8, SensorOffset for the 46 // State Set ID 15 = 1 & PLDM State Set Enumeration List = 1 47 // (Valid Configuration) 48 {"/xyz/openbmc_project/network/hypervisor/eth1/ipv4/addr0", 49 "xyz.openbmc_project.Object.Enable", "Enabled", "bool", true}, 50 }, 51 { 52 0x02010008, // SensorID for VMI Port 1 ipv4 = 8, SensorOffset for the 53 // State Set ID 15 = 1 & PLDM State Set Enumeration List = 2 54 // (Invalid Configuration) 55 {"/xyz/openbmc_project/network/hypervisor/eth1/ipv4/addr0", 56 "xyz.openbmc_project.Object.Enable", "Enabled", "bool", false}, 57 }}; 58 59 void Handler::addDbusObjMaps( 60 uint16_t id, 61 std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps> dbusObj, 62 TypeId typeId) 63 { 64 if (typeId == TypeId::PLDM_SENSOR_ID) 65 { 66 sensorDbusObjMaps.emplace(id, dbusObj); 67 } 68 else 69 { 70 effecterDbusObjMaps.emplace(id, dbusObj); 71 } 72 } 73 74 const std::tuple<pdr_utils::DbusMappings, pdr_utils::DbusValMaps>& 75 Handler::getDbusObjMaps(uint16_t id, TypeId typeId) const 76 { 77 if (typeId == TypeId::PLDM_SENSOR_ID) 78 { 79 return sensorDbusObjMaps.at(id); 80 } 81 else 82 { 83 return effecterDbusObjMaps.at(id); 84 } 85 } 86 87 void Handler::generate(const pldm::utils::DBusHandler& dBusIntf, 88 const std::string& dir, Repo& repo) 89 { 90 if (!fs::exists(dir)) 91 { 92 return; 93 } 94 95 // A map of PDR type to a lambda that handles creation of that PDR type. 96 // The lambda essentially would parse the platform specific PDR JSONs to 97 // generate the PDR structures. This function iterates through the map to 98 // invoke all lambdas, so that all PDR types can be created. 99 100 const std::map<Type, generatePDR> generateHandlers = { 101 {PLDM_STATE_EFFECTER_PDR, 102 [this](const DBusHandler& dBusIntf, const auto& json, 103 RepoInterface& repo) { 104 pdr_state_effecter::generateStateEffecterPDR< 105 pldm::utils::DBusHandler, Handler>(dBusIntf, json, *this, 106 repo); 107 }}, 108 {PLDM_NUMERIC_EFFECTER_PDR, 109 [this](const DBusHandler& dBusIntf, const auto& json, 110 RepoInterface& repo) { 111 pdr_numeric_effecter::generateNumericEffecterPDR< 112 pldm::utils::DBusHandler, Handler>(dBusIntf, json, *this, 113 repo); 114 }}, 115 {PLDM_STATE_SENSOR_PDR, [this](const DBusHandler& dBusIntf, 116 const auto& json, RepoInterface& repo) { 117 pdr_state_sensor::generateStateSensorPDR<pldm::utils::DBusHandler, 118 Handler>(dBusIntf, json, 119 *this, repo); 120 }}}; 121 122 Type pdrType{}; 123 for (const auto& dirEntry : fs::directory_iterator(dir)) 124 { 125 try 126 { 127 auto json = readJson(dirEntry.path().string()); 128 if (!json.empty()) 129 { 130 auto effecterPDRs = json.value("effecterPDRs", empty); 131 for (const auto& effecter : effecterPDRs) 132 { 133 pdrType = effecter.value("pdrType", 0); 134 generateHandlers.at(pdrType)(dBusIntf, effecter, repo); 135 } 136 137 auto sensorPDRs = json.value("sensorPDRs", empty); 138 for (const auto& sensor : sensorPDRs) 139 { 140 pdrType = sensor.value("pdrType", 0); 141 generateHandlers.at(pdrType)(dBusIntf, sensor, repo); 142 } 143 } 144 } 145 catch (const InternalFailure& e) 146 { 147 std::cerr << "PDR config directory does not exist or empty, TYPE= " 148 << pdrType << "PATH= " << dirEntry 149 << " ERROR=" << e.what() << "\n"; 150 } 151 catch (const Json::exception& e) 152 { 153 std::cerr << "Failed parsing PDR JSON file, TYPE= " << pdrType 154 << " ERROR=" << e.what() << "\n"; 155 pldm::utils::reportError( 156 "xyz.openbmc_project.bmc.pldm.InternalFailure"); 157 } 158 catch (const std::exception& e) 159 { 160 std::cerr << "Failed parsing PDR JSON file, TYPE= " << pdrType 161 << " ERROR=" << e.what() << "\n"; 162 pldm::utils::reportError( 163 "xyz.openbmc_project.bmc.pldm.InternalFailure"); 164 } 165 } 166 } 167 168 Response Handler::getPDR(const pldm_msg* request, size_t payloadLength) 169 { 170 if (!pdrCreated) 171 { 172 generateTerminusLocatorPDR(pdrRepo); 173 generate(*dBusIntf, pdrJsonsDir, pdrRepo); 174 pdrCreated = true; 175 } 176 177 // Build FRU table if not built, since entity association PDR's are built 178 // when the FRU table is constructed. 179 if (fruHandler) 180 { 181 fruHandler->buildFRUTable(); 182 } 183 184 Response response(sizeof(pldm_msg_hdr) + PLDM_GET_PDR_MIN_RESP_BYTES, 0); 185 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 186 187 if (payloadLength != PLDM_GET_PDR_REQ_BYTES) 188 { 189 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH); 190 } 191 192 uint32_t recordHandle{}; 193 uint32_t dataTransferHandle{}; 194 uint8_t transferOpFlag{}; 195 uint16_t reqSizeBytes{}; 196 uint16_t recordChangeNum{}; 197 198 auto rc = decode_get_pdr_req(request, payloadLength, &recordHandle, 199 &dataTransferHandle, &transferOpFlag, 200 &reqSizeBytes, &recordChangeNum); 201 if (rc != PLDM_SUCCESS) 202 { 203 return CmdHandler::ccOnlyResponse(request, rc); 204 } 205 206 uint16_t respSizeBytes{}; 207 uint8_t* recordData = nullptr; 208 try 209 { 210 pdr_utils::PdrEntry e; 211 auto record = pdr::getRecordByHandle(pdrRepo, recordHandle, e); 212 if (record == NULL) 213 { 214 return CmdHandler::ccOnlyResponse( 215 request, PLDM_PLATFORM_INVALID_RECORD_HANDLE); 216 } 217 218 if (reqSizeBytes) 219 { 220 respSizeBytes = e.size; 221 if (respSizeBytes > reqSizeBytes) 222 { 223 respSizeBytes = reqSizeBytes; 224 } 225 recordData = e.data; 226 } 227 response.resize(sizeof(pldm_msg_hdr) + PLDM_GET_PDR_MIN_RESP_BYTES + 228 respSizeBytes, 229 0); 230 responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 231 rc = encode_get_pdr_resp( 232 request->hdr.instance_id, PLDM_SUCCESS, e.handle.nextRecordHandle, 233 0, PLDM_START_AND_END, respSizeBytes, recordData, 0, responsePtr); 234 if (rc != PLDM_SUCCESS) 235 { 236 return ccOnlyResponse(request, rc); 237 } 238 } 239 catch (const std::exception& e) 240 { 241 std::cerr << "Error accessing PDR, HANDLE=" << recordHandle 242 << " ERROR=" << e.what() << "\n"; 243 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR); 244 } 245 return response; 246 } 247 248 Response Handler::setStateEffecterStates(const pldm_msg* request, 249 size_t payloadLength) 250 { 251 Response response( 252 sizeof(pldm_msg_hdr) + PLDM_SET_STATE_EFFECTER_STATES_RESP_BYTES, 0); 253 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 254 uint16_t effecterId; 255 uint8_t compEffecterCnt; 256 constexpr auto maxCompositeEffecterCnt = 8; 257 std::vector<set_effecter_state_field> stateField(maxCompositeEffecterCnt, 258 {0, 0}); 259 260 if ((payloadLength > PLDM_SET_STATE_EFFECTER_STATES_REQ_BYTES) || 261 (payloadLength < sizeof(effecterId) + sizeof(compEffecterCnt) + 262 sizeof(set_effecter_state_field))) 263 { 264 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH); 265 } 266 267 int rc = decode_set_state_effecter_states_req(request, payloadLength, 268 &effecterId, &compEffecterCnt, 269 stateField.data()); 270 271 if (rc != PLDM_SUCCESS) 272 { 273 return CmdHandler::ccOnlyResponse(request, rc); 274 } 275 276 stateField.resize(compEffecterCnt); 277 const pldm::utils::DBusHandler dBusIntf; 278 rc = platform_state_effecter::setStateEffecterStatesHandler< 279 pldm::utils::DBusHandler, Handler>(dBusIntf, *this, effecterId, 280 stateField); 281 if (rc != PLDM_SUCCESS) 282 { 283 return CmdHandler::ccOnlyResponse(request, rc); 284 } 285 286 rc = encode_set_state_effecter_states_resp(request->hdr.instance_id, rc, 287 responsePtr); 288 if (rc != PLDM_SUCCESS) 289 { 290 return ccOnlyResponse(request, rc); 291 } 292 293 return response; 294 } 295 296 Response Handler::platformEventMessage(const pldm_msg* request, 297 size_t payloadLength) 298 { 299 uint8_t formatVersion{}; 300 uint8_t tid{}; 301 uint8_t eventClass{}; 302 size_t offset{}; 303 304 auto rc = decode_platform_event_message_req( 305 request, payloadLength, &formatVersion, &tid, &eventClass, &offset); 306 if (rc != PLDM_SUCCESS) 307 { 308 return CmdHandler::ccOnlyResponse(request, rc); 309 } 310 311 try 312 { 313 const auto& handlers = eventHandlers.at(eventClass); 314 for (const auto& handler : handlers) 315 { 316 auto rc = 317 handler(request, payloadLength, formatVersion, tid, offset); 318 if (rc != PLDM_SUCCESS) 319 { 320 return CmdHandler::ccOnlyResponse(request, rc); 321 } 322 } 323 } 324 catch (const std::out_of_range& e) 325 { 326 return CmdHandler::ccOnlyResponse(request, PLDM_ERROR_INVALID_DATA); 327 } 328 329 Response response( 330 sizeof(pldm_msg_hdr) + PLDM_PLATFORM_EVENT_MESSAGE_RESP_BYTES, 0); 331 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 332 333 rc = encode_platform_event_message_resp(request->hdr.instance_id, rc, 334 PLDM_EVENT_NO_LOGGING, responsePtr); 335 if (rc != PLDM_SUCCESS) 336 { 337 return ccOnlyResponse(request, rc); 338 } 339 340 return response; 341 } 342 343 int Handler::sensorEvent(const pldm_msg* request, size_t payloadLength, 344 uint8_t /*formatVersion*/, uint8_t tid, 345 size_t eventDataOffset) 346 { 347 uint16_t sensorId{}; 348 uint8_t eventClass{}; 349 size_t eventClassDataOffset{}; 350 auto eventData = 351 reinterpret_cast<const uint8_t*>(request->payload) + eventDataOffset; 352 auto eventDataSize = payloadLength - eventDataOffset; 353 354 auto rc = decode_sensor_event_data(eventData, eventDataSize, &sensorId, 355 &eventClass, &eventClassDataOffset); 356 if (rc != PLDM_SUCCESS) 357 { 358 return rc; 359 } 360 361 auto eventClassData = reinterpret_cast<const uint8_t*>(request->payload) + 362 eventDataOffset + eventClassDataOffset; 363 auto eventClassDataSize = 364 payloadLength - eventDataOffset - eventClassDataOffset; 365 366 if (eventClass == PLDM_STATE_SENSOR_STATE) 367 { 368 uint8_t sensorOffset{}; 369 uint8_t eventState{}; 370 uint8_t previousEventState{}; 371 372 rc = decode_state_sensor_data(eventClassData, eventClassDataSize, 373 &sensorOffset, &eventState, 374 &previousEventState); 375 if (rc != PLDM_SUCCESS) 376 { 377 return PLDM_ERROR; 378 } 379 380 // Emitting state sensor event signal 381 emitStateSensorEventSignal(tid, sensorId, sensorOffset, eventState, 382 previousEventState); 383 384 // Handle PLDM events for which PDR is not available, setSensorEventData 385 // will return PLDM_ERROR_INVALID_DATA if the sensorID is not found in 386 // the hardcoded sensor list. 387 rc = setSensorEventData(sensorId, sensorOffset, eventState); 388 if (rc != PLDM_ERROR_INVALID_DATA) 389 { 390 return rc; 391 } 392 393 // If there are no HOST PDR's, there is no further action 394 if (hostPDRHandler == NULL) 395 { 396 return PLDM_SUCCESS; 397 } 398 399 // Handle PLDM events for which PDR is available 400 SensorEntry sensorEntry{tid, sensorId}; 401 try 402 { 403 const auto& [entityInfo, compositeSensorStates] = 404 hostPDRHandler->lookupSensorInfo(sensorEntry); 405 if (sensorOffset >= compositeSensorStates.size()) 406 { 407 return PLDM_ERROR_INVALID_DATA; 408 } 409 410 const auto& possibleStates = compositeSensorStates[sensorOffset]; 411 if (possibleStates.find(eventState) == possibleStates.end()) 412 { 413 return PLDM_ERROR_INVALID_DATA; 414 } 415 416 const auto& [containerId, entityType, entityInstance] = entityInfo; 417 events::StateSensorEntry stateSensorEntry{ 418 containerId, entityType, entityInstance, sensorOffset}; 419 return stateSensorHandler.eventAction(stateSensorEntry, eventState); 420 } 421 // If there is no mapping for events return PLDM_SUCCESS 422 catch (const std::out_of_range& e) 423 { 424 return PLDM_SUCCESS; 425 } 426 } 427 else 428 { 429 return PLDM_ERROR_INVALID_DATA; 430 } 431 432 return PLDM_SUCCESS; 433 } 434 435 int Handler::setSensorEventData(uint16_t sensorId, uint8_t sensorOffset, 436 uint8_t eventState) 437 { 438 EventEntry eventEntry = ((static_cast<uint32_t>(eventState)) << 24) + 439 ((static_cast<uint32_t>(sensorOffset)) << 16) + 440 sensorId; 441 auto iter = eventEntryMap.find(eventEntry); 442 if (iter == eventEntryMap.end()) 443 { 444 return PLDM_ERROR_INVALID_DATA; 445 } 446 447 const auto& dBusInfo = iter->second; 448 try 449 { 450 pldm::utils::DBusMapping dbusMapping{ 451 dBusInfo.dBusValues.objectPath, dBusInfo.dBusValues.interface, 452 dBusInfo.dBusValues.propertyName, dBusInfo.dBusValues.propertyType}; 453 pldm::utils::DBusHandler().setDbusProperty(dbusMapping, 454 dBusInfo.dBusPropertyValue); 455 } 456 catch (std::exception& e) 457 { 458 std::cerr 459 << "Error Setting dbus property,SensorID=" << eventEntry 460 << "DBusInfo=" << dBusInfo.dBusValues.objectPath 461 << dBusInfo.dBusValues.interface << dBusInfo.dBusValues.propertyName 462 << "ERROR=" << e.what() << "\n"; 463 return PLDM_ERROR; 464 } 465 return PLDM_SUCCESS; 466 } 467 468 int Handler::pldmPDRRepositoryChgEvent(const pldm_msg* request, 469 size_t payloadLength, 470 uint8_t /*formatVersion*/, 471 uint8_t /*tid*/, size_t eventDataOffset) 472 { 473 uint8_t eventDataFormat{}; 474 uint8_t numberOfChangeRecords{}; 475 size_t dataOffset{}; 476 477 auto eventData = 478 reinterpret_cast<const uint8_t*>(request->payload) + eventDataOffset; 479 auto eventDataSize = payloadLength - eventDataOffset; 480 481 auto rc = decode_pldm_pdr_repository_chg_event_data( 482 eventData, eventDataSize, &eventDataFormat, &numberOfChangeRecords, 483 &dataOffset); 484 if (rc != PLDM_SUCCESS) 485 { 486 return rc; 487 } 488 489 PDRRecordHandles pdrRecordHandles; 490 491 if (eventDataFormat == FORMAT_IS_PDR_TYPES) 492 { 493 return PLDM_ERROR_INVALID_DATA; 494 } 495 496 if (eventDataFormat == FORMAT_IS_PDR_HANDLES) 497 { 498 uint8_t eventDataOperation{}; 499 uint8_t numberOfChangeEntries{}; 500 501 auto changeRecordData = eventData + dataOffset; 502 auto changeRecordDataSize = eventDataSize - dataOffset; 503 504 while (changeRecordDataSize) 505 { 506 rc = decode_pldm_pdr_repository_change_record_data( 507 changeRecordData, changeRecordDataSize, &eventDataOperation, 508 &numberOfChangeEntries, &dataOffset); 509 510 if (rc != PLDM_SUCCESS) 511 { 512 return rc; 513 } 514 515 if (eventDataOperation == PLDM_RECORDS_ADDED) 516 { 517 rc = getPDRRecordHandles( 518 reinterpret_cast<const ChangeEntry*>(changeRecordData + 519 dataOffset), 520 changeRecordDataSize - dataOffset, 521 static_cast<size_t>(numberOfChangeEntries), 522 pdrRecordHandles); 523 524 if (rc != PLDM_SUCCESS) 525 { 526 return rc; 527 } 528 } 529 530 changeRecordData += 531 dataOffset + (numberOfChangeEntries * sizeof(ChangeEntry)); 532 changeRecordDataSize -= 533 dataOffset + (numberOfChangeEntries * sizeof(ChangeEntry)); 534 } 535 } 536 if (hostPDRHandler) 537 { 538 hostPDRHandler->fetchPDR(std::move(pdrRecordHandles)); 539 } 540 541 return PLDM_SUCCESS; 542 } 543 544 int Handler::getPDRRecordHandles(const ChangeEntry* changeEntryData, 545 size_t changeEntryDataSize, 546 size_t numberOfChangeEntries, 547 PDRRecordHandles& pdrRecordHandles) 548 { 549 if (numberOfChangeEntries > (changeEntryDataSize / sizeof(ChangeEntry))) 550 { 551 return PLDM_ERROR_INVALID_DATA; 552 } 553 for (size_t i = 0; i < numberOfChangeEntries; i++) 554 { 555 pdrRecordHandles.push_back(changeEntryData[i]); 556 } 557 return PLDM_SUCCESS; 558 } 559 560 Response Handler::setNumericEffecterValue(const pldm_msg* request, 561 size_t payloadLength) 562 { 563 Response response(sizeof(pldm_msg_hdr) + 564 PLDM_SET_NUMERIC_EFFECTER_VALUE_RESP_BYTES); 565 uint16_t effecterId{}; 566 uint8_t effecterDataSize{}; 567 uint8_t effecterValue[4] = {}; 568 569 if ((payloadLength > sizeof(effecterId) + sizeof(effecterDataSize) + 570 sizeof(union_effecter_data_size)) || 571 (payloadLength < sizeof(effecterId) + sizeof(effecterDataSize) + 1)) 572 { 573 return ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH); 574 } 575 576 int rc = decode_set_numeric_effecter_value_req( 577 request, payloadLength, &effecterId, &effecterDataSize, 578 reinterpret_cast<uint8_t*>(&effecterValue)); 579 580 if (rc == PLDM_SUCCESS) 581 { 582 const pldm::utils::DBusHandler dBusIntf; 583 rc = platform_numeric_effecter::setNumericEffecterValueHandler< 584 pldm::utils::DBusHandler, Handler>(dBusIntf, *this, effecterId, 585 effecterDataSize, effecterValue, 586 sizeof(effecterValue)); 587 } 588 589 return ccOnlyResponse(request, rc); 590 } 591 592 void Handler::generateTerminusLocatorPDR(Repo& repo) 593 { 594 std::vector<uint8_t> pdrBuffer(sizeof(pldm_terminus_locator_pdr)); 595 596 auto pdr = reinterpret_cast<pldm_terminus_locator_pdr*>(pdrBuffer.data()); 597 598 pdr->hdr.record_handle = 0; 599 pdr->hdr.version = 1; 600 pdr->hdr.type = PLDM_TERMINUS_LOCATOR_PDR; 601 pdr->hdr.record_change_num = 0; 602 pdr->hdr.length = sizeof(pldm_terminus_locator_pdr) - sizeof(pldm_pdr_hdr); 603 pdr->terminus_handle = BmcPldmTerminusHandle; 604 pdr->validity = PLDM_TL_PDR_VALID; 605 pdr->tid = BmcTerminusId; 606 pdr->container_id = 0x0; 607 pdr->terminus_locator_type = PLDM_TERMINUS_LOCATOR_TYPE_MCTP_EID; 608 pdr->terminus_locator_value_size = 609 sizeof(pldm_terminus_locator_type_mctp_eid); 610 auto locatorValue = reinterpret_cast<pldm_terminus_locator_type_mctp_eid*>( 611 pdr->terminus_locator_value); 612 locatorValue->eid = BmcMctpEid; 613 614 PdrEntry pdrEntry{}; 615 pdrEntry.data = pdrBuffer.data(); 616 pdrEntry.size = pdrBuffer.size(); 617 repo.addRecord(pdrEntry); 618 } 619 620 Response Handler::getStateSensorReadings(const pldm_msg* request, 621 size_t payloadLength) 622 { 623 uint16_t sensorId{}; 624 bitfield8_t sensorRearm{}; 625 uint8_t reserved{}; 626 627 if (payloadLength != PLDM_GET_SENSOR_READING_REQ_BYTES) 628 { 629 return ccOnlyResponse(request, PLDM_ERROR_INVALID_LENGTH); 630 } 631 632 int rc = decode_get_state_sensor_readings_req( 633 request, payloadLength, &sensorId, &sensorRearm, &reserved); 634 635 if (rc != PLDM_SUCCESS) 636 { 637 return ccOnlyResponse(request, rc); 638 } 639 640 // 0x01 to 0x08 641 uint8_t sensorRearmCout = getBitfieldCount(sensorRearm); 642 std::vector<get_sensor_state_field> stateField(sensorRearmCout); 643 uint8_t comSensorCnt{}; 644 const pldm::utils::DBusHandler dBusIntf; 645 rc = platform_state_sensor::getStateSensorReadingsHandler< 646 pldm::utils::DBusHandler, Handler>( 647 dBusIntf, *this, sensorId, sensorRearmCout, comSensorCnt, stateField); 648 649 if (rc != PLDM_SUCCESS) 650 { 651 return ccOnlyResponse(request, rc); 652 } 653 654 Response response(sizeof(pldm_msg_hdr) + 655 PLDM_GET_STATE_SENSOR_READINGS_MIN_RESP_BYTES + 656 sizeof(get_sensor_state_field) * comSensorCnt); 657 auto responsePtr = reinterpret_cast<pldm_msg*>(response.data()); 658 rc = encode_get_state_sensor_readings_resp(request->hdr.instance_id, rc, 659 comSensorCnt, stateField.data(), 660 responsePtr); 661 if (rc != PLDM_SUCCESS) 662 { 663 return ccOnlyResponse(request, rc); 664 } 665 666 return response; 667 } 668 669 } // namespace platform 670 } // namespace responder 671 } // namespace pldm 672