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