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