1 /* 2 * SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & 3 * AFFILIATES. All rights reserved. 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #pragma once 8 9 #include <OcpMctpVdm.hpp> 10 #include <boost/asio/generic/datagram_protocol.hpp> 11 #include <boost/asio/io_context.hpp> 12 #include <boost/asio/steady_timer.hpp> 13 #include <boost/container/devector.hpp> 14 15 #include <cstddef> 16 #include <cstdint> 17 #include <functional> 18 #include <memory> 19 #include <span> 20 #include <unordered_map> 21 #include <utility> 22 23 namespace mctp 24 { 25 class Requester 26 { 27 public: 28 Requester() = delete; 29 30 Requester(const Requester&) = delete; 31 32 Requester(Requester&&) = delete; 33 34 Requester& operator=(const Requester&) = delete; 35 36 Requester& operator=(Requester&&) = delete; 37 38 explicit Requester(boost::asio::io_context& ctx); 39 40 void sendRecvMsg(uint8_t eid, std::span<const uint8_t> reqMsg, 41 std::span<uint8_t> respMsg, 42 std::move_only_function<void(int)> callback); 43 44 private: 45 void processRecvMsg(std::span<const uint8_t> reqMsg, 46 std::span<uint8_t> respMsg, 47 const boost::system::error_code& ec, size_t length); 48 49 void handleSendMsgCompletion(uint8_t eid, std::span<const uint8_t> reqMsg, 50 std::span<uint8_t> respMsg, 51 const boost::system::error_code& ec, 52 size_t length); 53 54 boost::asio::generic::datagram_protocol::socket mctpSocket; 55 56 static constexpr size_t maxMessageSize = 65536 + 256; 57 58 boost::asio::generic::datagram_protocol::endpoint sendEndPoint; 59 60 boost::asio::generic::datagram_protocol::endpoint recvEndPoint; 61 62 boost::asio::steady_timer expiryTimer; 63 64 std::unordered_map<uint8_t, std::move_only_function<void(int)>> 65 completionCallbacks; 66 67 static constexpr uint8_t msgType = ocp::accelerator_management::messageType; 68 }; 69 70 class QueuingRequester 71 { 72 public: 73 QueuingRequester() = delete; 74 QueuingRequester(const QueuingRequester&) = delete; 75 QueuingRequester(QueuingRequester&&) = delete; 76 QueuingRequester& operator=(const QueuingRequester&) = delete; 77 QueuingRequester& operator=(QueuingRequester&&) = delete; 78 QueuingRequester(boost::asio::io_context & ctx)79 explicit QueuingRequester(boost::asio::io_context& ctx) : requester(ctx) {} 80 81 void sendRecvMsg(uint8_t eid, std::span<const uint8_t> reqMsg, 82 std::span<uint8_t> respMsg, 83 std::move_only_function<void(int)> callback); 84 85 private: 86 struct RequestContext 87 { 88 std::span<const uint8_t> reqMsg; 89 std::span<uint8_t> respMsg; 90 std::move_only_function<void(int)> callback; 91 92 RequestContext(const RequestContext&) = delete; 93 RequestContext& operator=(const RequestContext&) = delete; 94 95 RequestContext(RequestContext&&) = default; 96 RequestContext& operator=(RequestContext&&) = default; 97 ~RequestContext() = default; 98 RequestContextmctp::QueuingRequester::RequestContext99 explicit RequestContext(std::span<const uint8_t> req, 100 std::span<uint8_t> resp, 101 std::move_only_function<void(int)>&& cb) : 102 reqMsg(req), respMsg(resp), callback(std::move(cb)) 103 {} 104 }; 105 106 void handleResult(uint8_t eid, int result); 107 void processQueue(uint8_t eid); 108 109 Requester requester; 110 std::unordered_map< 111 uint8_t, boost::container::devector<std::unique_ptr<RequestContext>>> 112 requestContextQueues; 113 }; 114 115 using MctpRequester = QueuingRequester; 116 } // namespace mctp 117