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