xref: /openbmc/pldm/oem/ibm/libpldmresponder/platform_oem_ibm.cpp (revision b4ef4310bdda97566d20a6b8a04215c8fb4fb308)
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 #include <xyz/openbmc_project/State/Boot/Progress/client.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     using BootProgress =
28         sdbusplus::client::xyz::openbmc_project::state::boot::Progress<>;
29 
30     constexpr auto hostStatePath = "/xyz/openbmc_project/state/host0";
31     constexpr auto hostStateProperty = "BootProgress";
32 
33     try
34     {
35         auto propVal = pldm::utils::DBusHandler().getDbusPropertyVariant(
36             hostStatePath, hostStateProperty, BootProgress::interface);
37 
38         using Stages = BootProgress::ProgressStages;
39         auto currHostState = sdbusplus::message::convert_from_string<Stages>(
40                                  std::get<std::string>(propVal))
41                                  .value();
42 
43         if (currHostState != Stages::SystemInitComplete &&
44             currHostState != Stages::OSRunning &&
45             currHostState != Stages::SystemSetup)
46         {
47             return PLDM_SUCCESS;
48         }
49     }
50     catch (
51         const sdbusplus::xyz::openbmc_project::Common::Error::ResourceNotFound&)
52     {
53         /* Exception is expected to happen in the case when state manager is
54          * started after pldm, this is expected to happen in reboot case
55          * where host is considered to be up. As host is up pldm is expected
56          * to send attribute update event to host so this is not an error
57          * case */
58     }
59     catch (const sdbusplus::exception_t& e)
60     {
61         error(
62             "Error in getting current host state, {EXCEP_NAME} Continue sending the bios attribute update event ...",
63             "EXCEP_NAME", e.name());
64     }
65 
66     auto instanceId = instanceIdDb->next(eid);
67 
68     std::vector<uint8_t> requestMsg(
69         sizeof(pldm_msg_hdr) + sizeof(pldm_bios_attribute_update_event_req) -
70             1 + (handles.size() * sizeof(uint16_t)),
71         0);
72 
73     auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
74 
75     auto rc = encode_bios_attribute_update_event_req(
76         instanceId, PLDM_PLATFORM_EVENT_MESSAGE_FORMAT_VERSION, TERMINUS_ID,
77         handles.size(), reinterpret_cast<const uint8_t*>(handles.data()),
78         requestMsg.size() - sizeof(pldm_msg_hdr), request);
79     if (rc != PLDM_SUCCESS)
80     {
81         error(
82             "BIOS Attribute update event message encode failure. PLDM error code = {RC}",
83             "RC", lg2::hex, rc);
84         instanceIdDb->free(eid, instanceId);
85         return rc;
86     }
87 
88     auto platformEventMessageResponseHandler =
89         [](mctp_eid_t /*eid*/, const pldm_msg* response, size_t respMsgLen) {
90         if (response == nullptr || !respMsgLen)
91         {
92             error("Failed to receive response for platform event message");
93             return;
94         }
95         uint8_t completionCode{};
96         uint8_t status{};
97         auto rc = decode_platform_event_message_resp(response, respMsgLen,
98                                                      &completionCode, &status);
99         if (rc || completionCode)
100         {
101             error(
102                 "Failed to decode BIOS Attribute update platform_event_message_resp: rc = {RC}, cc= {CC}",
103                 "RC", rc, "CC", static_cast<unsigned>(completionCode));
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         error(
112             "Failed to send BIOS Attribute update the platform event message");
113     }
114 
115     return rc;
116 }
117 
118 } // namespace platform
119 
120 } // namespace responder
121 
122 } // namespace pldm
123