From ec643789aba7386851cb26080d6f75ec8f3a8912 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 19 Feb 2021 01:56:04 -0800 Subject: [PATCH] htcs: implement data channel manager --- .../impl/rpc/htcs_data_channel_manager.cpp | 98 +++++++++++++++++++ .../impl/rpc/htcs_data_channel_manager.hpp | 2 +- 2 files changed, 99 insertions(+), 1 deletion(-) create mode 100644 libraries/libstratosphere/source/htcs/impl/rpc/htcs_data_channel_manager.cpp diff --git a/libraries/libstratosphere/source/htcs/impl/rpc/htcs_data_channel_manager.cpp b/libraries/libstratosphere/source/htcs/impl/rpc/htcs_data_channel_manager.cpp new file mode 100644 index 000000000..22d3f987f --- /dev/null +++ b/libraries/libstratosphere/source/htcs/impl/rpc/htcs_data_channel_manager.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2018-2020 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include +#include "htcs_rpc_tasks.hpp" +#include "htcs_data_channel_manager.hpp" +#include "../../../htclow/htclow_channel.hpp" + +namespace ams::htcs::impl::rpc { + + Result DataChannelManager::Receive(void *buffer, s64 buffer_size, u32 task_id) { + /* Check that the buffer size is allowable. */ + R_UNLESS(util::IsIntValueRepresentable(buffer_size), htcs::ResultInvalidSize()); + + /* Create an htclow channel. */ + htclow::Channel channel(m_htclow_manager); + + /* Open the channel. */ + R_ABORT_UNLESS(channel.Open(std::addressof(m_module), GetReceiveDataChannelId(task_id))); + + /* Ensure that we close the channel, when we're done. */ + ON_SCOPE_EXIT { channel.Close(); }; + + /* Set the channel config. */ + constexpr htclow::ChannelConfig BulkReceiveConfig = { + .flow_control_enabled = false, + .handshake_enabled = false, + .max_packet_size = 0x3E000, + }; + channel.SetConfig(BulkReceiveConfig); + + /* Set the receive buffer. */ + channel.SetReceiveBuffer(buffer, buffer_size); + + /* Connect the channel. */ + R_TRY(channel.Connect()); + + /* Ensure that we clean up when we're done. */ + ON_SCOPE_EXIT { channel.Shutdown(); }; + + /* Notify the receive task. */ + R_TRY(m_rpc_client->Notify(task_id)); + + /* Wait to receive the data. */ + R_TRY(channel.WaitReceive(buffer_size)); + + return ResultSuccess(); + } + + Result DataChannelManager::Send(const void *buffer, s64 buffer_size, u32 task_id) { + /* Check that the buffer size is allowable. */ + R_UNLESS(util::IsIntValueRepresentable(buffer_size), htcs::ResultInvalidSize()); + + /* Create an htclow channel. */ + htclow::Channel channel(m_htclow_manager); + + /* Open the channel. */ + R_ABORT_UNLESS(channel.Open(std::addressof(m_module), GetSendDataChannelId(task_id))); + + /* Ensure that we close the channel, when we're done. */ + ON_SCOPE_EXIT { channel.Close(); }; + + /* Set the channel config. */ + constexpr htclow::ChannelConfig BulkSendConfig = { + .flow_control_enabled = false, + .handshake_enabled = false, + .max_packet_size = 0x3E000, + }; + channel.SetConfig(BulkSendConfig); + + /* Set the send buffer. */ + channel.SetSendBufferWithData(buffer, buffer_size); + + /* Connect the channel. */ + R_TRY(channel.Connect()); + + /* Ensure that we clean up when we're done. */ + ON_SCOPE_EXIT { channel.Shutdown(); }; + + /* Wait to send the data. */ + R_TRY(channel.Flush()); + + return ResultSuccess(); + } + +} diff --git a/libraries/libstratosphere/source/htcs/impl/rpc/htcs_data_channel_manager.hpp b/libraries/libstratosphere/source/htcs/impl/rpc/htcs_data_channel_manager.hpp index aaac64d48..af4980efb 100644 --- a/libraries/libstratosphere/source/htcs/impl/rpc/htcs_data_channel_manager.hpp +++ b/libraries/libstratosphere/source/htcs/impl/rpc/htcs_data_channel_manager.hpp @@ -28,8 +28,8 @@ namespace ams::htcs::impl::rpc { public: DataChannelManager(htc::server::rpc::RpcClient *client, htclow::HtclowManager *htclow_manager) : m_rpc_client(client), m_htclow_manager(htclow_manager), m_module(htclow::ModuleId::Htcs) { /* ... */ } public: - Result Send(const void *buffer, s64 buffer_size, u32 task_id); Result Receive(void *buffer, s64 buffer_size, u32 task_id); + Result Send(const void *buffer, s64 buffer_size, u32 task_id); }; }