1 #pragma once 2 3 #include "config.h" 4 5 #include "requester/handler.hpp" 6 #include "requester/mctp_endpoint_discovery.hpp" 7 #include "terminus.hpp" 8 9 #include <libpldm/platform.h> 10 #include <libpldm/pldm.h> 11 12 #include <limits> 13 #include <map> 14 #include <memory> 15 #include <optional> 16 #include <queue> 17 #include <utility> 18 #include <vector> 19 20 namespace pldm 21 { 22 23 enum class SupportedTransportLayer 24 { 25 MCTP 26 }; 27 28 namespace platform_mc 29 { 30 31 /** @brief Size of TID Pool in pldmd */ 32 constexpr size_t tidPoolSize = std::numeric_limits<pldm_tid_t>::max() + 1; 33 /** @brief Type definition for Requester request handler */ 34 using RequesterHandler = requester::Handler<requester::Request>; 35 /** @brief Type definition for Terminus handler mapper */ 36 using TerminiMapper = std::map<pldm_tid_t, std::shared_ptr<Terminus>>; 37 38 class Manager; 39 /** 40 * @brief TerminusManager 41 * 42 * TerminusManager class to discover and initialize PLDM terminus. 43 */ 44 class 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 TerminusManager(sdeventplus::Event & event,RequesterHandler & handler,pldm::InstanceIdDb & instanceIdDb,TerminiMapper & termini,Manager * manager,mctp_eid_t localEid)54 explicit TerminusManager( 55 sdeventplus::Event& event, RequesterHandler& handler, 56 pldm::InstanceIdDb& instanceIdDb, TerminiMapper& termini, 57 Manager* manager, mctp_eid_t localEid) : 58 handler(handler), instanceIdDb(instanceIdDb), termini(termini), 59 tidPool(tidPoolSize, false), manager(manager), localEid(localEid), 60 event(event) 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> sendRecvPldmMsgOverMctp( 104 mctp_eid_t eid, Request& request, const pldm_msg** responseMsg, 105 size_t* responseLen); 106 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 */ 137 std::optional<pldm_tid_t> storeTerminusInfo(const MctpInfo& mctpInfo, 138 pldm_tid_t tid); 139 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 149 /** @brief getter of local EID 150 * 151 * @return uint8_t - local EID 152 */ getLocalEid()153 mctp_eid_t getLocalEid() 154 { 155 return localEid; 156 } 157 158 /** @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 167 /** @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 174 /** @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 184 private: 185 /** @brief Find the terminus object pointer in termini list. 186 * 187 * @param[in] mctpInfos - list information of the MCTP endpoints 188 */ 189 TerminiMapper::iterator findTerminusPtr(const MctpInfo& mctpInfo); 190 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 231 /** @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 242 /** @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 247 * @param[in] version - PLDM Type version 248 * @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, 253 ver32_t version, 254 bitfield8_t* supportedCmds); 255 256 /** @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; 285 286 /** @brief local EID */ 287 mctp_eid_t localEid; 288 289 /** @brief MCTP Endpoint available status mapping */ 290 std::map<MctpInfo, Availability> mctpInfoAvailTable; 291 292 /** @brief reference of main event loop of pldmd, primarily used to schedule 293 * work 294 */ 295 sdeventplus::Event& event; 296 }; 297 } // namespace platform_mc 298 } // namespace pldm 299