1 #include "platform_oem_ibm.hpp" 2 3 #include "common/utils.hpp" 4 #include "libpldmresponder/pdr.hpp" 5 6 #include <libpldm/oem/ibm/platform.h> 7 8 #include <phosphor-logging/lg2.hpp> 9 #include <xyz/openbmc_project/Common/error.hpp> 10 11 #include <iostream> 12 13 PHOSPHOR_LOG2_USING; 14 15 namespace pldm 16 { 17 namespace responder 18 { 19 namespace platform 20 { 21 int sendBiosAttributeUpdateEvent( 22 uint8_t eid, pldm::InstanceIdDb* instanceIdDb, 23 const std::vector<uint16_t>& handles, 24 pldm::requester::Handler<pldm::requester::Request>* handler) 25 { 26 constexpr auto hostStatePath = "/xyz/openbmc_project/state/host0"; 27 constexpr auto hostStateInterface = 28 "xyz.openbmc_project.State.Boot.Progress"; 29 constexpr auto hostStateProperty = "BootProgress"; 30 31 try 32 { 33 auto propVal = pldm::utils::DBusHandler().getDbusPropertyVariant( 34 hostStatePath, hostStateProperty, hostStateInterface); 35 const auto& currHostState = std::get<std::string>(propVal); 36 if ((currHostState != "xyz.openbmc_project.State.Boot.Progress." 37 "ProgressStages.SystemInitComplete") && 38 (currHostState != "xyz.openbmc_project.State.Boot.Progress." 39 "ProgressStages.OSRunning") && 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 error( 59 "Error in getting current host state, {EXCEP_NAME} Continue sending the bios attribute update event ...", 60 "EXCEP_NAME", e.name()); 61 } 62 63 auto instanceId = instanceIdDb->next(eid); 64 65 std::vector<uint8_t> requestMsg( 66 sizeof(pldm_msg_hdr) + sizeof(pldm_bios_attribute_update_event_req) - 67 1 + (handles.size() * sizeof(uint16_t)), 68 0); 69 70 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data()); 71 72 auto rc = encode_bios_attribute_update_event_req( 73 instanceId, PLDM_PLATFORM_EVENT_MESSAGE_FORMAT_VERSION, TERMINUS_ID, 74 handles.size(), reinterpret_cast<const uint8_t*>(handles.data()), 75 requestMsg.size() - sizeof(pldm_msg_hdr), request); 76 if (rc != PLDM_SUCCESS) 77 { 78 error( 79 "BIOS Attribute update event message encode failure. PLDM error code = {RC}", 80 "RC", lg2::hex, rc); 81 instanceIdDb->free(eid, instanceId); 82 return rc; 83 } 84 85 auto platformEventMessageResponseHandler = 86 [](mctp_eid_t /*eid*/, const pldm_msg* response, size_t respMsgLen) { 87 if (response == nullptr || !respMsgLen) 88 { 89 error("Failed to receive response for platform event message"); 90 return; 91 } 92 uint8_t completionCode{}; 93 uint8_t status{}; 94 auto rc = decode_platform_event_message_resp(response, respMsgLen, 95 &completionCode, &status); 96 if (rc || completionCode) 97 { 98 error( 99 "Failed to decode BIOS Attribute update platform_event_message_resp: rc = {RC}, cc= {CC}", 100 "RC", rc, "CC", static_cast<unsigned>(completionCode)); 101 } 102 }; 103 rc = handler->registerRequest( 104 eid, instanceId, PLDM_PLATFORM, PLDM_PLATFORM_EVENT_MESSAGE, 105 std::move(requestMsg), std::move(platformEventMessageResponseHandler)); 106 if (rc) 107 { 108 error( 109 "Failed to send BIOS Attribute update the platform event message"); 110 } 111 112 return rc; 113 } 114 115 } // namespace platform 116 117 } // namespace responder 118 119 } // namespace pldm 120