diff --git a/include/pldm_fw.hpp b/include/pldm_fw.hpp index f8959f4057..624721c229 100644 --- a/include/pldm_fw.hpp +++ b/include/pldm_fw.hpp @@ -1,5 +1,8 @@ #include "types.hpp" +#include +#include +#include #include #include @@ -21,12 +24,26 @@ class PldmFramework /** * @brief Construtor */ - PldmFramework() = default; + PldmFramework() + { + int rc = pldm_instance_db_init_default(&pldmInstanceIdDb); + if (rc) + { + throw std::system_category().default_error_condition(rc); + } + } /** * @brief Destructor */ - ~PldmFramework() = default; + ~PldmFramework() + { + int rc = pldm_instance_db_destroy(pldmInstanceIdDb); + if (rc) + { + std::cout << "pldm_instance_db_destroy failed, rc =" << rc << "\n"; + } + } /** * @brief Send Panel Function to PHYP. @@ -43,6 +60,19 @@ class PldmFramework /** Host mctp eid */ static constexpr auto mctpEid = (types::Byte)9; + /** @brief Hardcoded TID */ + using TerminusID = uint8_t; + static constexpr TerminusID tid = mctpEid; + + /** @brief PLDM instance ID database object used to get instance IDs + */ + pldm_instance_db* pldmInstanceIdDb = nullptr; + + /** pldm transport instance */ + struct pldm_transport* pldmTransport = NULL; + + struct pldm_transport_mctp_demux* mctpDemux = NULL; + // Constants required for PLDM packet. static constexpr auto phypTerminusID = (types::Byte)208; static constexpr auto frontPanelBoardEntityId = (uint16_t)32837; @@ -81,12 +111,32 @@ class PldmFramework /** * @brief Get instance ID - * This api returns the instance id by making a dbus call to GetInstanceId - * api of Pldm. Instance id is to uniquely identify a message packet. This - * id is generated by pldm. + * This api returns the instance id by making a dbus call to libpldm + * api. Instance id is to uniquely identify a message packet. + * @return pldm_instance_id_t instance id. + */ + pldm_instance_id_t getInstanceID(); + + /** + * @brief Free PLDM requester instance id + * @param[in] pdrs - Panel PDR data. + */ + void freeInstanceID(pldm_instance_id_t instanceID); + + /** + * @brief setup PLDM transport for sending and receiving messages + * + * @return file descriptor + */ + int openPldm(); + + /** @brief Opens the MCTP socket for sending and receiving messages. * - * @return one byte instance id. */ - types::Byte getInstanceID(); + int openMctpDemuxTransport(); + + /** @brief Close the PLDM file */ + void pldmClose(); + }; } // namespace panel diff --git a/meson.build b/meson.build index 0e21759181..bc683f2fcc 100644 --- a/meson.build +++ b/meson.build @@ -34,6 +34,10 @@ systemd_system_unit_dir = systemd.get_variable('systemdsystemunitdir') service_file = 'service_files/com.ibm.panel.service' +if cxx.has_header('poll.h') + add_project_arguments('-DPLDM_HAS_POLL=1', language: 'cpp') +endif + if get_option('system-vpd-dependency').enabled() service_file = 'service_files/ibm.panel.system.vpd.dependent.service' endif diff --git a/src/pldm_fw.cpp b/src/pldm_fw.cpp index 09c19561b4..17dd58c810 100644 --- a/src/pldm_fw.cpp +++ b/src/pldm_fw.cpp @@ -1,3 +1,4 @@ + #include "pldm_fw.hpp" #include "exception.hpp" @@ -7,6 +8,7 @@ #include #include #include +#include #include #include @@ -14,26 +16,104 @@ namespace panel { -types::Byte PldmFramework::getInstanceID() +pldm_instance_id_t PldmFramework::getInstanceID() { - types::Byte instanceId = 0; - auto bus = sdbusplus::bus::new_default(); + pldm_instance_id_t instanceID = 0; - try + auto rc = pldm_instance_id_alloc(pldmInstanceIdDb, tid, &instanceID); + if (rc == -EAGAIN) { - auto method = bus.new_method_call( - "xyz.openbmc_project.PLDM", "/xyz/openbmc_project/pldm", - "xyz.openbmc_project.PLDM.Requester", "GetInstanceId"); - method.append(mctpEid); - auto reply = bus.call(method); - reply.read(instanceId); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + rc = pldm_instance_id_alloc(pldmInstanceIdDb, tid, &instanceID); } - catch (const sdbusplus::exception::SdBusError& e) + + if (rc) { - std::cerr << e.what() << std::endl; + std::cerr << "Return code = " << rc << std::endl; throw FunctionFailure("pldm: call to GetInstanceId failed."); } - return instanceId; + std::cout << "Got instanceId: " << static_cast(instanceID) + << " from PLDM eid: " << static_cast(tid) << std::endl; + return instanceID; +} + +void PldmFramework::freeInstanceID(pldm_instance_id_t instanceID) +{ + std::cout << "Free instanceId: " << static_cast(instanceID) + << std::endl; + auto rc = pldm_instance_id_free(pldmInstanceIdDb, tid, instanceID); + if (rc) + { + std::cerr << "pldm_instance_id_free failed to free id = " + << static_cast(instanceID) + << " of tid = " << static_cast(tid) << " rc = " << rc + << std::endl; + } +} + +int PldmFramework::openPldm() +{ + auto fd = -1; + if (pldmTransport) + { + std::cerr << "open: pldmTransport already setup!" << std::endl; + throw FunctionFailure("Required host dump action via PLDM is not " + "allowed due to openPldm failed"); + return fd; + } + + fd = openMctpDemuxTransport(); + if (fd < 0) + { + auto e = errno; + std::cerr << "openPldm failed, errno: " << e << ", FD: " << fd + << std::endl; + throw FunctionFailure("Required host dump action via PLDM is not " + "allowed due to openPldm failed"); + } + return fd; +} + +int PldmFramework::openMctpDemuxTransport() +{ + int rc = pldm_transport_mctp_demux_init(&mctpDemux); + if (rc) + { + std::cerr << "openMctpDemuxTransport: Failed to init MCTP demux " + "transport. rc = " + << rc << std::endl; + throw FunctionFailure("Failed to init MCTP demux transport"); + } + + rc = pldm_transport_mctp_demux_map_tid(mctpDemux, tid, tid); + if (rc) + { + std::cerr << "openMctpDemuxTransport: Failed to setup tid to eid " + "mapping. rc = " + << rc << std::endl; + pldmClose(); + throw FunctionFailure("Failed to setup tid to eid mapping"); + } + pldmTransport = pldm_transport_mctp_demux_core(mctpDemux); + + struct pollfd pollfd; + rc = pldm_transport_mctp_demux_init_pollfd(pldmTransport, &pollfd); + if (rc) + { + std::cerr << "openMctpDemuxTransport: Failed to get pollfd. rc = " << rc + << std::endl; + pldmClose(); + throw FunctionFailure("Failed to get pollfd"); + } + std::cout << " Lakshmi openMctpDemuxTransport done.\n" << std::endl; + return pollfd.fd; +} + +void PldmFramework::pldmClose() +{ + pldm_transport_mctp_demux_destroy(mctpDemux); + mctpDemux = NULL; + pldmTransport = NULL; } void PldmFramework::fetchPanelEffecterStateSet(const types::PdrList& pdrs, @@ -128,7 +208,7 @@ void PldmFramework::sendPanelFunctionToPhyp( return; } - types::Byte instance = getInstanceID(); + pldm_instance_id_t instance = getInstanceID(); types::PldmPacket packet = prepareSetEffecterReq(pdrs, instance, funcNumber); @@ -144,10 +224,10 @@ void PldmFramework::sendPanelFunctionToPhyp( return; } - int fd = pldm_open(); + int fd = openPldm(); if (fd == -1) { - std::cerr << "pldm_open() failed with error = " << strerror(errno) + std::cerr << "openPldm() failed with error = " << strerror(errno) << std::endl; std::map additionalData{}; additionalData.emplace("DESCRIPTION", @@ -156,6 +236,7 @@ void PldmFramework::sendPanelFunctionToPhyp( utils::createPEL("com.ibm.Panel.Error.HostCommunicationError", "xyz.openbmc_project.Logging.Entry.Level.Warning", additionalData); + freeInstanceID(instance); return; } @@ -167,14 +248,12 @@ void PldmFramework::sendPanelFunctionToPhyp( } std::cout << std::endl; - auto rc = pldm_send(mctpEid, fd, packet.data(), packet.size()); - - if (close(fd) == -1) - { - std::cerr << "Close on File descriptor failed with error = " - << strerror(errno) << std::endl; - } + pldm_tid_t pldmTID = static_cast(mctpEid); + auto rc = pldm_transport_send_msg(pldmTransport, pldmTID, packet.data(), + packet.size()); + freeInstanceID(instance); + pldmClose(); if (rc) { std::map additionalData{};