1 #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 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 &,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 { 61 // DSP0240 v1.1.0 table-8, special value: 0,0xFF = reserved 62 tidPool[0] = true; 63 tidPool[PLDM_TID_RESERVED] = true; 64 } 65 66 /** @brief start a coroutine to discover terminus 67 * 68 * @param[in] mctpInfos - list information of the MCTP endpoints 69 */ 70 void discoverMctpTerminus(const MctpInfos& mctpInfos); 71 72 /** @brief remove MCTP endpoints 73 * 74 * @param[in] mctpInfos - list information of the MCTP endpoints 75 */ 76 void removeMctpTerminus(const MctpInfos& mctpInfos); 77 78 /** @brief Send request PLDM message to tid. The function will return when 79 * received the response message from terminus. The function will 80 * auto get the instanceID from libmctp and update to request 81 * message. 82 * 83 * @param[in] tid - Destination TID 84 * @param[in] request - request PLDM message 85 * @param[out] responseMsg - response PLDM message 86 * @param[out] responseLen - length of response PLDM message 87 * @return coroutine return_value - PLDM completion code 88 */ 89 exec::task<int> sendRecvPldmMsg(pldm_tid_t tid, Request& request, 90 const pldm_msg** responseMsg, 91 size_t* responseLen); 92 93 /** @brief Send request PLDM message to eid. The function will 94 * return when received the response message from terminus. 95 * 96 * @param[in] eid - Destination EID 97 * @param[in] request - request PLDM message 98 * @param[out] responseMsg - response PLDM message 99 * @param[out] responseLen - length of response PLDM message 100 * @return coroutine return_value - PLDM completion code 101 */ 102 virtual exec::task<int> sendRecvPldmMsgOverMctp( 103 mctp_eid_t eid, Request& request, const pldm_msg** responseMsg, 104 size_t* responseLen); 105 106 /** @brief member functions to map/unmap tid 107 */ 108 std::optional<MctpInfo> toMctpInfo(const pldm_tid_t& tid); 109 110 /** @brief Member functions to response the TID of specific MCTP interface 111 * 112 * @param[in] mctpInfos - list information of the MCTP endpoints 113 * 114 * @return tid - Terminus tid 115 */ 116 std::optional<pldm_tid_t> toTid(const MctpInfo& mctpInfo) const; 117 118 /** @brief Member functions to find the TID for MCTP interface. Response the 119 * Terminus TID when mctpInfo is already in the data base. Response 120 * new tid from pool when mctpInfo is new. 121 * 122 * @param[in] mctpInfos - list information of the MCTP endpoints 123 * 124 * @return tid - Terminus tid 125 */ 126 std::optional<pldm_tid_t> mapTid(const MctpInfo& mctpInfo); 127 128 /** @brief Member functions to store the mctp info and tid to terminus info 129 * list. 130 * 131 * @param[in] mctpInfos - list information of the MCTP endpoints 132 * @param[in] tid - Destination TID 133 * 134 * @return tid - Terminus tid 135 */ 136 std::optional<pldm_tid_t> 137 storeTerminusInfo(const MctpInfo& mctpInfo, pldm_tid_t tid); 138 139 /** @brief Member functions to remove the TID from the transportLayer and 140 * mctpInfo table 141 * 142 * @param[in] tid - Destination TID 143 * 144 * @return true/false - True when tid in the table otherwise return false 145 */ 146 bool unmapTid(const pldm_tid_t& tid); 147 148 /** @brief getter of local EID 149 * 150 * @return uint8_t - local EID 151 */ getLocalEid()152 mctp_eid_t getLocalEid() 153 { 154 return localEid; 155 } 156 157 private: 158 /** @brief Find the terminus object pointer in termini list. 159 * 160 * @param[in] mctpInfos - list information of the MCTP endpoints 161 */ 162 TerminiMapper::iterator findTerminusPtr(const MctpInfo& mctpInfo); 163 164 /** @brief The coroutine task execute by discoverMctpTerminus() 165 * 166 * @return coroutine return_value - PLDM completion code 167 */ 168 exec::task<int> discoverMctpTerminusTask(); 169 170 /** @brief Initialize terminus and then instantiate terminus object to keeps 171 * the data fetched from terminus 172 * 173 * @param[in] mctpInfo - information of the MCTP endpoints 174 * @return coroutine return_value - PLDM completion code 175 */ 176 exec::task<int> initMctpTerminus(const MctpInfo& mctpInfo); 177 178 /** @brief Send getTID PLDM command to destination EID and then return the 179 * value of tid in reference parameter. 180 * 181 * @param[in] eid - Destination EID 182 * @param[out] tid - Terminus TID 183 * @return coroutine return_value - PLDM completion code 184 */ 185 exec::task<int> getTidOverMctp(mctp_eid_t eid, pldm_tid_t* tid); 186 187 /** @brief Send setTID command to destination EID. 188 * 189 * @param[in] eid - Destination EID 190 * @param[in] tid - Destination TID 191 * @return coroutine return_value - PLDM completion code 192 */ 193 exec::task<int> setTidOverMctp(mctp_eid_t eid, pldm_tid_t tid); 194 195 /** @brief Send getPLDMTypes command to destination TID and then return the 196 * value of supportedTypes in reference parameter. 197 * 198 * @param[in] tid - Destination TID 199 * @param[out] supportedTypes - Supported Types returned from terminus 200 * @return coroutine return_value - PLDM completion code 201 */ 202 exec::task<int> getPLDMTypes(pldm_tid_t tid, uint64_t& supportedTypes); 203 204 /** @brief Send getPLDMVersion command to destination TID and then return 205 * the version of the PLDM supported type. 206 * 207 * @param[in] tid - Destination TID 208 * @param[in] type - PLDM Type 209 * @param[out] version - PLDM Type version 210 * @return coroutine return_value - PLDM completion code 211 */ 212 exec::task<int> getPLDMVersion(pldm_tid_t tid, uint8_t type, 213 ver32_t* version); 214 215 /** @brief Send getPLDMCommands command to destination TID and then return 216 * the value of supportedCommands in reference parameter. 217 * 218 * @param[in] tid - Destination TID 219 * @param[in] type - PLDM Type 220 * @param[in] version - PLDM Type version 221 * @param[in] supportedCmds - Supported commands returned from terminus 222 * for specific type 223 * @return coroutine return_value - PLDM completion code 224 */ 225 exec::task<int> getPLDMCommands(pldm_tid_t tid, uint8_t type, 226 ver32_t version, 227 bitfield8_t* supportedCmds); 228 229 /** @brief Reference to a Handler object that manages the request/response 230 * logic. 231 */ 232 RequesterHandler& handler; 233 234 /** @brief Reference to the instanceID data base from libpldm */ 235 pldm::InstanceIdDb& instanceIdDb; 236 237 /** @brief Managed termini list */ 238 TerminiMapper& termini; 239 240 /** @brief tables for maintaining assigned TID */ 241 std::vector<bool> tidPool; 242 243 /** @brief Store the supported transport layers of specific TID */ 244 std::map<pldm_tid_t, SupportedTransportLayer> transportLayerTable; 245 246 /** @brief Store the supported MCTP interface info of specific TID */ 247 std::map<pldm_tid_t, MctpInfo> mctpInfoTable; 248 249 /** @brief A queue of MctpInfos to be discovered **/ 250 std::queue<MctpInfos> queuedMctpInfos{}; 251 252 /** @brief coroutine handle of discoverTerminusTask */ 253 std::optional<std::pair<exec::async_scope, std::optional<int>>> 254 discoverMctpTerminusTaskHandle{}; 255 256 /** @brief A Manager interface for calling the hook functions **/ 257 Manager* manager; 258 259 /** @brief local EID */ 260 mctp_eid_t localEid; 261 }; 262 } // namespace platform_mc 263 } // namespace pldm 264