1 #include "platform_oem_ibm.hpp" 2 3 #include "common/utils.hpp" 4 #include "libpldmresponder/pdr.hpp" 5 6 #include <libpldm/platform_oem_ibm.h> 7 #include <libpldm/pldm.h> 8 9 #include <xyz/openbmc_project/Common/error.hpp> 10 11 #include <iostream> 12 13 namespace pldm 14 { 15 namespace responder 16 { 17 namespace platform 18 { 19 int sendBiosAttributeUpdateEvent( 20 uint8_t eid, dbus_api::Requester* requester, 21 const std::vector<uint16_t>& handles, 22 pldm::requester::Handler<pldm::requester::Request>* handler) 23 { 24 constexpr auto hostStatePath = "/xyz/openbmc_project/state/host0"; 25 constexpr auto hostStateInterface = 26 "xyz.openbmc_project.State.Boot.Progress"; 27 constexpr auto hostStateProperty = "BootProgress"; 28 29 try 30 { 31 auto propVal = pldm::utils::DBusHandler().getDbusPropertyVariant( 32 hostStatePath, hostStateProperty, hostStateInterface); 33 const auto& currHostState = std::get<std::string>(propVal); 34 if ((currHostState != "xyz.openbmc_project.State.Boot.Progress." 35 "ProgressStages.SystemInitComplete") && 36 (currHostState != "xyz.openbmc_project.State.Boot.Progress." 37 "ProgressStages.OSRunning") && 38 (currHostState != "xyz.openbmc_project.State.Boot.Progress." 39 "ProgressStages.OSStart") && 40 (currHostState != "xyz.openbmc_project.State.Boot.Progress." 41 "ProgressStages.SystemSetup")) 42 { 43 return PLDM_SUCCESS; 44 } 45 } 46 catch ( 47 const sdbusplus::xyz::openbmc_project::Common::Error::ResourceNotFound& 48 e) 49 { 50 /* Exception is expected to happen in the case when state manager is 51 * started after pldm, this is expected to happen in reboot case 52 * where host is considered to be up. As host is up pldm is expected 53 * to send attribute update event to host so this is not an error 54 * case */ 55 } 56 catch (const sdbusplus::exception_t& e) 57 { 58 std::cerr << "Error in getting current host state, " << e.name() 59 << " Continue sending the bios attribute update event ... \n"; 60 } 61 62 auto instanceId = requester->getInstanceId(eid); 63 64 std::vector<uint8_t> requestMsg( 65 sizeof(pldm_msg_hdr) + sizeof(pldm_bios_attribute_update_event_req) - 66 1 + (handles.size() * sizeof(uint16_t)), 67 0); 68 69 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 70 71 auto rc = encode_bios_attribute_update_event_req( 72 instanceId, PLDM_PLATFORM_EVENT_MESSAGE_FORMAT_VERSION, TERMINUS_ID, 73 handles.size(), reinterpret_cast<const uint8_t*>(handles.data()), 74 requestMsg.size() - sizeof(pldm_msg_hdr), request); 75 if (rc != PLDM_SUCCESS) 76 { 77 std::cerr 78 << "BIOS Attribute update event message encode failure. PLDM error code = " 79 << std::hex << std::showbase << rc << "\n"; 80 requester->markFree(eid, instanceId); 81 return rc; 82 } 83 84 auto platformEventMessageResponseHandler = [](mctp_eid_t /*eid*/, 85 const pldm_msg* response, 86 size_t respMsgLen) { 87 if (response == nullptr || !respMsgLen) 88 { 89 std::cerr 90 << "Failed to receive response for BIOS Attribute update platform event message \n"; 91 return; 92 } 93 uint8_t completionCode{}; 94 uint8_t status{}; 95 auto rc = decode_platform_event_message_resp(response, respMsgLen, 96 &completionCode, &status); 97 if (rc || completionCode) 98 { 99 std::cerr 100 << "Failed to decode BIOS Attribute update platform_event_message_resp: " 101 << "rc=" << rc 102 << ", cc=" << static_cast<unsigned>(completionCode) 103 << std::endl; 104 } 105 }; 106 rc = handler->registerRequest( 107 eid, instanceId, PLDM_PLATFORM, PLDM_PLATFORM_EVENT_MESSAGE, 108 std::move(requestMsg), std::move(platformEventMessageResponseHandler)); 109 if (rc) 110 { 111 std::cerr 112 << "Failed to send BIOS Attribute update the platform event message \n"; 113 } 114 115 return rc; 116 } 117 118 } // namespace platform 119 120 } // namespace responder 121 122 } // namespace pldm 123