blob: 9d05ebd8da159488ec6da4e0f572806c404a9d41 [file] [log] [blame]
/*
* SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION &
* AFFILIATES. All rights reserved.
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <OcpMctpVdm.hpp>
#include <boost/asio/generic/datagram_protocol.hpp>
#include <boost/asio/io_context.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/container/devector.hpp>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <memory>
#include <span>
#include <unordered_map>
#include <utility>
namespace mctp
{
class Requester
{
public:
Requester() = delete;
Requester(const Requester&) = delete;
Requester(Requester&&) = delete;
Requester& operator=(const Requester&) = delete;
Requester& operator=(Requester&&) = delete;
explicit Requester(boost::asio::io_context& ctx);
void sendRecvMsg(uint8_t eid, std::span<const uint8_t> reqMsg,
std::span<uint8_t> respMsg,
std::move_only_function<void(int)> callback);
private:
void processRecvMsg(std::span<const uint8_t> reqMsg,
std::span<uint8_t> respMsg,
const boost::system::error_code& ec, size_t length);
void handleSendMsgCompletion(uint8_t eid, std::span<const uint8_t> reqMsg,
std::span<uint8_t> respMsg,
const boost::system::error_code& ec,
size_t length);
boost::asio::generic::datagram_protocol::socket mctpSocket;
static constexpr size_t maxMessageSize = 65536 + 256;
boost::asio::generic::datagram_protocol::endpoint sendEndPoint;
boost::asio::generic::datagram_protocol::endpoint recvEndPoint;
boost::asio::steady_timer expiryTimer;
std::unordered_map<uint8_t, std::move_only_function<void(int)>>
completionCallbacks;
static constexpr uint8_t msgType = ocp::accelerator_management::messageType;
};
class QueuingRequester
{
public:
QueuingRequester() = delete;
QueuingRequester(const QueuingRequester&) = delete;
QueuingRequester(QueuingRequester&&) = delete;
QueuingRequester& operator=(const QueuingRequester&) = delete;
QueuingRequester& operator=(QueuingRequester&&) = delete;
explicit QueuingRequester(boost::asio::io_context& ctx) : requester(ctx) {}
void sendRecvMsg(uint8_t eid, std::span<const uint8_t> reqMsg,
std::span<uint8_t> respMsg,
std::move_only_function<void(int)> callback);
private:
struct RequestContext
{
std::span<const uint8_t> reqMsg;
std::span<uint8_t> respMsg;
std::move_only_function<void(int)> 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,
std::span<uint8_t> resp,
std::move_only_function<void(int)>&& cb) :
reqMsg(req), respMsg(resp), callback(std::move(cb))
{}
};
void handleResult(uint8_t eid, int result);
void processQueue(uint8_t eid);
Requester requester;
std::unordered_map<
uint8_t, boost::container::devector<std::unique_ptr<RequestContext>>>
requestContextQueues;
};
using MctpRequester = QueuingRequester;
} // namespace mctp