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::exception& 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