blob: eca3bd916d5e8b404f7fd2e1144eeac6c5d3b428 [file] [log] [blame]
Harshit Aghera560e6af2025-04-21 20:04:56 +05301/*
Ed Tanousb5e823f2025-10-09 20:28:42 -04002 * SPDX-FileCopyrightText: Copyright OpenBMC Authors
Harshit Aghera560e6af2025-04-21 20:04:56 +05303 * SPDX-License-Identifier: Apache-2.0
4 */
5
6#pragma once
7
Marc Olberdingd0125c92025-10-08 14:37:19 -07008#include <MctpAsioEndpoint.hpp>
Harshit Aghera560e6af2025-04-21 20:04:56 +05309#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>
Marc Olberdingd0125c92025-10-08 14:37:19 -070013#include <boost/circular_buffer.hpp>
Aditya Kurdunkared0af212025-06-11 04:38:52 +053014#include <boost/container/devector.hpp>
Marc Olberdingd0125c92025-10-08 14:37:19 -070015#include <boost/container/flat_map.hpp>
16#include <boost/container/small_vector.hpp>
Harshit Aghera560e6af2025-04-21 20:04:56 +053017
18#include <cstddef>
19#include <cstdint>
Marc Olberdingd0125c92025-10-08 14:37:19 -070020#include <expected>
Harshit Aghera560e6af2025-04-21 20:04:56 +053021#include <functional>
Marc Olberdingd0125c92025-10-08 14:37:19 -070022#include <iostream>
Aditya Kurdunkared0af212025-06-11 04:38:52 +053023#include <memory>
Marc Olberdingd0125c92025-10-08 14:37:19 -070024#include <queue>
Harshit Aghera560e6af2025-04-21 20:04:56 +053025#include <span>
Marc Olberdingd0125c92025-10-08 14:37:19 -070026#include <system_error>
Aditya Kurdunkared0af212025-06-11 04:38:52 +053027#include <unordered_map>
28#include <utility>
Harshit Aghera560e6af2025-04-21 20:04:56 +053029
30namespace mctp
31{
Marc Olberdingd0125c92025-10-08 14:37:19 -070032class MctpRequester
Harshit Aghera560e6af2025-04-21 20:04:56 +053033{
34 public:
Marc Olberdingd0125c92025-10-08 14:37:19 -070035 MctpRequester() = delete;
Harshit Aghera560e6af2025-04-21 20:04:56 +053036
Marc Olberdingd0125c92025-10-08 14:37:19 -070037 MctpRequester(const MctpRequester&) = delete;
Harshit Aghera560e6af2025-04-21 20:04:56 +053038
Marc Olberdingd0125c92025-10-08 14:37:19 -070039 MctpRequester(MctpRequester&&) = delete;
Harshit Aghera560e6af2025-04-21 20:04:56 +053040
Marc Olberdingd0125c92025-10-08 14:37:19 -070041 MctpRequester& operator=(const MctpRequester&) = delete;
Harshit Aghera560e6af2025-04-21 20:04:56 +053042
Marc Olberdingd0125c92025-10-08 14:37:19 -070043 MctpRequester& operator=(MctpRequester&&) = delete;
Harshit Aghera560e6af2025-04-21 20:04:56 +053044
Marc Olberdingd0125c92025-10-08 14:37:19 -070045 explicit MctpRequester(boost::asio::io_context& ctx);
Harshit Aghera560e6af2025-04-21 20:04:56 +053046
47 void sendRecvMsg(uint8_t eid, std::span<const uint8_t> reqMsg,
Marc Olberdingd0125c92025-10-08 14:37:19 -070048 std::move_only_function<void(const std::error_code&,
49 std::span<const uint8_t>)>
50 callback);
Harshit Aghera560e6af2025-04-21 20:04:56 +053051
52 private:
Marc Olberdingd0125c92025-10-08 14:37:19 -070053 using cb_t = std::move_only_function<void(const std::error_code&,
54 std::span<const uint8_t>)>;
Harshit Aghera560e6af2025-04-21 20:04:56 +053055
56 static constexpr size_t maxMessageSize = 65536 + 256;
Harshit Aghera560e6af2025-04-21 20:04:56 +053057 static constexpr uint8_t msgType = ocp::accelerator_management::messageType;
Aditya Kurdunkared0af212025-06-11 04:38:52 +053058
Aditya Kurdunkared0af212025-06-11 04:38:52 +053059 struct RequestContext
60 {
Marc Olberdingd0125c92025-10-08 14:37:19 -070061 std::vector<uint8_t> reqMsg;
62 cb_t callback;
Aditya Kurdunkared0af212025-06-11 04:38:52 +053063
64 RequestContext(const RequestContext&) = delete;
65 RequestContext& operator=(const RequestContext&) = delete;
66
67 RequestContext(RequestContext&&) = default;
68 RequestContext& operator=(RequestContext&&) = default;
69 ~RequestContext() = default;
70
Marc Olberdingd0125c92025-10-08 14:37:19 -070071 explicit RequestContext(std::span<const uint8_t> req, cb_t&& cb) :
72 reqMsg(req.begin(), req.end()), callback(std::move(cb))
Aditya Kurdunkared0af212025-06-11 04:38:52 +053073 {}
74 };
75
Marc Olberdingd0125c92025-10-08 14:37:19 -070076 struct EidContext
77 {
78 boost::asio::steady_timer timer;
79 uint8_t iid{};
80 boost::container::devector<RequestContext> queue;
81 EidContext(boost::asio::io_context& io) : timer{io}, iid{0xFF} {}
82 EidContext(EidContext&&) noexcept = default;
83 EidContext& operator=(EidContext&&) noexcept = default;
84 EidContext& operator=(const EidContext&) = delete;
85 EidContext(const EidContext&) = delete;
86 ~EidContext() = default;
87 };
88
89 std::optional<uint8_t> getNextIid(uint8_t eid);
90 void startReceive();
91 void processRecvMsg(const boost::system::error_code& ec, size_t length);
92 void handleSendMsgCompletion(uint8_t eid,
93 const boost::system::error_code& ec,
94 size_t length);
95
96 void handleResult(uint8_t eid, const std::error_code& ec,
97 std::span<const uint8_t> buffer);
Aditya Kurdunkared0af212025-06-11 04:38:52 +053098 void processQueue(uint8_t eid);
99
Marc Olberdingd0125c92025-10-08 14:37:19 -0700100 boost::asio::io_context& io;
101 boost::asio::generic::datagram_protocol::endpoint sendEndPoint;
102
103 boost::asio::generic::datagram_protocol::socket mctpSocket;
104 std::array<uint8_t, maxMessageSize> buffer{};
105 MctpAsioEndpoint recvEndPoint;
106 std::unordered_map<uint8_t, EidContext> requestContextQueues;
Aditya Kurdunkared0af212025-06-11 04:38:52 +0530107};
108
Harshit Aghera560e6af2025-04-21 20:04:56 +0530109} // namespace mctp