blob: 3292004db137fd50064d4d9f0e108f9de99c1a17 [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{
22 constexpr auto osStatePath = "/xyz/openbmc_project/state/host0";
23 constexpr auto osStateInterface =
24 "xyz.openbmc_project.State.OperatingSystem.Status";
25 constexpr auto osStateProperty = "OperatingSystemState";
26
27 try
28 {
29 auto propVal = pldm::utils::DBusHandler().getDbusPropertyVariant(
30 osStatePath, osStateProperty, osStateInterface);
31 const auto& currHostState = std::get<std::string>(propVal);
32 if ((currHostState != "xyz.openbmc_project.State.OperatingSystem."
33 "Status.OSStatus.Standby") &&
34 (currHostState != "xyz.openbmc_project.State.OperatingSystem."
35 "Status.OSStatus.BootComplete"))
36 {
37 return PLDM_SUCCESS;
38 }
39 }
40 catch (const sdbusplus::exception::SdBusError& e)
41 {
42 std::cerr << "Error in getting current host state, continue ... \n";
43 }
44
45 auto instanceId = requester->getInstanceId(eid);
46
47 std::vector<uint8_t> requestMsg(
48 sizeof(pldm_msg_hdr) + sizeof(pldm_bios_attribute_update_event_req) -
49 1 + (handles.size() * sizeof(uint16_t)),
50 0);
51
52 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
53
54 auto rc = encode_bios_attribute_update_event_req(
55 instanceId, PLDM_PLATFORM_EVENT_MESSAGE_FORMAT_VERSION,
56 pldm::responder::pdr::BmcMctpEid, handles.size(),
57 reinterpret_cast<const uint8_t*>(handles.data()),
58 requestMsg.size() - sizeof(pldm_msg_hdr), request);
59 if (rc != PLDM_SUCCESS)
60 {
61 std::cerr << "Message encode failure 1. PLDM error code = " << std::hex
62 << std::showbase << rc << "\n";
63 requester->markFree(eid, instanceId);
64 return rc;
65 }
66
67 if (requestMsg.size())
68 {
69 std::ostringstream tempStream;
70 for (int byte : requestMsg)
71 {
72 tempStream << std::setfill('0') << std::setw(2) << std::hex << byte
73 << " ";
74 }
75 std::cout << tempStream.str() << std::endl;
76 }
77
78 uint8_t* responseMsg = nullptr;
79 size_t responseMsgSize{};
80
81 rc = pldm_send_recv(eid, fd, requestMsg.data(), requestMsg.size(),
82 &responseMsg, &responseMsgSize);
83 std::unique_ptr<uint8_t, decltype(std::free)*> responseMsgPtr{responseMsg,
84 std::free};
85 requester->markFree(eid, instanceId);
86
87 if (rc != PLDM_REQUESTER_SUCCESS)
88 {
89 std::cerr << "Failed to send BIOS attribute update event. RC = " << rc
90 << ", errno = " << errno << "\n";
91 pldm::utils::reportError(
92 "xyz.openbmc_project.bmc.pldm.InternalFailure");
93 return rc;
94 }
95
96 auto responsePtr = reinterpret_cast<struct pldm_msg*>(responseMsgPtr.get());
97 uint8_t completionCode{};
98 uint8_t status{};
99 rc = decode_platform_event_message_resp(
100 responsePtr, responseMsgSize - sizeof(pldm_msg_hdr), &completionCode,
101 &status);
102 if (rc != PLDM_SUCCESS)
103 {
104 std::cerr << "Failed to decode PlatformEventMessage response, rc = "
105 << rc << "\n";
106 return rc;
107 }
108
109 if (completionCode != PLDM_SUCCESS)
110 {
111 std::cerr << "Failed to send the BIOS attribute update event, rc = "
112 << (uint32_t)completionCode << "\n";
113 pldm::utils::reportError(
114 "xyz.openbmc_project.bmc.pldm.InternalFailure");
115 }
116
117 return completionCode;
118}
119
120} // namespace platform
121
122} // namespace responder
123
124} // namespace pldm