blob: d5c6528b8e7e0e72d7c5afb3a57db25f321230b3 [file] [log] [blame]
Tom Joseph7f839f92020-09-21 10:20:44 +05301#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
11namespace pldm
12{
13namespace responder
14{
15namespace platform
16{
17
18int sendBiosAttributeUpdateEvent(int fd, uint8_t eid,
19 dbus_api::Requester* requester,
20 const std::vector<uint16_t>& handles)
21{
Tom Joseph5dad5f42020-12-08 18:23:42 +053022 constexpr auto hostStatePath = "/xyz/openbmc_project/state/host0";
23 constexpr auto hostStateInterface =
24 "xyz.openbmc_project.State.Boot.Progress";
25 constexpr auto hostStateProperty = "BootProgress";
Tom Joseph7f839f92020-09-21 10:20:44 +053026
27 try
28 {
29 auto propVal = pldm::utils::DBusHandler().getDbusPropertyVariant(
Tom Joseph5dad5f42020-12-08 18:23:42 +053030 hostStatePath, hostStateProperty, hostStateInterface);
Tom Joseph7f839f92020-09-21 10:20:44 +053031 const auto& currHostState = std::get<std::string>(propVal);
Tom Joseph5dad5f42020-12-08 18:23:42 +053032 if ((currHostState != "xyz.openbmc_project.State.Boot.Progress."
33 "ProgressStages.SystemInitComplete") &&
34 (currHostState != "xyz.openbmc_project.State.Boot.Progress."
35 "ProgressStages.OSRunning") &&
36 (currHostState != "xyz.openbmc_project.State.Boot.Progress."
37 "ProgressStages.OSStart"))
Tom Joseph7f839f92020-09-21 10:20:44 +053038 {
39 return PLDM_SUCCESS;
40 }
41 }
42 catch (const sdbusplus::exception::SdBusError& e)
43 {
44 std::cerr << "Error in getting current host state, continue ... \n";
45 }
46
47 auto instanceId = requester->getInstanceId(eid);
48
49 std::vector<uint8_t> requestMsg(
50 sizeof(pldm_msg_hdr) + sizeof(pldm_bios_attribute_update_event_req) -
51 1 + (handles.size() * sizeof(uint16_t)),
52 0);
53
54 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
55
56 auto rc = encode_bios_attribute_update_event_req(
57 instanceId, PLDM_PLATFORM_EVENT_MESSAGE_FORMAT_VERSION,
58 pldm::responder::pdr::BmcMctpEid, handles.size(),
59 reinterpret_cast<const uint8_t*>(handles.data()),
60 requestMsg.size() - sizeof(pldm_msg_hdr), request);
61 if (rc != PLDM_SUCCESS)
62 {
63 std::cerr << "Message encode failure 1. PLDM error code = " << std::hex
64 << std::showbase << rc << "\n";
65 requester->markFree(eid, instanceId);
66 return rc;
67 }
68
69 if (requestMsg.size())
70 {
71 std::ostringstream tempStream;
72 for (int byte : requestMsg)
73 {
74 tempStream << std::setfill('0') << std::setw(2) << std::hex << byte
75 << " ";
76 }
77 std::cout << tempStream.str() << std::endl;
78 }
79
80 uint8_t* responseMsg = nullptr;
81 size_t responseMsgSize{};
82
83 rc = pldm_send_recv(eid, fd, requestMsg.data(), requestMsg.size(),
84 &responseMsg, &responseMsgSize);
85 std::unique_ptr<uint8_t, decltype(std::free)*> responseMsgPtr{responseMsg,
86 std::free};
87 requester->markFree(eid, instanceId);
88
89 if (rc != PLDM_REQUESTER_SUCCESS)
90 {
91 std::cerr << "Failed to send BIOS attribute update event. RC = " << rc
92 << ", errno = " << errno << "\n";
93 pldm::utils::reportError(
94 "xyz.openbmc_project.bmc.pldm.InternalFailure");
95 return rc;
96 }
97
98 auto responsePtr = reinterpret_cast<struct pldm_msg*>(responseMsgPtr.get());
99 uint8_t completionCode{};
100 uint8_t status{};
101 rc = decode_platform_event_message_resp(
102 responsePtr, responseMsgSize - sizeof(pldm_msg_hdr), &completionCode,
103 &status);
104 if (rc != PLDM_SUCCESS)
105 {
106 std::cerr << "Failed to decode PlatformEventMessage response, rc = "
107 << rc << "\n";
108 return rc;
109 }
110
111 if (completionCode != PLDM_SUCCESS)
112 {
113 std::cerr << "Failed to send the BIOS attribute update event, rc = "
114 << (uint32_t)completionCode << "\n";
115 pldm::utils::reportError(
116 "xyz.openbmc_project.bmc.pldm.InternalFailure");
117 }
118
119 return completionCode;
120}
121
122} // namespace platform
123
124} // namespace responder
125
126} // namespace pldm