BMC RR: check whether the Host is running
This commit checks whether Host is up by sending a request to
Host when pldmd starts up. This does not differentiate the case
when there is a bmc RR or pldmd restarted.
Updates the Host condition accordingly.
Initiates a PDR exchange if Host is running.
Change-Id: I630b342f5f9cc62530e0274f46357d238e92d0c9
Signed-off-by: sampmisr <sampmisr@gmail.com>
diff --git a/host-bmc/host_pdr_handler.cpp b/host-bmc/host_pdr_handler.cpp
index a2d4d17..a786ed4 100644
--- a/host-bmc/host_pdr_handler.cpp
+++ b/host-bmc/host_pdr_handler.cpp
@@ -7,6 +7,10 @@
#include <assert.h>
#include <nlohmann/json.hpp>
+#include <sdeventplus/clock.hpp>
+#include <sdeventplus/exception.hpp>
+#include <sdeventplus/source/io.hpp>
+#include <sdeventplus/source/time.hpp>
#include <fstream>
@@ -482,4 +486,114 @@
this->getHostPDR(nextRecordHandle);
}
+void HostPDRHandler::setHostState()
+{
+ using namespace sdeventplus;
+ using namespace sdeventplus::source;
+ constexpr auto clockId = sdeventplus::ClockId::RealTime;
+ using Clock = Clock<clockId>;
+ using Timer = Time<clockId>;
+
+ auto event1 = sdeventplus::Event::get_default();
+ auto& bus = pldm::utils::DBusHandler::getBus();
+ bus.attach_event(event1.get(), SD_EVENT_PRIORITY_NORMAL);
+
+ responseReceived = false;
+ timeOut = false;
+
+ int fd = pldm_open();
+ if (-1 == fd)
+ {
+ std::cerr << "Failed to connect to mctp demux daemon \n";
+ return;
+ }
+
+ auto timerCallback = [=, this](Timer& /*source*/,
+ Timer::TimePoint /*time*/) {
+ timeOut = true;
+ if (!responseReceived)
+ {
+ std::cout << "PLDM did not get a response from Host"
+ " Host seems to be off \n";
+ }
+ return;
+ };
+
+ Timer time(event1, (Clock(event1).now() + std::chrono::seconds{3}),
+ std::chrono::seconds{1}, std::move(timerCallback));
+
+ auto callback = [=, this](IO& /*io*/, int fd, uint32_t revents) {
+ if (!(revents & EPOLLIN))
+ {
+ return;
+ }
+ uint8_t* responseMsg = nullptr;
+ size_t responseMsgSize{};
+ auto rc =
+ pldm_recv(mctp_eid, fd, insId, &responseMsg, &responseMsgSize);
+ if (rc != PLDM_REQUESTER_SUCCESS)
+ {
+ return;
+ }
+ std::unique_ptr<uint8_t, decltype(std::free)*> responseMsgPtr{
+ responseMsg, std::free};
+ auto response = reinterpret_cast<pldm_msg*>(responseMsgPtr.get());
+ std::cout << "Getting the response. PLDM RC = " << std::hex
+ << std::showbase
+ << static_cast<uint16_t>(response->payload[0]) << "\n";
+ responseReceived = true;
+ return;
+ };
+ IO io(event1, fd, EPOLLIN, std::move(callback));
+ std::vector<uint8_t> requestMsg(sizeof(pldm_msg_hdr) +
+ PLDM_GET_PDR_REQ_BYTES);
+ auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
+ uint32_t recordHandle{};
+ insId = requester.getInstanceId(mctp_eid);
+ auto rc =
+ encode_get_pdr_req(insId, recordHandle, 0, PLDM_GET_FIRSTPART,
+ UINT16_MAX, 0, request, PLDM_GET_PDR_REQ_BYTES);
+ if (rc != PLDM_SUCCESS)
+ {
+ requester.markFree(mctp_eid, insId);
+ std::cerr << "Failed to encode_get_pdr_req, rc = " << rc << std::endl;
+ return;
+ }
+ rc = pldm_send(mctp_eid, fd, requestMsg.data(), requestMsg.size());
+ if (0 > rc)
+ {
+ std::cerr << "Failed to send message RC = " << rc
+ << ", errno = " << errno << "\n";
+ return;
+ }
+ while (1)
+ {
+ if (responseReceived)
+ {
+ requester.markFree(mctp_eid, insId);
+ break;
+ }
+ if (timeOut)
+ {
+ requester.markFree(mctp_eid, insId);
+ break;
+ }
+ try
+ {
+ event1.run(std::nullopt);
+ }
+ catch (const sdeventplus::SdEventError& e)
+ {
+ std::cerr << "Failure in processing request.ERROR= " << e.what()
+ << "\n";
+ return;
+ }
+ }
+}
+
+bool HostPDRHandler::isHostUp()
+{
+ return responseReceived;
+}
+
} // namespace pldm