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             (currHostState != "xyz.openbmc_project.State.Boot.Progress."
40                               "ProgressStages.SystemSetup"))
41         {
42             return PLDM_SUCCESS;
43         }
44     }
45     catch (const sdbusplus::exception_t& e)
46     {
47         std::cerr << "Error in getting current host state, continue ... \n";
48     }
49 
50     auto instanceId = requester->getInstanceId(eid);
51 
52     std::vector<uint8_t> requestMsg(
53         sizeof(pldm_msg_hdr) + sizeof(pldm_bios_attribute_update_event_req) -
54             1 + (handles.size() * sizeof(uint16_t)),
55         0);
56 
57     auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
58 
59     auto rc = encode_bios_attribute_update_event_req(
60         instanceId, PLDM_PLATFORM_EVENT_MESSAGE_FORMAT_VERSION,
61         pldm::responder::pdr::BmcMctpEid, handles.size(),
62         reinterpret_cast<const uint8_t*>(handles.data()),
63         requestMsg.size() - sizeof(pldm_msg_hdr), request);
64     if (rc != PLDM_SUCCESS)
65     {
66         std::cerr << "Message encode failure 1. PLDM error code = " << std::hex
67                   << std::showbase << rc << "\n";
68         requester->markFree(eid, instanceId);
69         return rc;
70     }
71 
72     if (requestMsg.size())
73     {
74         std::ostringstream tempStream;
75         for (int byte : requestMsg)
76         {
77             tempStream << std::setfill('0') << std::setw(2) << std::hex << byte
78                        << " ";
79         }
80         std::cout << tempStream.str() << std::endl;
81     }
82 
83     auto platformEventMessageResponseHandler = [](mctp_eid_t /*eid*/,
84                                                   const pldm_msg* response,
85                                                   size_t respMsgLen) {
86         if (response == nullptr || !respMsgLen)
87         {
88             std::cerr
89                 << "Failed to receive response for platform event message \n";
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             std::cerr << "Failed to decode_platform_event_message_resp: "
99                       << "rc=" << rc
100                       << ", cc=" << static_cast<unsigned>(completionCode)
101                       << std::endl;
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         std::cerr << "Failed to send the platform event message \n";
110     }
111 
112     return rc;
113 }
114 
115 } // namespace platform
116 
117 } // namespace responder
118 
119 } // namespace pldm
120