blob: 0fd468353a85e9af8c0c058e9cb0c462362e4595 [file] [log] [blame]
/*
* SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION &
* AFFILIATES. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <MctpAsioEndpoint.hpp>
#include <OcpMctpVdm.hpp>
#include <boost/asio/generic/datagram_protocol.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/circular_buffer.hpp>
#include <boost/container/devector.hpp>
#include <boost/container/flat_map.hpp>
#include <boost/container/small_vector.hpp>
#include <cstddef>
#include <cstdint>
#include <expected>
#include <functional>
#include <iostream>
#include <memory>
#include <queue>
#include <span>
#include <system_error>
#include <unordered_map>
#include <utility>
namespace mctp
{
class MctpRequester
{
public:
MctpRequester() = delete;
MctpRequester(const MctpRequester&) = delete;
MctpRequester(MctpRequester&&) = delete;
MctpRequester& operator=(const MctpRequester&) = delete;
MctpRequester& operator=(MctpRequester&&) = delete;
explicit MctpRequester(boost::asio::io_context& ctx);
void sendRecvMsg(uint8_t eid, std::span<const uint8_t> reqMsg,
std::move_only_function<void(const std::error_code&,
std::span<const uint8_t>)>
callback);
private:
using cb_t = std::move_only_function<void(const std::error_code&,
std::span<const uint8_t>)>;
static constexpr size_t maxMessageSize = 65536 + 256;
static constexpr uint8_t msgType = ocp::accelerator_management::messageType;
struct RequestContext
{
std::vector<uint8_t> reqMsg;
cb_t callback;
RequestContext(const RequestContext&) = delete;
RequestContext& operator=(const RequestContext&) = delete;
RequestContext(RequestContext&&) = default;
RequestContext& operator=(RequestContext&&) = default;
~RequestContext() = default;
explicit RequestContext(std::span<const uint8_t> req, cb_t&& cb) :
reqMsg(req.begin(), req.end()), callback(std::move(cb))
{}
};
struct EidContext
{
boost::asio::steady_timer timer;
uint8_t iid{};
boost::container::devector<RequestContext> queue;
EidContext(boost::asio::io_context& io) : timer{io}, iid{0xFF} {}
EidContext(EidContext&&) noexcept = default;
EidContext& operator=(EidContext&&) noexcept = default;
EidContext& operator=(const EidContext&) = delete;
EidContext(const EidContext&) = delete;
~EidContext() = default;
};
std::optional<uint8_t> getNextIid(uint8_t eid);
void startReceive();
void processRecvMsg(const boost::system::error_code& ec, size_t length);
void handleSendMsgCompletion(uint8_t eid,
const boost::system::error_code& ec,
size_t length);
void handleResult(uint8_t eid, const std::error_code& ec,
std::span<const uint8_t> buffer);
void processQueue(uint8_t eid);
boost::asio::io_context& io;
boost::asio::generic::datagram_protocol::endpoint sendEndPoint;
boost::asio::generic::datagram_protocol::socket mctpSocket;
std::array<uint8_t, maxMessageSize> buffer{};
MctpAsioEndpoint recvEndPoint;
std::unordered_map<uint8_t, EidContext> requestContextQueues;
};
} // namespace mctp