xref: /openbmc/pldm/platform-mc/terminus_manager.hpp (revision fe2527954be36a3013dc6b8c8ff13ae649bb58a6)
16c7fed4cSGilbert Chen #pragma once
26c7fed4cSGilbert Chen 
36c7fed4cSGilbert Chen #include "config.h"
46c7fed4cSGilbert Chen 
56c7fed4cSGilbert Chen #include "requester/handler.hpp"
66c7fed4cSGilbert Chen #include "requester/mctp_endpoint_discovery.hpp"
76c7fed4cSGilbert Chen #include "terminus.hpp"
86c7fed4cSGilbert Chen 
9*fe252795SManojkiran Eda #include <libpldm/platform.h>
10*fe252795SManojkiran Eda #include <libpldm/pldm.h>
11*fe252795SManojkiran Eda 
126c7fed4cSGilbert Chen #include <limits>
136c7fed4cSGilbert Chen #include <map>
146c7fed4cSGilbert Chen #include <memory>
156c7fed4cSGilbert Chen #include <optional>
166c7fed4cSGilbert Chen #include <queue>
176c7fed4cSGilbert Chen #include <utility>
186c7fed4cSGilbert Chen #include <vector>
196c7fed4cSGilbert Chen 
206c7fed4cSGilbert Chen namespace pldm
216c7fed4cSGilbert Chen {
226c7fed4cSGilbert Chen 
236c7fed4cSGilbert Chen enum class SupportedTransportLayer
246c7fed4cSGilbert Chen {
256c7fed4cSGilbert Chen     MCTP
266c7fed4cSGilbert Chen };
276c7fed4cSGilbert Chen 
286c7fed4cSGilbert Chen namespace platform_mc
296c7fed4cSGilbert Chen {
306c7fed4cSGilbert Chen 
316c7fed4cSGilbert Chen /** @brief Size of TID Pool in pldmd */
326c7fed4cSGilbert Chen constexpr size_t tidPoolSize = std::numeric_limits<pldm_tid_t>::max() + 1;
336c7fed4cSGilbert Chen /** @brief Type definition for Requester request handler */
346c7fed4cSGilbert Chen using RequesterHandler = requester::Handler<requester::Request>;
356c7fed4cSGilbert Chen /** @brief Type definition for Terminus handler mapper */
366c7fed4cSGilbert Chen using TerminiMapper = std::map<pldm_tid_t, std::shared_ptr<Terminus>>;
376c7fed4cSGilbert Chen 
386c7fed4cSGilbert Chen class Manager;
396c7fed4cSGilbert Chen /**
406c7fed4cSGilbert Chen  * @brief TerminusManager
416c7fed4cSGilbert Chen  *
426c7fed4cSGilbert Chen  * TerminusManager class to discover and initialize PLDM terminus.
436c7fed4cSGilbert Chen  */
446c7fed4cSGilbert Chen class TerminusManager
456c7fed4cSGilbert Chen {
466c7fed4cSGilbert Chen   public:
476c7fed4cSGilbert Chen     TerminusManager() = delete;
486c7fed4cSGilbert Chen     TerminusManager(const TerminusManager&) = delete;
496c7fed4cSGilbert Chen     TerminusManager(TerminusManager&&) = delete;
506c7fed4cSGilbert Chen     TerminusManager& operator=(const TerminusManager&) = delete;
516c7fed4cSGilbert Chen     TerminusManager& operator=(TerminusManager&&) = delete;
526c7fed4cSGilbert Chen     virtual ~TerminusManager() = default;
536c7fed4cSGilbert Chen 
TerminusManager(sdeventplus::Event & event,RequesterHandler & handler,pldm::InstanceIdDb & instanceIdDb,TerminiMapper & termini,Manager * manager,mctp_eid_t localEid)5451d66b59SThu Nguyen     explicit TerminusManager(
55fdf61cc3SChaul Ly         sdeventplus::Event& event, RequesterHandler& handler,
5651d66b59SThu Nguyen         pldm::InstanceIdDb& instanceIdDb, TerminiMapper& termini,
5751d66b59SThu Nguyen         Manager* manager, mctp_eid_t localEid) :
5816c2a0a0SPatrick Williams         handler(handler), instanceIdDb(instanceIdDb), termini(termini),
59fdf61cc3SChaul Ly         tidPool(tidPoolSize, false), manager(manager), localEid(localEid),
60fdf61cc3SChaul Ly         event(event)
616c7fed4cSGilbert Chen     {
626c7fed4cSGilbert Chen         // DSP0240 v1.1.0 table-8, special value: 0,0xFF = reserved
636c7fed4cSGilbert Chen         tidPool[0] = true;
646c7fed4cSGilbert Chen         tidPool[PLDM_TID_RESERVED] = true;
656c7fed4cSGilbert Chen     }
666c7fed4cSGilbert Chen 
676c7fed4cSGilbert Chen     /** @brief start a coroutine to discover terminus
686c7fed4cSGilbert Chen      *
696c7fed4cSGilbert Chen      *  @param[in] mctpInfos - list information of the MCTP endpoints
706c7fed4cSGilbert Chen      */
716c7fed4cSGilbert Chen     void discoverMctpTerminus(const MctpInfos& mctpInfos);
726c7fed4cSGilbert Chen 
736c7fed4cSGilbert Chen     /** @brief remove MCTP endpoints
746c7fed4cSGilbert Chen      *
756c7fed4cSGilbert Chen      *  @param[in] mctpInfos - list information of the MCTP endpoints
766c7fed4cSGilbert Chen      */
776c7fed4cSGilbert Chen     void removeMctpTerminus(const MctpInfos& mctpInfos);
786c7fed4cSGilbert Chen 
796c7fed4cSGilbert Chen     /** @brief Send request PLDM message to tid. The function will return when
806c7fed4cSGilbert Chen      *         received the response message from terminus. The function will
816c7fed4cSGilbert Chen      *         auto get the instanceID from libmctp and update to request
826c7fed4cSGilbert Chen      *         message.
836c7fed4cSGilbert Chen      *
846c7fed4cSGilbert Chen      *  @param[in] tid - Destination TID
856c7fed4cSGilbert Chen      *  @param[in] request - request PLDM message
866c7fed4cSGilbert Chen      *  @param[out] responseMsg - response PLDM message
876c7fed4cSGilbert Chen      *  @param[out] responseLen - length of response PLDM message
886c7fed4cSGilbert Chen      *  @return coroutine return_value - PLDM completion code
896c7fed4cSGilbert Chen      */
906c7fed4cSGilbert Chen     exec::task<int> sendRecvPldmMsg(pldm_tid_t tid, Request& request,
916c7fed4cSGilbert Chen                                     const pldm_msg** responseMsg,
926c7fed4cSGilbert Chen                                     size_t* responseLen);
936c7fed4cSGilbert Chen 
946c7fed4cSGilbert Chen     /** @brief Send request PLDM message to eid. The function will
956c7fed4cSGilbert Chen      *         return when received the response message from terminus.
966c7fed4cSGilbert Chen      *
976c7fed4cSGilbert Chen      *  @param[in] eid - Destination EID
986c7fed4cSGilbert Chen      *  @param[in] request - request PLDM message
996c7fed4cSGilbert Chen      *  @param[out] responseMsg - response PLDM message
1006c7fed4cSGilbert Chen      *  @param[out] responseLen - length of response PLDM message
1016c7fed4cSGilbert Chen      *  @return coroutine return_value - PLDM completion code
1026c7fed4cSGilbert Chen      */
10316c2a0a0SPatrick Williams     virtual exec::task<int> sendRecvPldmMsgOverMctp(
10416c2a0a0SPatrick Williams         mctp_eid_t eid, Request& request, const pldm_msg** responseMsg,
1056c7fed4cSGilbert Chen         size_t* responseLen);
1066c7fed4cSGilbert Chen 
1076c7fed4cSGilbert Chen     /** @brief member functions to map/unmap tid
1086c7fed4cSGilbert Chen      */
1096c7fed4cSGilbert Chen     std::optional<MctpInfo> toMctpInfo(const pldm_tid_t& tid);
1106c7fed4cSGilbert Chen 
1116c7fed4cSGilbert Chen     /** @brief Member functions to response the TID of specific MCTP interface
1126c7fed4cSGilbert Chen      *
1136c7fed4cSGilbert Chen      *  @param[in] mctpInfos - list information of the MCTP endpoints
1146c7fed4cSGilbert Chen      *
1156c7fed4cSGilbert Chen      *  @return tid - Terminus tid
1166c7fed4cSGilbert Chen      */
1176c7fed4cSGilbert Chen     std::optional<pldm_tid_t> toTid(const MctpInfo& mctpInfo) const;
1186c7fed4cSGilbert Chen 
1196c7fed4cSGilbert Chen     /** @brief Member functions to find the TID for MCTP interface. Response the
1206c7fed4cSGilbert Chen      *         Terminus TID when mctpInfo is already in the data base. Response
1216c7fed4cSGilbert Chen      *         new tid from pool when mctpInfo is new.
1226c7fed4cSGilbert Chen      *
1236c7fed4cSGilbert Chen      *  @param[in] mctpInfos - list information of the MCTP endpoints
1246c7fed4cSGilbert Chen      *
1256c7fed4cSGilbert Chen      *  @return tid - Terminus tid
1266c7fed4cSGilbert Chen      */
1276c7fed4cSGilbert Chen     std::optional<pldm_tid_t> mapTid(const MctpInfo& mctpInfo);
1286c7fed4cSGilbert Chen 
1296c7fed4cSGilbert Chen     /** @brief Member functions to store the mctp info and tid to terminus info
1306c7fed4cSGilbert Chen      *         list.
1316c7fed4cSGilbert Chen      *
1326c7fed4cSGilbert Chen      *  @param[in] mctpInfos - list information of the MCTP endpoints
1336c7fed4cSGilbert Chen      *  @param[in] tid - Destination TID
1346c7fed4cSGilbert Chen      *
1356c7fed4cSGilbert Chen      *  @return tid - Terminus tid
1366c7fed4cSGilbert Chen      */
137366507c8SPatrick Williams     std::optional<pldm_tid_t> storeTerminusInfo(const MctpInfo& mctpInfo,
138366507c8SPatrick Williams                                                 pldm_tid_t tid);
1396c7fed4cSGilbert Chen 
1406c7fed4cSGilbert Chen     /** @brief Member functions to remove the TID from the transportLayer and
1416c7fed4cSGilbert Chen      *         mctpInfo table
1426c7fed4cSGilbert Chen      *
1436c7fed4cSGilbert Chen      *  @param[in] tid - Destination TID
1446c7fed4cSGilbert Chen      *
1456c7fed4cSGilbert Chen      *  @return true/false - True when tid in the table otherwise return false
1466c7fed4cSGilbert Chen      */
1476c7fed4cSGilbert Chen     bool unmapTid(const pldm_tid_t& tid);
1486c7fed4cSGilbert Chen 
14951d66b59SThu Nguyen     /** @brief getter of local EID
15051d66b59SThu Nguyen      *
15151d66b59SThu Nguyen      *  @return uint8_t - local EID
15251d66b59SThu Nguyen      */
getLocalEid()15351d66b59SThu Nguyen     mctp_eid_t getLocalEid()
15451d66b59SThu Nguyen     {
15551d66b59SThu Nguyen         return localEid;
15651d66b59SThu Nguyen     }
15751d66b59SThu Nguyen 
15875e00422SChau Ly     /** @brief Helper function to invoke registered handlers for
15975e00422SChau Ly      *  updating the availability status of the MCTP endpoint
16075e00422SChau Ly      *
16175e00422SChau Ly      *  @param[in] mctpInfo - information of the target endpoint
16275e00422SChau Ly      *  @param[in] availability - new availability status
16375e00422SChau Ly      */
16475e00422SChau Ly     void updateMctpEndpointAvailability(const MctpInfo& mctpInfo,
16575e00422SChau Ly                                         Availability availability);
16675e00422SChau Ly 
1678fa40dbeSChau Ly     /** @brief Construct MCTP Endpoint object path base on the MCTP endpoint
1688fa40dbeSChau Ly      *  info
1698fa40dbeSChau Ly      *
1708fa40dbeSChau Ly      *  @param[in] mctpInfo - information of the target endpoint
1718fa40dbeSChau Ly      */
1728fa40dbeSChau Ly     std::string constructEndpointObjPath(const MctpInfo& mctpInfo);
1738fa40dbeSChau Ly 
17438e12aa2SThu Nguyen     /** @brief Member functions to get the MCTP eid of active MCTP medium
17538e12aa2SThu Nguyen      *         interface of one terminus by terminus name
17638e12aa2SThu Nguyen      *
17738e12aa2SThu Nguyen      *  @param[in] terminusName - terminus name
17838e12aa2SThu Nguyen      *
17938e12aa2SThu Nguyen      *  @return option mctp_eid_t - the mctp eid or std::nullopt
18038e12aa2SThu Nguyen      */
18138e12aa2SThu Nguyen     std::optional<mctp_eid_t> getActiveEidByName(
18238e12aa2SThu Nguyen         const std::string& terminusName);
18338e12aa2SThu Nguyen 
1846c7fed4cSGilbert Chen   private:
1856c7fed4cSGilbert Chen     /** @brief Find the terminus object pointer in termini list.
1866c7fed4cSGilbert Chen      *
1876c7fed4cSGilbert Chen      *  @param[in] mctpInfos - list information of the MCTP endpoints
1886c7fed4cSGilbert Chen      */
189ef5c4eb0SManojkiran Eda     TerminiMapper::iterator findTerminusPtr(const MctpInfo& mctpInfo);
1906c7fed4cSGilbert Chen 
1916c7fed4cSGilbert Chen     /** @brief The coroutine task execute by discoverMctpTerminus()
1926c7fed4cSGilbert Chen      *
1936c7fed4cSGilbert Chen      *  @return coroutine return_value - PLDM completion code
1946c7fed4cSGilbert Chen      */
1956c7fed4cSGilbert Chen     exec::task<int> discoverMctpTerminusTask();
1966c7fed4cSGilbert Chen 
1976c7fed4cSGilbert Chen     /** @brief Initialize terminus and then instantiate terminus object to keeps
1986c7fed4cSGilbert Chen      *         the data fetched from terminus
1996c7fed4cSGilbert Chen      *
2006c7fed4cSGilbert Chen      *  @param[in] mctpInfo - information of the MCTP endpoints
2016c7fed4cSGilbert Chen      *  @return coroutine return_value - PLDM completion code
2026c7fed4cSGilbert Chen      */
2036c7fed4cSGilbert Chen     exec::task<int> initMctpTerminus(const MctpInfo& mctpInfo);
2046c7fed4cSGilbert Chen 
2056c7fed4cSGilbert Chen     /** @brief Send getTID PLDM command to destination EID and then return the
2066c7fed4cSGilbert Chen      *         value of tid in reference parameter.
2076c7fed4cSGilbert Chen      *
2086c7fed4cSGilbert Chen      *  @param[in] eid - Destination EID
2096c7fed4cSGilbert Chen      *  @param[out] tid - Terminus TID
2106c7fed4cSGilbert Chen      *  @return coroutine return_value - PLDM completion code
2116c7fed4cSGilbert Chen      */
2126c7fed4cSGilbert Chen     exec::task<int> getTidOverMctp(mctp_eid_t eid, pldm_tid_t* tid);
2136c7fed4cSGilbert Chen 
2146c7fed4cSGilbert Chen     /** @brief Send setTID command to destination EID.
2156c7fed4cSGilbert Chen      *
2166c7fed4cSGilbert Chen      *  @param[in] eid - Destination EID
2176c7fed4cSGilbert Chen      *  @param[in] tid - Destination TID
2186c7fed4cSGilbert Chen      *  @return coroutine return_value - PLDM completion code
2196c7fed4cSGilbert Chen      */
2206c7fed4cSGilbert Chen     exec::task<int> setTidOverMctp(mctp_eid_t eid, pldm_tid_t tid);
2216c7fed4cSGilbert Chen 
2226c7fed4cSGilbert Chen     /** @brief Send getPLDMTypes command to destination TID and then return the
2236c7fed4cSGilbert Chen      *         value of supportedTypes in reference parameter.
2246c7fed4cSGilbert Chen      *
2256c7fed4cSGilbert Chen      *  @param[in] tid - Destination TID
2266c7fed4cSGilbert Chen      *  @param[out] supportedTypes - Supported Types returned from terminus
2276c7fed4cSGilbert Chen      *  @return coroutine return_value - PLDM completion code
2286c7fed4cSGilbert Chen      */
2296c7fed4cSGilbert Chen     exec::task<int> getPLDMTypes(pldm_tid_t tid, uint64_t& supportedTypes);
2306c7fed4cSGilbert Chen 
2316e615622SThu Nguyen     /** @brief Send getPLDMVersion command to destination TID and then return
2326e615622SThu Nguyen      *         the version of the PLDM supported type.
2336e615622SThu Nguyen      *
2346e615622SThu Nguyen      *  @param[in] tid - Destination TID
2356e615622SThu Nguyen      *  @param[in] type - PLDM Type
2366e615622SThu Nguyen      *  @param[out] version - PLDM Type version
2376e615622SThu Nguyen      *  @return coroutine return_value - PLDM completion code
2386e615622SThu Nguyen      */
2396e615622SThu Nguyen     exec::task<int> getPLDMVersion(pldm_tid_t tid, uint8_t type,
2406e615622SThu Nguyen                                    ver32_t* version);
2416e615622SThu Nguyen 
2426c7fed4cSGilbert Chen     /** @brief Send getPLDMCommands command to destination TID and then return
2436c7fed4cSGilbert Chen      *         the value of supportedCommands in reference parameter.
2446c7fed4cSGilbert Chen      *
2456c7fed4cSGilbert Chen      *  @param[in] tid - Destination TID
2466c7fed4cSGilbert Chen      *  @param[in] type - PLDM Type
2476e615622SThu Nguyen      *  @param[in] version - PLDM Type version
2486c7fed4cSGilbert Chen      *  @param[in] supportedCmds - Supported commands returned from terminus
2496c7fed4cSGilbert Chen      *                             for specific type
2506c7fed4cSGilbert Chen      *  @return coroutine return_value - PLDM completion code
2516c7fed4cSGilbert Chen      */
2526c7fed4cSGilbert Chen     exec::task<int> getPLDMCommands(pldm_tid_t tid, uint8_t type,
2536e615622SThu Nguyen                                     ver32_t version,
2546c7fed4cSGilbert Chen                                     bitfield8_t* supportedCmds);
2556c7fed4cSGilbert Chen 
2566c7fed4cSGilbert Chen     /** @brief Reference to a Handler object that manages the request/response
2576c7fed4cSGilbert Chen      *         logic.
2586c7fed4cSGilbert Chen      */
2596c7fed4cSGilbert Chen     RequesterHandler& handler;
2606c7fed4cSGilbert Chen 
2616c7fed4cSGilbert Chen     /** @brief Reference to the instanceID data base from libpldm */
2626c7fed4cSGilbert Chen     pldm::InstanceIdDb& instanceIdDb;
2636c7fed4cSGilbert Chen 
2646c7fed4cSGilbert Chen     /** @brief Managed termini list */
2656c7fed4cSGilbert Chen     TerminiMapper& termini;
2666c7fed4cSGilbert Chen 
2676c7fed4cSGilbert Chen     /** @brief tables for maintaining assigned TID */
2686c7fed4cSGilbert Chen     std::vector<bool> tidPool;
2696c7fed4cSGilbert Chen 
2706c7fed4cSGilbert Chen     /** @brief Store the supported transport layers of specific TID */
2716c7fed4cSGilbert Chen     std::map<pldm_tid_t, SupportedTransportLayer> transportLayerTable;
2726c7fed4cSGilbert Chen 
2736c7fed4cSGilbert Chen     /** @brief Store the supported MCTP interface info of specific TID */
2746c7fed4cSGilbert Chen     std::map<pldm_tid_t, MctpInfo> mctpInfoTable;
2756c7fed4cSGilbert Chen 
2766c7fed4cSGilbert Chen     /** @brief A queue of MctpInfos to be discovered **/
2776c7fed4cSGilbert Chen     std::queue<MctpInfos> queuedMctpInfos{};
2786c7fed4cSGilbert Chen 
2796c7fed4cSGilbert Chen     /** @brief coroutine handle of discoverTerminusTask */
2806c7fed4cSGilbert Chen     std::optional<std::pair<exec::async_scope, std::optional<int>>>
2816c7fed4cSGilbert Chen         discoverMctpTerminusTaskHandle{};
2826c7fed4cSGilbert Chen 
2836c7fed4cSGilbert Chen     /** @brief A Manager interface for calling the hook functions **/
2846c7fed4cSGilbert Chen     Manager* manager;
28551d66b59SThu Nguyen 
28651d66b59SThu Nguyen     /** @brief local EID */
28751d66b59SThu Nguyen     mctp_eid_t localEid;
28875e00422SChau Ly 
28975e00422SChau Ly     /** @brief MCTP Endpoint available status mapping */
29075e00422SChau Ly     std::map<MctpInfo, Availability> mctpInfoAvailTable;
291fdf61cc3SChaul Ly 
292fdf61cc3SChaul Ly     /** @brief reference of main event loop of pldmd, primarily used to schedule
293fdf61cc3SChaul Ly      *  work
294fdf61cc3SChaul Ly      */
295fdf61cc3SChaul Ly     sdeventplus::Event& event;
2966c7fed4cSGilbert Chen };
2976c7fed4cSGilbert Chen } // namespace platform_mc
2986c7fed4cSGilbert Chen } // namespace pldm
299