1*6c7fed4cSGilbert Chen #pragma once
2*6c7fed4cSGilbert Chen 
3*6c7fed4cSGilbert Chen #include "config.h"
4*6c7fed4cSGilbert Chen 
5*6c7fed4cSGilbert Chen #include "libpldm/platform.h"
6*6c7fed4cSGilbert Chen #include "libpldm/pldm.h"
7*6c7fed4cSGilbert Chen 
8*6c7fed4cSGilbert Chen #include "requester/handler.hpp"
9*6c7fed4cSGilbert Chen #include "requester/mctp_endpoint_discovery.hpp"
10*6c7fed4cSGilbert Chen #include "terminus.hpp"
11*6c7fed4cSGilbert Chen 
12*6c7fed4cSGilbert Chen #include <limits>
13*6c7fed4cSGilbert Chen #include <map>
14*6c7fed4cSGilbert Chen #include <memory>
15*6c7fed4cSGilbert Chen #include <optional>
16*6c7fed4cSGilbert Chen #include <queue>
17*6c7fed4cSGilbert Chen #include <utility>
18*6c7fed4cSGilbert Chen #include <vector>
19*6c7fed4cSGilbert Chen 
20*6c7fed4cSGilbert Chen namespace pldm
21*6c7fed4cSGilbert Chen {
22*6c7fed4cSGilbert Chen 
23*6c7fed4cSGilbert Chen enum class SupportedTransportLayer
24*6c7fed4cSGilbert Chen {
25*6c7fed4cSGilbert Chen     MCTP
26*6c7fed4cSGilbert Chen };
27*6c7fed4cSGilbert Chen 
28*6c7fed4cSGilbert Chen namespace platform_mc
29*6c7fed4cSGilbert Chen {
30*6c7fed4cSGilbert Chen 
31*6c7fed4cSGilbert Chen /** @brief Size of TID Pool in pldmd */
32*6c7fed4cSGilbert Chen constexpr size_t tidPoolSize = std::numeric_limits<pldm_tid_t>::max() + 1;
33*6c7fed4cSGilbert Chen /** @brief Type definition for Requester request handler */
34*6c7fed4cSGilbert Chen using RequesterHandler = requester::Handler<requester::Request>;
35*6c7fed4cSGilbert Chen /** @brief Type definition for Terminus handler mapper */
36*6c7fed4cSGilbert Chen using TerminiMapper = std::map<pldm_tid_t, std::shared_ptr<Terminus>>;
37*6c7fed4cSGilbert Chen 
38*6c7fed4cSGilbert Chen class Manager;
39*6c7fed4cSGilbert Chen /**
40*6c7fed4cSGilbert Chen  * @brief TerminusManager
41*6c7fed4cSGilbert Chen  *
42*6c7fed4cSGilbert Chen  * TerminusManager class to discover and initialize PLDM terminus.
43*6c7fed4cSGilbert Chen  */
44*6c7fed4cSGilbert Chen class TerminusManager
45*6c7fed4cSGilbert Chen {
46*6c7fed4cSGilbert Chen   public:
47*6c7fed4cSGilbert Chen     TerminusManager() = delete;
48*6c7fed4cSGilbert Chen     TerminusManager(const TerminusManager&) = delete;
49*6c7fed4cSGilbert Chen     TerminusManager(TerminusManager&&) = delete;
50*6c7fed4cSGilbert Chen     TerminusManager& operator=(const TerminusManager&) = delete;
51*6c7fed4cSGilbert Chen     TerminusManager& operator=(TerminusManager&&) = delete;
52*6c7fed4cSGilbert Chen     virtual ~TerminusManager() = default;
53*6c7fed4cSGilbert Chen 
TerminusManager(sdeventplus::Event & event,RequesterHandler & handler,pldm::InstanceIdDb & instanceIdDb,TerminiMapper & termini,Manager * manager)54*6c7fed4cSGilbert Chen     explicit TerminusManager(sdeventplus::Event& event,
55*6c7fed4cSGilbert Chen                              RequesterHandler& handler,
56*6c7fed4cSGilbert Chen                              pldm::InstanceIdDb& instanceIdDb,
57*6c7fed4cSGilbert Chen                              TerminiMapper& termini, Manager* manager) :
58*6c7fed4cSGilbert Chen         event(event),
59*6c7fed4cSGilbert Chen         handler(handler), instanceIdDb(instanceIdDb), termini(termini),
60*6c7fed4cSGilbert Chen         tidPool(tidPoolSize, false), manager(manager)
61*6c7fed4cSGilbert Chen     {
62*6c7fed4cSGilbert Chen         // DSP0240 v1.1.0 table-8, special value: 0,0xFF = reserved
63*6c7fed4cSGilbert Chen         tidPool[0] = true;
64*6c7fed4cSGilbert Chen         tidPool[PLDM_TID_RESERVED] = true;
65*6c7fed4cSGilbert Chen     }
66*6c7fed4cSGilbert Chen 
67*6c7fed4cSGilbert Chen     /** @brief start a coroutine to discover terminus
68*6c7fed4cSGilbert Chen      *
69*6c7fed4cSGilbert Chen      *  @param[in] mctpInfos - list information of the MCTP endpoints
70*6c7fed4cSGilbert Chen      */
71*6c7fed4cSGilbert Chen     void discoverMctpTerminus(const MctpInfos& mctpInfos);
72*6c7fed4cSGilbert Chen 
73*6c7fed4cSGilbert Chen     /** @brief remove MCTP endpoints
74*6c7fed4cSGilbert Chen      *
75*6c7fed4cSGilbert Chen      *  @param[in] mctpInfos - list information of the MCTP endpoints
76*6c7fed4cSGilbert Chen      */
77*6c7fed4cSGilbert Chen     void removeMctpTerminus(const MctpInfos& mctpInfos);
78*6c7fed4cSGilbert Chen 
79*6c7fed4cSGilbert Chen     /** @brief Send request PLDM message to tid. The function will return when
80*6c7fed4cSGilbert Chen      *         received the response message from terminus. The function will
81*6c7fed4cSGilbert Chen      *         auto get the instanceID from libmctp and update to request
82*6c7fed4cSGilbert Chen      *         message.
83*6c7fed4cSGilbert Chen      *
84*6c7fed4cSGilbert Chen      *  @param[in] tid - Destination TID
85*6c7fed4cSGilbert Chen      *  @param[in] request - request PLDM message
86*6c7fed4cSGilbert Chen      *  @param[out] responseMsg - response PLDM message
87*6c7fed4cSGilbert Chen      *  @param[out] responseLen - length of response PLDM message
88*6c7fed4cSGilbert Chen      *  @return coroutine return_value - PLDM completion code
89*6c7fed4cSGilbert Chen      */
90*6c7fed4cSGilbert Chen     exec::task<int> sendRecvPldmMsg(pldm_tid_t tid, Request& request,
91*6c7fed4cSGilbert Chen                                     const pldm_msg** responseMsg,
92*6c7fed4cSGilbert Chen                                     size_t* responseLen);
93*6c7fed4cSGilbert Chen 
94*6c7fed4cSGilbert Chen     /** @brief Send request PLDM message to eid. The function will
95*6c7fed4cSGilbert Chen      *         return when received the response message from terminus.
96*6c7fed4cSGilbert Chen      *
97*6c7fed4cSGilbert Chen      *  @param[in] eid - Destination EID
98*6c7fed4cSGilbert Chen      *  @param[in] request - request PLDM message
99*6c7fed4cSGilbert Chen      *  @param[out] responseMsg - response PLDM message
100*6c7fed4cSGilbert Chen      *  @param[out] responseLen - length of response PLDM message
101*6c7fed4cSGilbert Chen      *  @return coroutine return_value - PLDM completion code
102*6c7fed4cSGilbert Chen      */
103*6c7fed4cSGilbert Chen     virtual exec::task<int>
104*6c7fed4cSGilbert Chen         sendRecvPldmMsgOverMctp(mctp_eid_t eid, Request& request,
105*6c7fed4cSGilbert Chen                                 const pldm_msg** responseMsg,
106*6c7fed4cSGilbert Chen                                 size_t* responseLen);
107*6c7fed4cSGilbert Chen 
108*6c7fed4cSGilbert Chen     /** @brief member functions to map/unmap tid
109*6c7fed4cSGilbert Chen      */
110*6c7fed4cSGilbert Chen     std::optional<MctpInfo> toMctpInfo(const pldm_tid_t& tid);
111*6c7fed4cSGilbert Chen 
112*6c7fed4cSGilbert Chen     /** @brief Member functions to response the TID of specific MCTP interface
113*6c7fed4cSGilbert Chen      *
114*6c7fed4cSGilbert Chen      *  @param[in] mctpInfos - list information of the MCTP endpoints
115*6c7fed4cSGilbert Chen      *
116*6c7fed4cSGilbert Chen      *  @return tid - Terminus tid
117*6c7fed4cSGilbert Chen      */
118*6c7fed4cSGilbert Chen     std::optional<pldm_tid_t> toTid(const MctpInfo& mctpInfo) const;
119*6c7fed4cSGilbert Chen 
120*6c7fed4cSGilbert Chen     /** @brief Member functions to find the TID for MCTP interface. Response the
121*6c7fed4cSGilbert Chen      *         Terminus TID when mctpInfo is already in the data base. Response
122*6c7fed4cSGilbert Chen      *         new tid from pool when mctpInfo is new.
123*6c7fed4cSGilbert Chen      *
124*6c7fed4cSGilbert Chen      *  @param[in] mctpInfos - list information of the MCTP endpoints
125*6c7fed4cSGilbert Chen      *
126*6c7fed4cSGilbert Chen      *  @return tid - Terminus tid
127*6c7fed4cSGilbert Chen      */
128*6c7fed4cSGilbert Chen     std::optional<pldm_tid_t> mapTid(const MctpInfo& mctpInfo);
129*6c7fed4cSGilbert Chen 
130*6c7fed4cSGilbert Chen     /** @brief Member functions to store the mctp info and tid to terminus info
131*6c7fed4cSGilbert Chen      *         list.
132*6c7fed4cSGilbert Chen      *
133*6c7fed4cSGilbert Chen      *  @param[in] mctpInfos - list information of the MCTP endpoints
134*6c7fed4cSGilbert Chen      *  @param[in] tid - Destination TID
135*6c7fed4cSGilbert Chen      *
136*6c7fed4cSGilbert Chen      *  @return tid - Terminus tid
137*6c7fed4cSGilbert Chen      */
138*6c7fed4cSGilbert Chen     std::optional<pldm_tid_t> storeTerminusInfo(const MctpInfo& mctpInfo,
139*6c7fed4cSGilbert Chen                                                 pldm_tid_t tid);
140*6c7fed4cSGilbert Chen 
141*6c7fed4cSGilbert Chen     /** @brief Member functions to remove the TID from the transportLayer and
142*6c7fed4cSGilbert Chen      *         mctpInfo table
143*6c7fed4cSGilbert Chen      *
144*6c7fed4cSGilbert Chen      *  @param[in] tid - Destination TID
145*6c7fed4cSGilbert Chen      *
146*6c7fed4cSGilbert Chen      *  @return true/false - True when tid in the table otherwise return false
147*6c7fed4cSGilbert Chen      */
148*6c7fed4cSGilbert Chen     bool unmapTid(const pldm_tid_t& tid);
149*6c7fed4cSGilbert Chen 
150*6c7fed4cSGilbert Chen   private:
151*6c7fed4cSGilbert Chen     /** @brief Find the terminus object pointer in termini list.
152*6c7fed4cSGilbert Chen      *
153*6c7fed4cSGilbert Chen      *  @param[in] mctpInfos - list information of the MCTP endpoints
154*6c7fed4cSGilbert Chen      */
155*6c7fed4cSGilbert Chen     auto findTeminusPtr(const MctpInfo& mctpInfo);
156*6c7fed4cSGilbert Chen 
157*6c7fed4cSGilbert Chen     /** @brief The coroutine task execute by discoverMctpTerminus()
158*6c7fed4cSGilbert Chen      *
159*6c7fed4cSGilbert Chen      *  @return coroutine return_value - PLDM completion code
160*6c7fed4cSGilbert Chen      */
161*6c7fed4cSGilbert Chen     exec::task<int> discoverMctpTerminusTask();
162*6c7fed4cSGilbert Chen 
163*6c7fed4cSGilbert Chen     /** @brief Initialize terminus and then instantiate terminus object to keeps
164*6c7fed4cSGilbert Chen      *         the data fetched from terminus
165*6c7fed4cSGilbert Chen      *
166*6c7fed4cSGilbert Chen      *  @param[in] mctpInfo - information of the MCTP endpoints
167*6c7fed4cSGilbert Chen      *  @return coroutine return_value - PLDM completion code
168*6c7fed4cSGilbert Chen      */
169*6c7fed4cSGilbert Chen     exec::task<int> initMctpTerminus(const MctpInfo& mctpInfo);
170*6c7fed4cSGilbert Chen 
171*6c7fed4cSGilbert Chen     /** @brief Send getTID PLDM command to destination EID and then return the
172*6c7fed4cSGilbert Chen      *         value of tid in reference parameter.
173*6c7fed4cSGilbert Chen      *
174*6c7fed4cSGilbert Chen      *  @param[in] eid - Destination EID
175*6c7fed4cSGilbert Chen      *  @param[out] tid - Terminus TID
176*6c7fed4cSGilbert Chen      *  @return coroutine return_value - PLDM completion code
177*6c7fed4cSGilbert Chen      */
178*6c7fed4cSGilbert Chen     exec::task<int> getTidOverMctp(mctp_eid_t eid, pldm_tid_t* tid);
179*6c7fed4cSGilbert Chen 
180*6c7fed4cSGilbert Chen     /** @brief Send setTID command to destination EID.
181*6c7fed4cSGilbert Chen      *
182*6c7fed4cSGilbert Chen      *  @param[in] eid - Destination EID
183*6c7fed4cSGilbert Chen      *  @param[in] tid - Destination TID
184*6c7fed4cSGilbert Chen      *  @return coroutine return_value - PLDM completion code
185*6c7fed4cSGilbert Chen      */
186*6c7fed4cSGilbert Chen     exec::task<int> setTidOverMctp(mctp_eid_t eid, pldm_tid_t tid);
187*6c7fed4cSGilbert Chen 
188*6c7fed4cSGilbert Chen     /** @brief Send getPLDMTypes command to destination TID and then return the
189*6c7fed4cSGilbert Chen      *         value of supportedTypes in reference parameter.
190*6c7fed4cSGilbert Chen      *
191*6c7fed4cSGilbert Chen      *  @param[in] tid - Destination TID
192*6c7fed4cSGilbert Chen      *  @param[out] supportedTypes - Supported Types returned from terminus
193*6c7fed4cSGilbert Chen      *  @return coroutine return_value - PLDM completion code
194*6c7fed4cSGilbert Chen      */
195*6c7fed4cSGilbert Chen     exec::task<int> getPLDMTypes(pldm_tid_t tid, uint64_t& supportedTypes);
196*6c7fed4cSGilbert Chen 
197*6c7fed4cSGilbert Chen     /** @brief Send getPLDMCommands command to destination TID and then return
198*6c7fed4cSGilbert Chen      *         the value of supportedCommands in reference parameter.
199*6c7fed4cSGilbert Chen      *
200*6c7fed4cSGilbert Chen      *  @param[in] tid - Destination TID
201*6c7fed4cSGilbert Chen      *  @param[in] type - PLDM Type
202*6c7fed4cSGilbert Chen      *  @param[in] supportedCmds - Supported commands returned from terminus
203*6c7fed4cSGilbert Chen      *                             for specific type
204*6c7fed4cSGilbert Chen      *  @return coroutine return_value - PLDM completion code
205*6c7fed4cSGilbert Chen      */
206*6c7fed4cSGilbert Chen     exec::task<int> getPLDMCommands(pldm_tid_t tid, uint8_t type,
207*6c7fed4cSGilbert Chen                                     bitfield8_t* supportedCmds);
208*6c7fed4cSGilbert Chen 
209*6c7fed4cSGilbert Chen     /** @brief Reference to to PLDM daemon's main event loop.
210*6c7fed4cSGilbert Chen      */
211*6c7fed4cSGilbert Chen     sdeventplus::Event& event;
212*6c7fed4cSGilbert Chen 
213*6c7fed4cSGilbert Chen     /** @brief Reference to a Handler object that manages the request/response
214*6c7fed4cSGilbert Chen      *         logic.
215*6c7fed4cSGilbert Chen      */
216*6c7fed4cSGilbert Chen     RequesterHandler& handler;
217*6c7fed4cSGilbert Chen 
218*6c7fed4cSGilbert Chen     /** @brief Reference to the instanceID data base from libpldm */
219*6c7fed4cSGilbert Chen     pldm::InstanceIdDb& instanceIdDb;
220*6c7fed4cSGilbert Chen 
221*6c7fed4cSGilbert Chen     /** @brief Managed termini list */
222*6c7fed4cSGilbert Chen     TerminiMapper& termini;
223*6c7fed4cSGilbert Chen 
224*6c7fed4cSGilbert Chen     /** @brief tables for maintaining assigned TID */
225*6c7fed4cSGilbert Chen     std::vector<bool> tidPool;
226*6c7fed4cSGilbert Chen 
227*6c7fed4cSGilbert Chen     /** @brief Store the supported transport layers of specific TID */
228*6c7fed4cSGilbert Chen     std::map<pldm_tid_t, SupportedTransportLayer> transportLayerTable;
229*6c7fed4cSGilbert Chen 
230*6c7fed4cSGilbert Chen     /** @brief Store the supported MCTP interface info of specific TID */
231*6c7fed4cSGilbert Chen     std::map<pldm_tid_t, MctpInfo> mctpInfoTable;
232*6c7fed4cSGilbert Chen 
233*6c7fed4cSGilbert Chen     /** @brief A queue of MctpInfos to be discovered **/
234*6c7fed4cSGilbert Chen     std::queue<MctpInfos> queuedMctpInfos{};
235*6c7fed4cSGilbert Chen 
236*6c7fed4cSGilbert Chen     /** @brief coroutine handle of discoverTerminusTask */
237*6c7fed4cSGilbert Chen     std::optional<std::pair<exec::async_scope, std::optional<int>>>
238*6c7fed4cSGilbert Chen         discoverMctpTerminusTaskHandle{};
239*6c7fed4cSGilbert Chen 
240*6c7fed4cSGilbert Chen     /** @brief A Manager interface for calling the hook functions **/
241*6c7fed4cSGilbert Chen     Manager* manager;
242*6c7fed4cSGilbert Chen };
243*6c7fed4cSGilbert Chen } // namespace platform_mc
244*6c7fed4cSGilbert Chen } // namespace pldm
245