xref: /openbmc/dbus-sensors/src/nvidia-gpu/MctpRequester.hpp (revision ed0af21ca6092a7ceb19660b69b76a5c304efcb0)
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