blob: fa6a7ebd704c0527984e5493d23c47db5438d453 [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
Thu Nguyen51d66b52024-08-06 09:15:55 +000054 explicit TerminusManager(
Chaul Lyfdf61cc2025-01-22 07:55:45 +000055 sdeventplus::Event& event, RequesterHandler& handler,
Thu Nguyen51d66b52024-08-06 09:15:55 +000056 pldm::InstanceIdDb& instanceIdDb, TerminiMapper& termini,
57 Manager* manager, mctp_eid_t localEid) :
Patrick Williams16c2a0a2024-08-16 15:20:59 -040058 handler(handler), instanceIdDb(instanceIdDb), termini(termini),
Chaul Lyfdf61cc2025-01-22 07:55:45 +000059 tidPool(tidPoolSize, false), manager(manager), localEid(localEid),
60 event(event)
Gilbert Chen6c7fed42022-02-22 15:40:17 +000061 {
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 */
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400103 virtual exec::task<int> sendRecvPldmMsgOverMctp(
104 mctp_eid_t eid, Request& request, const pldm_msg** responseMsg,
105 size_t* responseLen);
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000106
107 /** @brief member functions to map/unmap tid
108 */
109 std::optional<MctpInfo> toMctpInfo(const pldm_tid_t& tid);
110
111 /** @brief Member functions to response the TID of specific MCTP interface
112 *
113 * @param[in] mctpInfos - list information of the MCTP endpoints
114 *
115 * @return tid - Terminus tid
116 */
117 std::optional<pldm_tid_t> toTid(const MctpInfo& mctpInfo) const;
118
119 /** @brief Member functions to find the TID for MCTP interface. Response the
120 * Terminus TID when mctpInfo is already in the data base. Response
121 * new tid from pool when mctpInfo is new.
122 *
123 * @param[in] mctpInfos - list information of the MCTP endpoints
124 *
125 * @return tid - Terminus tid
126 */
127 std::optional<pldm_tid_t> mapTid(const MctpInfo& mctpInfo);
128
129 /** @brief Member functions to store the mctp info and tid to terminus info
130 * list.
131 *
132 * @param[in] mctpInfos - list information of the MCTP endpoints
133 * @param[in] tid - Destination TID
134 *
135 * @return tid - Terminus tid
136 */
Patrick Williams366507c2025-02-03 14:28:01 -0500137 std::optional<pldm_tid_t> storeTerminusInfo(const MctpInfo& mctpInfo,
138 pldm_tid_t tid);
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000139
140 /** @brief Member functions to remove the TID from the transportLayer and
141 * mctpInfo table
142 *
143 * @param[in] tid - Destination TID
144 *
145 * @return true/false - True when tid in the table otherwise return false
146 */
147 bool unmapTid(const pldm_tid_t& tid);
148
Thu Nguyen51d66b52024-08-06 09:15:55 +0000149 /** @brief getter of local EID
150 *
151 * @return uint8_t - local EID
152 */
153 mctp_eid_t getLocalEid()
154 {
155 return localEid;
156 }
157
Chau Ly75e00422024-03-19 12:33:08 +0000158 /** @brief Helper function to invoke registered handlers for
159 * updating the availability status of the MCTP endpoint
160 *
161 * @param[in] mctpInfo - information of the target endpoint
162 * @param[in] availability - new availability status
163 */
164 void updateMctpEndpointAvailability(const MctpInfo& mctpInfo,
165 Availability availability);
166
Chau Ly8fa40db2024-04-02 09:32:01 +0000167 /** @brief Construct MCTP Endpoint object path base on the MCTP endpoint
168 * info
169 *
170 * @param[in] mctpInfo - information of the target endpoint
171 */
172 std::string constructEndpointObjPath(const MctpInfo& mctpInfo);
173
Thu Nguyen38e12aa2025-01-21 22:47:56 +0000174 /** @brief Member functions to get the MCTP eid of active MCTP medium
175 * interface of one terminus by terminus name
176 *
177 * @param[in] terminusName - terminus name
178 *
179 * @return option mctp_eid_t - the mctp eid or std::nullopt
180 */
181 std::optional<mctp_eid_t> getActiveEidByName(
182 const std::string& terminusName);
183
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000184 private:
185 /** @brief Find the terminus object pointer in termini list.
186 *
187 * @param[in] mctpInfos - list information of the MCTP endpoints
188 */
Manojkiran Edaef5c4eb2024-07-25 22:36:41 +0530189 TerminiMapper::iterator findTerminusPtr(const MctpInfo& mctpInfo);
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000190
191 /** @brief The coroutine task execute by discoverMctpTerminus()
192 *
193 * @return coroutine return_value - PLDM completion code
194 */
195 exec::task<int> discoverMctpTerminusTask();
196
197 /** @brief Initialize terminus and then instantiate terminus object to keeps
198 * the data fetched from terminus
199 *
200 * @param[in] mctpInfo - information of the MCTP endpoints
201 * @return coroutine return_value - PLDM completion code
202 */
203 exec::task<int> initMctpTerminus(const MctpInfo& mctpInfo);
204
205 /** @brief Send getTID PLDM command to destination EID and then return the
206 * value of tid in reference parameter.
207 *
208 * @param[in] eid - Destination EID
209 * @param[out] tid - Terminus TID
210 * @return coroutine return_value - PLDM completion code
211 */
212 exec::task<int> getTidOverMctp(mctp_eid_t eid, pldm_tid_t* tid);
213
214 /** @brief Send setTID command to destination EID.
215 *
216 * @param[in] eid - Destination EID
217 * @param[in] tid - Destination TID
218 * @return coroutine return_value - PLDM completion code
219 */
220 exec::task<int> setTidOverMctp(mctp_eid_t eid, pldm_tid_t tid);
221
222 /** @brief Send getPLDMTypes command to destination TID and then return the
223 * value of supportedTypes in reference parameter.
224 *
225 * @param[in] tid - Destination TID
226 * @param[out] supportedTypes - Supported Types returned from terminus
227 * @return coroutine return_value - PLDM completion code
228 */
229 exec::task<int> getPLDMTypes(pldm_tid_t tid, uint64_t& supportedTypes);
230
Thu Nguyen6e615622024-06-22 02:10:34 +0000231 /** @brief Send getPLDMVersion command to destination TID and then return
232 * the version of the PLDM supported type.
233 *
234 * @param[in] tid - Destination TID
235 * @param[in] type - PLDM Type
236 * @param[out] version - PLDM Type version
237 * @return coroutine return_value - PLDM completion code
238 */
239 exec::task<int> getPLDMVersion(pldm_tid_t tid, uint8_t type,
240 ver32_t* version);
241
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000242 /** @brief Send getPLDMCommands command to destination TID and then return
243 * the value of supportedCommands in reference parameter.
244 *
245 * @param[in] tid - Destination TID
246 * @param[in] type - PLDM Type
Thu Nguyen6e615622024-06-22 02:10:34 +0000247 * @param[in] version - PLDM Type version
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000248 * @param[in] supportedCmds - Supported commands returned from terminus
249 * for specific type
250 * @return coroutine return_value - PLDM completion code
251 */
252 exec::task<int> getPLDMCommands(pldm_tid_t tid, uint8_t type,
Thu Nguyen6e615622024-06-22 02:10:34 +0000253 ver32_t version,
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000254 bitfield8_t* supportedCmds);
255
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000256 /** @brief Reference to a Handler object that manages the request/response
257 * logic.
258 */
259 RequesterHandler& handler;
260
261 /** @brief Reference to the instanceID data base from libpldm */
262 pldm::InstanceIdDb& instanceIdDb;
263
264 /** @brief Managed termini list */
265 TerminiMapper& termini;
266
267 /** @brief tables for maintaining assigned TID */
268 std::vector<bool> tidPool;
269
270 /** @brief Store the supported transport layers of specific TID */
271 std::map<pldm_tid_t, SupportedTransportLayer> transportLayerTable;
272
273 /** @brief Store the supported MCTP interface info of specific TID */
274 std::map<pldm_tid_t, MctpInfo> mctpInfoTable;
275
276 /** @brief A queue of MctpInfos to be discovered **/
277 std::queue<MctpInfos> queuedMctpInfos{};
278
279 /** @brief coroutine handle of discoverTerminusTask */
280 std::optional<std::pair<exec::async_scope, std::optional<int>>>
281 discoverMctpTerminusTaskHandle{};
282
283 /** @brief A Manager interface for calling the hook functions **/
284 Manager* manager;
Thu Nguyen51d66b52024-08-06 09:15:55 +0000285
286 /** @brief local EID */
287 mctp_eid_t localEid;
Chau Ly75e00422024-03-19 12:33:08 +0000288
289 /** @brief MCTP Endpoint available status mapping */
290 std::map<MctpInfo, Availability> mctpInfoAvailTable;
Chaul Lyfdf61cc2025-01-22 07:55:45 +0000291
292 /** @brief reference of main event loop of pldmd, primarily used to schedule
293 * work
294 */
295 sdeventplus::Event& event;
Gilbert Chen6c7fed42022-02-22 15:40:17 +0000296};
297} // namespace platform_mc
298} // namespace pldm