blob: d485de5ec58422d19cf1c7769d557aaac021da64 [file] [log] [blame]
#pragma once
#include "config.h"
#include "libpldm/platform.h"
#include "libpldm/pldm.h"
#include "requester/handler.hpp"
#include "requester/mctp_endpoint_discovery.hpp"
#include "terminus.hpp"
#include <limits>
#include <map>
#include <memory>
#include <optional>
#include <queue>
#include <utility>
#include <vector>
namespace pldm
{
enum class SupportedTransportLayer
{
MCTP
};
namespace platform_mc
{
/** @brief Size of TID Pool in pldmd */
constexpr size_t tidPoolSize = std::numeric_limits<pldm_tid_t>::max() + 1;
/** @brief Type definition for Requester request handler */
using RequesterHandler = requester::Handler<requester::Request>;
/** @brief Type definition for Terminus handler mapper */
using TerminiMapper = std::map<pldm_tid_t, std::shared_ptr<Terminus>>;
class Manager;
/**
* @brief TerminusManager
*
* TerminusManager class to discover and initialize PLDM terminus.
*/
class TerminusManager
{
public:
TerminusManager() = delete;
TerminusManager(const TerminusManager&) = delete;
TerminusManager(TerminusManager&&) = delete;
TerminusManager& operator=(const TerminusManager&) = delete;
TerminusManager& operator=(TerminusManager&&) = delete;
virtual ~TerminusManager() = default;
explicit TerminusManager(sdeventplus::Event& /* event */,
RequesterHandler& handler,
pldm::InstanceIdDb& instanceIdDb,
TerminiMapper& termini, Manager* manager) :
handler(handler), instanceIdDb(instanceIdDb), termini(termini),
tidPool(tidPoolSize, false), manager(manager)
{
// DSP0240 v1.1.0 table-8, special value: 0,0xFF = reserved
tidPool[0] = true;
tidPool[PLDM_TID_RESERVED] = true;
}
/** @brief start a coroutine to discover terminus
*
* @param[in] mctpInfos - list information of the MCTP endpoints
*/
void discoverMctpTerminus(const MctpInfos& mctpInfos);
/** @brief remove MCTP endpoints
*
* @param[in] mctpInfos - list information of the MCTP endpoints
*/
void removeMctpTerminus(const MctpInfos& mctpInfos);
/** @brief Send request PLDM message to tid. The function will return when
* received the response message from terminus. The function will
* auto get the instanceID from libmctp and update to request
* message.
*
* @param[in] tid - Destination TID
* @param[in] request - request PLDM message
* @param[out] responseMsg - response PLDM message
* @param[out] responseLen - length of response PLDM message
* @return coroutine return_value - PLDM completion code
*/
exec::task<int> sendRecvPldmMsg(pldm_tid_t tid, Request& request,
const pldm_msg** responseMsg,
size_t* responseLen);
/** @brief Send request PLDM message to eid. The function will
* return when received the response message from terminus.
*
* @param[in] eid - Destination EID
* @param[in] request - request PLDM message
* @param[out] responseMsg - response PLDM message
* @param[out] responseLen - length of response PLDM message
* @return coroutine return_value - PLDM completion code
*/
virtual exec::task<int> sendRecvPldmMsgOverMctp(
mctp_eid_t eid, Request& request, const pldm_msg** responseMsg,
size_t* responseLen);
/** @brief member functions to map/unmap tid
*/
std::optional<MctpInfo> toMctpInfo(const pldm_tid_t& tid);
/** @brief Member functions to response the TID of specific MCTP interface
*
* @param[in] mctpInfos - list information of the MCTP endpoints
*
* @return tid - Terminus tid
*/
std::optional<pldm_tid_t> toTid(const MctpInfo& mctpInfo) const;
/** @brief Member functions to find the TID for MCTP interface. Response the
* Terminus TID when mctpInfo is already in the data base. Response
* new tid from pool when mctpInfo is new.
*
* @param[in] mctpInfos - list information of the MCTP endpoints
*
* @return tid - Terminus tid
*/
std::optional<pldm_tid_t> mapTid(const MctpInfo& mctpInfo);
/** @brief Member functions to store the mctp info and tid to terminus info
* list.
*
* @param[in] mctpInfos - list information of the MCTP endpoints
* @param[in] tid - Destination TID
*
* @return tid - Terminus tid
*/
std::optional<pldm_tid_t>
storeTerminusInfo(const MctpInfo& mctpInfo, pldm_tid_t tid);
/** @brief Member functions to remove the TID from the transportLayer and
* mctpInfo table
*
* @param[in] tid - Destination TID
*
* @return true/false - True when tid in the table otherwise return false
*/
bool unmapTid(const pldm_tid_t& tid);
private:
/** @brief Find the terminus object pointer in termini list.
*
* @param[in] mctpInfos - list information of the MCTP endpoints
*/
TerminiMapper::iterator findTerminusPtr(const MctpInfo& mctpInfo);
/** @brief The coroutine task execute by discoverMctpTerminus()
*
* @return coroutine return_value - PLDM completion code
*/
exec::task<int> discoverMctpTerminusTask();
/** @brief Initialize terminus and then instantiate terminus object to keeps
* the data fetched from terminus
*
* @param[in] mctpInfo - information of the MCTP endpoints
* @return coroutine return_value - PLDM completion code
*/
exec::task<int> initMctpTerminus(const MctpInfo& mctpInfo);
/** @brief Send getTID PLDM command to destination EID and then return the
* value of tid in reference parameter.
*
* @param[in] eid - Destination EID
* @param[out] tid - Terminus TID
* @return coroutine return_value - PLDM completion code
*/
exec::task<int> getTidOverMctp(mctp_eid_t eid, pldm_tid_t* tid);
/** @brief Send setTID command to destination EID.
*
* @param[in] eid - Destination EID
* @param[in] tid - Destination TID
* @return coroutine return_value - PLDM completion code
*/
exec::task<int> setTidOverMctp(mctp_eid_t eid, pldm_tid_t tid);
/** @brief Send getPLDMTypes command to destination TID and then return the
* value of supportedTypes in reference parameter.
*
* @param[in] tid - Destination TID
* @param[out] supportedTypes - Supported Types returned from terminus
* @return coroutine return_value - PLDM completion code
*/
exec::task<int> getPLDMTypes(pldm_tid_t tid, uint64_t& supportedTypes);
/** @brief Send getPLDMCommands command to destination TID and then return
* the value of supportedCommands in reference parameter.
*
* @param[in] tid - Destination TID
* @param[in] type - PLDM Type
* @param[in] supportedCmds - Supported commands returned from terminus
* for specific type
* @return coroutine return_value - PLDM completion code
*/
exec::task<int> getPLDMCommands(pldm_tid_t tid, uint8_t type,
bitfield8_t* supportedCmds);
/** @brief Reference to a Handler object that manages the request/response
* logic.
*/
RequesterHandler& handler;
/** @brief Reference to the instanceID data base from libpldm */
pldm::InstanceIdDb& instanceIdDb;
/** @brief Managed termini list */
TerminiMapper& termini;
/** @brief tables for maintaining assigned TID */
std::vector<bool> tidPool;
/** @brief Store the supported transport layers of specific TID */
std::map<pldm_tid_t, SupportedTransportLayer> transportLayerTable;
/** @brief Store the supported MCTP interface info of specific TID */
std::map<pldm_tid_t, MctpInfo> mctpInfoTable;
/** @brief A queue of MctpInfos to be discovered **/
std::queue<MctpInfos> queuedMctpInfos{};
/** @brief coroutine handle of discoverTerminusTask */
std::optional<std::pair<exec::async_scope, std::optional<int>>>
discoverMctpTerminusTaskHandle{};
/** @brief A Manager interface for calling the hook functions **/
Manager* manager;
};
} // namespace platform_mc
} // namespace pldm