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 54 explicit TerminusManager(sdeventplus::Event& /* event */, 55 RequesterHandler& handler, 56 pldm::InstanceIdDb& instanceIdDb, 57 TerminiMapper& termini, Manager* manager) : 58 handler(handler), 59 instanceIdDb(instanceIdDb), termini(termini), 60 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 */ 155 TerminiMapper::iterator findTerminusPtr(const MctpInfo& mctpInfo); 156 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 209 /** @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 241