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