From e20c2450ce85f211d3ba57841b18a56abc346bad Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Tue, 9 Feb 2021 12:36:37 -0800 Subject: [PATCH] htc: declare and begin impl of HtclowManagerImpl interface --- .../htclow/htclow_channel_types.hpp | 2 + .../htclow/htclow_module_types.hpp | 1 + .../htc/server/driver/htc_htclow_driver.cpp | 6 +- .../htclow/driver/htclow_driver_manager.cpp | 5 + .../htclow/driver/htclow_driver_manager.hpp | 2 + .../htclow/htclow_default_channel_config.hpp | 28 +++++ .../source/htclow/htclow_manager.cpp | 96 ++++++++++++++++ .../source/htclow/htclow_manager.hpp | 39 +++++++ .../source/htclow/htclow_manager_impl.cpp | 108 ++++++++++++++++++ .../source/htclow/htclow_manager_impl.hpp | 38 ++++++ .../source/htclow/mux/htclow_mux.cpp | 23 ++++ .../source/htclow/mux/htclow_mux.hpp | 4 + .../htclow/mux/htclow_mux_channel_impl.cpp | 11 ++ .../htclow/mux/htclow_mux_channel_impl.hpp | 2 +- .../mux/htclow_mux_channel_impl_map.cpp | 24 ++++ .../mux/htclow_mux_channel_impl_map.hpp | 2 + .../htclow/mux/htclow_mux_task_manager.cpp | 8 ++ .../htclow/mux/htclow_mux_task_manager.hpp | 2 + .../vapours/results/htclow_results.hpp | 11 +- libraries/libvapours/include/vapours/util.hpp | 2 +- 20 files changed, 405 insertions(+), 9 deletions(-) create mode 100644 libraries/libstratosphere/source/htclow/htclow_default_channel_config.hpp diff --git a/libraries/libstratosphere/include/stratosphere/htclow/htclow_channel_types.hpp b/libraries/libstratosphere/include/stratosphere/htclow/htclow_channel_types.hpp index 685f78372..51601f9c4 100644 --- a/libraries/libstratosphere/include/stratosphere/htclow/htclow_channel_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/htclow/htclow_channel_types.hpp @@ -36,6 +36,8 @@ namespace ams::htclow { struct ChannelConfig { bool flow_control_enabled; + bool handshake_enabled; + size_t max_packet_size; }; constexpr bool IsStateTransitionAllowed(ChannelState from, ChannelState to) { diff --git a/libraries/libstratosphere/include/stratosphere/htclow/htclow_module_types.hpp b/libraries/libstratosphere/include/stratosphere/htclow/htclow_module_types.hpp index f5a8817ef..178c61dfa 100644 --- a/libraries/libstratosphere/include/stratosphere/htclow/htclow_module_types.hpp +++ b/libraries/libstratosphere/include/stratosphere/htclow/htclow_module_types.hpp @@ -21,6 +21,7 @@ namespace ams::htclow { enum class ModuleId : u8 { Htcfs = 1, + Htcmisc = 3, Htcs = 4, }; diff --git a/libraries/libstratosphere/source/htc/server/driver/htc_htclow_driver.cpp b/libraries/libstratosphere/source/htc/server/driver/htc_htclow_driver.cpp index aed7f9f2b..ecc87a6c9 100644 --- a/libraries/libstratosphere/source/htc/server/driver/htc_htclow_driver.cpp +++ b/libraries/libstratosphere/source/htc/server/driver/htc_htclow_driver.cpp @@ -57,8 +57,8 @@ namespace ams::htc::server::driver { R_TRY(m_manager->Open(GetHtclowChannel(channel, m_module_id))); /* Set the send/receive buffers. */ - m_manager->SetReceiveBuffer(receive_buffer, receive_buffer_size); - m_manager->SetSendBuffer(send_buffer, send_buffer_size); + m_manager->SetReceiveBuffer(GetHtclowChannel(channel, m_module_id), receive_buffer, receive_buffer_size); + m_manager->SetSendBuffer(GetHtclowChannel(channel, m_module_id), send_buffer, send_buffer_size); return ResultSuccess(); } @@ -151,7 +151,7 @@ namespace ams::htc::server::driver { size_t received = 0; do { size_t cur_received; - const Result result = this->ReceiveInternal(std::addressof(cur_received), static_cast(dst) + received, static_cast(src_size) - received, channel, option); + const Result result = this->ReceiveInternal(std::addressof(cur_received), static_cast(dst) + received, static_cast(dst_size) - received, channel, option); if (R_FAILED(result)) { if (htclow::ResultChannelReceiveBufferEmpty::Includes(result)) { diff --git a/libraries/libstratosphere/source/htclow/driver/htclow_driver_manager.cpp b/libraries/libstratosphere/source/htclow/driver/htclow_driver_manager.cpp index 40268bf2c..1b79aeb93 100644 --- a/libraries/libstratosphere/source/htclow/driver/htclow_driver_manager.cpp +++ b/libraries/libstratosphere/source/htclow/driver/htclow_driver_manager.cpp @@ -59,4 +59,9 @@ namespace ams::htclow::driver { return m_open_driver; } + void DriverManager::SetDebugDriver(IDriver *driver) { + m_debug_driver = driver; + m_driver_type = impl::DriverType::Debug; + } + } diff --git a/libraries/libstratosphere/source/htclow/driver/htclow_driver_manager.hpp b/libraries/libstratosphere/source/htclow/driver/htclow_driver_manager.hpp index 6a2e80aff..c1ae457fb 100644 --- a/libraries/libstratosphere/source/htclow/driver/htclow_driver_manager.hpp +++ b/libraries/libstratosphere/source/htclow/driver/htclow_driver_manager.hpp @@ -35,6 +35,8 @@ namespace ams::htclow::driver { Result OpenDriver(impl::DriverType driver_type); IDriver *GetCurrentDriver(); + + void SetDebugDriver(IDriver *driver); }; } diff --git a/libraries/libstratosphere/source/htclow/htclow_default_channel_config.hpp b/libraries/libstratosphere/source/htclow/htclow_default_channel_config.hpp new file mode 100644 index 000000000..a442ef2ed --- /dev/null +++ b/libraries/libstratosphere/source/htclow/htclow_default_channel_config.hpp @@ -0,0 +1,28 @@ +/* + * 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 . + */ +#pragma once +#include +#include "htclow_packet.hpp" + +namespace ams::htclow { + + constexpr inline const ChannelConfig DefaultChannelConfig = { + .flow_control_enabled = true, + .handshake_enabled = true, + .max_packet_size = 0xE000 + sizeof(PacketHeader), + }; + +} diff --git a/libraries/libstratosphere/source/htclow/htclow_manager.cpp b/libraries/libstratosphere/source/htclow/htclow_manager.cpp index 44c670d29..398de260a 100644 --- a/libraries/libstratosphere/source/htclow/htclow_manager.cpp +++ b/libraries/libstratosphere/source/htclow/htclow_manager.cpp @@ -36,8 +36,104 @@ namespace ams::htclow { return m_impl->CloseDriver(); } + Result HtclowManager::Open(impl::ChannelInternalType channel) { + return m_impl->Open(channel); + } + + Result HtclowManager::Close(impl::ChannelInternalType channel) { + return m_impl->Close(channel); + } + + void HtclowManager::Resume() { + return m_impl->Resume(); + } + + void HtclowManager::Suspend() { + return m_impl->Suspend(); + } + + Result HtclowManager::ConnectBegin(u32 *out_task_id, impl::ChannelInternalType channel) { + return m_impl->ConnectBegin(out_task_id, channel); + } + + Result HtclowManager::ConnectEnd(impl::ChannelInternalType channel, u32 task_id) { + return m_impl->ConnectEnd(channel, task_id); + } + void HtclowManager::Disconnect() { return m_impl->Disconnect(); } + Result HtclowManager::FlushBegin(u32 *out_task_id, impl::ChannelInternalType channel) { + return m_impl->FlushBegin(out_task_id, channel); + } + + Result HtclowManager::FlushEnd(u32 task_id) { + return m_impl->FlushEnd(task_id); + } + + ChannelState HtclowManager::GetChannelState(impl::ChannelInternalType channel) { + return m_impl->GetChannelState(channel); + } + + os::EventType *HtclowManager::GetChannelStateEvent(impl::ChannelInternalType channel) { + return m_impl->GetChannelStateEvent(channel); + } + + impl::DriverType HtclowManager::GetDriverType() { + return m_impl->GetDriverType(); + } + + os::EventType *HtclowManager::GetTaskEvent(u32 task_id) { + return m_impl->GetTaskEvent(task_id); + } + + void HtclowManager::NotifyAsleep() { + return m_impl->NotifyAsleep(); + } + + void HtclowManager::NotifyAwake() { + return m_impl->NotifyAwake(); + } + + Result HtclowManager::ReceiveBegin(u32 *out_task_id, impl::ChannelInternalType channel, bool blocking) { + return m_impl->ReceiveBegin(out_task_id, channel, blocking); + } + + Result HtclowManager::ReceiveEnd(size_t *out, void *dst, size_t dst_size, impl::ChannelInternalType channel, u32 task_id) { + return m_impl->ReceiveEnd(out, dst, dst_size, channel, task_id); + } + + Result HtclowManager::SendBegin(u32 *out_task_id, size_t *out, const void *src, size_t src_size, impl::ChannelInternalType channel) { + return m_impl->SendBegin(out_task_id, out, src, src_size, channel); + } + + Result HtclowManager::SendEnd(u32 task_id) { + return m_impl->SendEnd(task_id); + } + + void HtclowManager::SetConfig(impl::ChannelInternalType channel, const ChannelConfig &config) { + return m_impl->SetConfig(channel, config); + } + + void HtclowManager::SetDebugDriver(driver::IDriver *driver) { + return m_impl->SetDebugDriver(driver); + } + + void HtclowManager::SetReceiveBuffer(impl::ChannelInternalType channel, void *buf, size_t buf_size) { + return m_impl->SetReceiveBuffer(channel, buf, buf_size); + } + + void HtclowManager::SetSendBuffer(impl::ChannelInternalType channel, void *buf, size_t buf_size) { + return m_impl->SetSendBuffer(channel, buf, buf_size); + } + + void HtclowManager::SetSendBufferWithData(impl::ChannelInternalType channel, const void *buf, size_t buf_size) { + return m_impl->SetSendBufferWithData(channel, buf, buf_size); + } + + Result HtclowManager::Shutdown(impl::ChannelInternalType channel) { + return m_impl->Shutdown(channel); + } + } diff --git a/libraries/libstratosphere/source/htclow/htclow_manager.hpp b/libraries/libstratosphere/source/htclow/htclow_manager.hpp index 727422a25..1842d2e5c 100644 --- a/libraries/libstratosphere/source/htclow/htclow_manager.hpp +++ b/libraries/libstratosphere/source/htclow/htclow_manager.hpp @@ -15,6 +15,7 @@ */ #pragma once #include +#include "driver/htclow_i_driver.hpp" namespace ams::htclow { @@ -31,7 +32,45 @@ namespace ams::htclow { Result OpenDriver(impl::DriverType driver_type); void CloseDriver(); + Result Open(impl::ChannelInternalType channel); + Result Close(impl::ChannelInternalType channel); + + void Resume(); + void Suspend(); + + Result ConnectBegin(u32 *out_task_id, impl::ChannelInternalType channel); + Result ConnectEnd(impl::ChannelInternalType channel, u32 task_id); + void Disconnect(); + + Result FlushBegin(u32 *out_task_id, impl::ChannelInternalType channel); + Result FlushEnd(u32 task_id); + + ChannelState GetChannelState(impl::ChannelInternalType channel); + os::EventType *GetChannelStateEvent(impl::ChannelInternalType channel); + + impl::DriverType GetDriverType(); + + os::EventType *GetTaskEvent(u32 task_id); + + void NotifyAsleep(); + void NotifyAwake(); + + Result ReceiveBegin(u32 *out_task_id, impl::ChannelInternalType channel, bool blocking); + Result ReceiveEnd(size_t *out, void *dst, size_t dst_size, impl::ChannelInternalType channel, u32 task_id); + + Result SendBegin(u32 *out_task_id, size_t *out, const void *src, size_t src_size, impl::ChannelInternalType channel); + Result SendEnd(u32 task_id); + + void SetConfig(impl::ChannelInternalType channel, const ChannelConfig &config); + + void SetDebugDriver(driver::IDriver *driver); + + void SetReceiveBuffer(impl::ChannelInternalType channel, void *buf, size_t buf_size); + void SetSendBuffer(impl::ChannelInternalType channel, void *buf, size_t buf_size); + void SetSendBufferWithData(impl::ChannelInternalType channel, const void *buf, size_t buf_size); + + Result Shutdown(impl::ChannelInternalType channel); }; } diff --git a/libraries/libstratosphere/source/htclow/htclow_manager_impl.cpp b/libraries/libstratosphere/source/htclow/htclow_manager_impl.cpp index 34e530bd6..97c5b51fa 100644 --- a/libraries/libstratosphere/source/htclow/htclow_manager_impl.cpp +++ b/libraries/libstratosphere/source/htclow/htclow_manager_impl.cpp @@ -56,8 +56,116 @@ namespace ams::htclow { AMS_ABORT("HtclowManagerImpl::CloseDriver"); } + Result HtclowManagerImpl::Open(impl::ChannelInternalType channel) { + return m_mux.Open(channel); + } + + Result HtclowManagerImpl::Close(impl::ChannelInternalType channel) { + /* TODO: Used by HtclowDriver */ + AMS_ABORT("HtclowManagerImpl::Close"); + } + + void HtclowManagerImpl::Resume() { + AMS_ABORT("HtclowManagerImpl::Resume"); + } + + void HtclowManagerImpl::Suspend() { + AMS_ABORT("HtclowManagerImpl::Suspend"); + } + + Result HtclowManagerImpl::ConnectBegin(u32 *out_task_id, impl::ChannelInternalType channel) { + /* TODO: Used by HtclowDriver */ + AMS_ABORT("HtclowManagerImpl::ConnectBegin"); + } + + Result HtclowManagerImpl::ConnectEnd(impl::ChannelInternalType channel, u32 task_id) { + /* TODO: Used by HtclowDriver */ + AMS_ABORT("HtclowManagerImpl::ConnectEnd"); + } + void HtclowManagerImpl::Disconnect() { AMS_ABORT("HtclowManagerImpl::Disconnect"); } + Result HtclowManagerImpl::FlushBegin(u32 *out_task_id, impl::ChannelInternalType channel) { + AMS_ABORT("HtclowManagerImpl::FlushBegin"); + } + + Result HtclowManagerImpl::FlushEnd(u32 task_id) { + AMS_ABORT("HtclowManagerImpl::FlushEnd"); + } + + ChannelState HtclowManagerImpl::GetChannelState(impl::ChannelInternalType channel) { + /* TODO: Used by HtclowDriver */ + AMS_ABORT("HtclowManagerImpl::GetChannelState"); + } + + os::EventType *HtclowManagerImpl::GetChannelStateEvent(impl::ChannelInternalType channel) { + /* TODO: Used by HtclowDriver */ + AMS_ABORT("HtclowManagerImpl::GetChannelStateEvent"); + } + + impl::DriverType HtclowManagerImpl::GetDriverType() { + AMS_ABORT("HtclowManagerImpl::GetDriverType"); + } + + os::EventType *HtclowManagerImpl::GetTaskEvent(u32 task_id) { + return m_mux.GetTaskEvent(task_id); + } + + void HtclowManagerImpl::NotifyAsleep() { + AMS_ABORT("HtclowManagerImpl::NotifyAsleep"); + } + + void HtclowManagerImpl::NotifyAwake() { + AMS_ABORT("HtclowManagerImpl::NotifyAwake"); + } + + Result HtclowManagerImpl::ReceiveBegin(u32 *out_task_id, impl::ChannelInternalType channel, bool blocking) { + /* TODO: Used by HtclowDriver */ + AMS_ABORT("HtclowManagerImpl::ReceiveBegin"); + } + + Result HtclowManagerImpl::ReceiveEnd(size_t *out, void *dst, size_t dst_size, impl::ChannelInternalType channel, u32 task_id) { + /* TODO: Used by HtclowDriver */ + AMS_ABORT("HtclowManagerImpl::ReceiveEnd"); + } + + Result HtclowManagerImpl::SendBegin(u32 *out_task_id, size_t *out, const void *src, size_t src_size, impl::ChannelInternalType channel) { + /* TODO: Used by HtclowDriver */ + AMS_ABORT("HtclowManagerImpl::SendBegin"); + } + + Result HtclowManagerImpl::SendEnd(u32 task_id) { + /* TODO: Used by HtclowDriver */ + AMS_ABORT("HtclowManagerImpl::SendEnd"); + } + + void HtclowManagerImpl::SetConfig(impl::ChannelInternalType channel, const ChannelConfig &config) { + AMS_ABORT("HtclowManagerImpl::SetConfig"); + } + + void HtclowManagerImpl::SetDebugDriver(driver::IDriver *driver) { + m_driver_manager.SetDebugDriver(driver); + } + + void HtclowManagerImpl::SetReceiveBuffer(impl::ChannelInternalType channel, void *buf, size_t buf_size) { + /* TODO: Used by HtclowDriver */ + AMS_ABORT("HtclowManagerImpl::SetReceiveBuffer"); + } + + void HtclowManagerImpl::SetSendBuffer(impl::ChannelInternalType channel, void *buf, size_t buf_size) { + /* TODO: Used by HtclowDriver */ + AMS_ABORT("HtclowManagerImpl::SetSendBuffer"); + } + + void HtclowManagerImpl::SetSendBufferWithData(impl::ChannelInternalType channel, const void *buf, size_t buf_size) { + AMS_ABORT("HtclowManagerImpl::SetSendBufferWithData"); + } + + Result HtclowManagerImpl::Shutdown(impl::ChannelInternalType channel) { + /* TODO: Used by HtclowDriver */ + AMS_ABORT("HtclowManagerImpl::Shutdown"); + } + } diff --git a/libraries/libstratosphere/source/htclow/htclow_manager_impl.hpp b/libraries/libstratosphere/source/htclow/htclow_manager_impl.hpp index 8a6f05d11..59c63aa02 100644 --- a/libraries/libstratosphere/source/htclow/htclow_manager_impl.hpp +++ b/libraries/libstratosphere/source/htclow/htclow_manager_impl.hpp @@ -44,7 +44,45 @@ namespace ams::htclow { Result OpenDriver(impl::DriverType driver_type); void CloseDriver(); + Result Open(impl::ChannelInternalType channel); + Result Close(impl::ChannelInternalType channel); + + void Resume(); + void Suspend(); + + Result ConnectBegin(u32 *out_task_id, impl::ChannelInternalType channel); + Result ConnectEnd(impl::ChannelInternalType channel, u32 task_id); + void Disconnect(); + + Result FlushBegin(u32 *out_task_id, impl::ChannelInternalType channel); + Result FlushEnd(u32 task_id); + + ChannelState GetChannelState(impl::ChannelInternalType channel); + os::EventType *GetChannelStateEvent(impl::ChannelInternalType channel); + + impl::DriverType GetDriverType(); + + os::EventType *GetTaskEvent(u32 task_id); + + void NotifyAsleep(); + void NotifyAwake(); + + Result ReceiveBegin(u32 *out_task_id, impl::ChannelInternalType channel, bool blocking); + Result ReceiveEnd(size_t *out, void *dst, size_t dst_size, impl::ChannelInternalType channel, u32 task_id); + + Result SendBegin(u32 *out_task_id, size_t *out, const void *src, size_t src_size, impl::ChannelInternalType channel); + Result SendEnd(u32 task_id); + + void SetConfig(impl::ChannelInternalType channel, const ChannelConfig &config); + + void SetDebugDriver(driver::IDriver *driver); + + void SetReceiveBuffer(impl::ChannelInternalType channel, void *buf, size_t buf_size); + void SetSendBuffer(impl::ChannelInternalType channel, void *buf, size_t buf_size); + void SetSendBufferWithData(impl::ChannelInternalType channel, const void *buf, size_t buf_size); + + Result Shutdown(impl::ChannelInternalType channel); }; } diff --git a/libraries/libstratosphere/source/htclow/mux/htclow_mux.cpp b/libraries/libstratosphere/source/htclow/mux/htclow_mux.cpp index 69e6288ba..a9e907511 100644 --- a/libraries/libstratosphere/source/htclow/mux/htclow_mux.cpp +++ b/libraries/libstratosphere/source/htclow/mux/htclow_mux.cpp @@ -166,4 +166,27 @@ namespace ams::htclow::mux { } } + Result Mux::Open(impl::ChannelInternalType channel) { + /* Lock ourselves. */ + std::scoped_lock lk(m_mutex); + + /* Check that the channel doesn't already exist. */ + R_UNLESS(!m_channel_impl_map.Exists(channel), htclow::ResultChannelAlreadyExist()); + + /* Add the channel. */ + R_TRY(m_channel_impl_map.AddChannel(channel)); + + /* Set the channel version. */ + m_channel_impl_map.GetChannelImpl(channel).SetVersion(m_version); + + return ResultSuccess(); + } + + os::EventType *Mux::GetTaskEvent(u32 task_id) { + /* Lock ourselves. */ + std::scoped_lock lk(m_mutex); + + return m_task_manager.GetTaskEvent(task_id); + } + } diff --git a/libraries/libstratosphere/source/htclow/mux/htclow_mux.hpp b/libraries/libstratosphere/source/htclow/mux/htclow_mux.hpp index 48e1a3a8e..9829310bb 100644 --- a/libraries/libstratosphere/source/htclow/mux/htclow_mux.hpp +++ b/libraries/libstratosphere/source/htclow/mux/htclow_mux.hpp @@ -53,6 +53,10 @@ namespace ams::htclow::mux { void UpdateChannelState(); void UpdateMuxState(); + public: + Result Open(impl::ChannelInternalType channel); + + os::EventType *GetTaskEvent(u32 task_id); private: Result CheckChannelExist(impl::ChannelInternalType channel); diff --git a/libraries/libstratosphere/source/htclow/mux/htclow_mux_channel_impl.cpp b/libraries/libstratosphere/source/htclow/mux/htclow_mux_channel_impl.cpp index b475f4cf2..0c7c7390c 100644 --- a/libraries/libstratosphere/source/htclow/mux/htclow_mux_channel_impl.cpp +++ b/libraries/libstratosphere/source/htclow/mux/htclow_mux_channel_impl.cpp @@ -16,9 +16,20 @@ #include #include "htclow_mux_channel_impl.hpp" #include "../ctrl/htclow_ctrl_state_machine.hpp" +#include "../htclow_default_channel_config.hpp" namespace ams::htclow::mux { + ChannelImpl::ChannelImpl(impl::ChannelInternalType channel, PacketFactory *pf, ctrl::HtcctrlStateMachine *sm, TaskManager *tm, os::Event *ev) + : m_channel(channel), m_packet_factory(pf), m_state_machine(sm), m_task_manager(tm), m_event(ev), + m_send_buffer(m_channel, pf), m_receive_buffer(), m_version(ProtocolVersion), m_config(DefaultChannelConfig), + m_offset(0), m_total_send_size(0), m_next_max_data(0), m_cur_max_data(0), m_share(), + m_state_change_event(os::EventClearMode_ManualClear), m_state(ChannelState_Unconnectable) + + { + this->UpdateState(); + } + void ChannelImpl::SetVersion(s16 version) { /* Sanity check the version. */ AMS_ASSERT(version <= ProtocolVersion); diff --git a/libraries/libstratosphere/source/htclow/mux/htclow_mux_channel_impl.hpp b/libraries/libstratosphere/source/htclow/mux/htclow_mux_channel_impl.hpp index 5b7ba3485..c167343ea 100644 --- a/libraries/libstratosphere/source/htclow/mux/htclow_mux_channel_impl.hpp +++ b/libraries/libstratosphere/source/htclow/mux/htclow_mux_channel_impl.hpp @@ -43,10 +43,10 @@ namespace ams::htclow::mux { RingBuffer m_receive_buffer; s16 m_version; ChannelConfig m_config; + u64 m_offset; u64 m_total_send_size; u64 m_next_max_data; u64 m_cur_max_data; - u64 m_offset; std::optional m_share; os::Event m_state_change_event; ChannelState m_state; diff --git a/libraries/libstratosphere/source/htclow/mux/htclow_mux_channel_impl_map.cpp b/libraries/libstratosphere/source/htclow/mux/htclow_mux_channel_impl_map.cpp index cd3ccf955..9ed955bd6 100644 --- a/libraries/libstratosphere/source/htclow/mux/htclow_mux_channel_impl_map.cpp +++ b/libraries/libstratosphere/source/htclow/mux/htclow_mux_channel_impl_map.cpp @@ -43,4 +43,28 @@ namespace ams::htclow::mux { return this->GetChannelImpl(it->second); } + Result ChannelImplMap::AddChannel(impl::ChannelInternalType channel) { + /* Find a free storage. */ + int idx; + for (idx = 0; idx < MaxChannelCount; ++idx) { + if (!m_storage_valid[idx]) { + break; + } + } + + /* Validate that the storage is free. */ + R_UNLESS(idx < MaxChannelCount, htclow::ResultOutOfResource()); + + /* Create the channel impl. */ + std::construct_at(GetPointer(m_channel_storage[idx]), channel, m_packet_factory, m_state_machine, m_task_manager, m_event); + + /* Mark the storage valid. */ + m_storage_valid[idx] = true; + + /* Insert into our map. */ + m_map.insert(std::pair{channel, idx}); + + return ResultSuccess(); + } + } diff --git a/libraries/libstratosphere/source/htclow/mux/htclow_mux_channel_impl_map.hpp b/libraries/libstratosphere/source/htclow/mux/htclow_mux_channel_impl_map.hpp index 623c0a07d..a949b8261 100644 --- a/libraries/libstratosphere/source/htclow/mux/htclow_mux_channel_impl_map.hpp +++ b/libraries/libstratosphere/source/htclow/mux/htclow_mux_channel_impl_map.hpp @@ -46,6 +46,8 @@ namespace ams::htclow::mux { bool Exists(impl::ChannelInternalType channel) const { return m_map.find(channel) != m_map.end(); } + + Result AddChannel(impl::ChannelInternalType channel); private: public: MapType &GetMap() { diff --git a/libraries/libstratosphere/source/htclow/mux/htclow_mux_task_manager.cpp b/libraries/libstratosphere/source/htclow/mux/htclow_mux_task_manager.cpp index c96b0535f..ce5f67576 100644 --- a/libraries/libstratosphere/source/htclow/mux/htclow_mux_task_manager.cpp +++ b/libraries/libstratosphere/source/htclow/mux/htclow_mux_task_manager.cpp @@ -18,6 +18,14 @@ namespace ams::htclow::mux { + os::EventType *TaskManager::GetTaskEvent(u32 task_id) { + /* Check pre-conditions. */ + AMS_ASSERT(0 <= task_id && task_id < MaxTaskCount); + AMS_ASSERT(m_valid[task_id]); + + return std::addressof(m_tasks[task_id].event); + } + void TaskManager::NotifyDisconnect(impl::ChannelInternalType channel) { for (auto i = 0; i < MaxTaskCount; ++i) { if (m_valid[i] && m_tasks[i].channel == channel) { diff --git a/libraries/libstratosphere/source/htclow/mux/htclow_mux_task_manager.hpp b/libraries/libstratosphere/source/htclow/mux/htclow_mux_task_manager.hpp index 5feac0803..bb27d3182 100644 --- a/libraries/libstratosphere/source/htclow/mux/htclow_mux_task_manager.hpp +++ b/libraries/libstratosphere/source/htclow/mux/htclow_mux_task_manager.hpp @@ -51,6 +51,8 @@ namespace ams::htclow::mux { public: TaskManager() : m_valid() { /* ... */ } + os::EventType *GetTaskEvent(u32 task_id); + void NotifyDisconnect(impl::ChannelInternalType channel); void NotifyReceiveData(impl::ChannelInternalType channel, size_t size); void NotifySendReady(); diff --git a/libraries/libvapours/include/vapours/results/htclow_results.hpp b/libraries/libvapours/include/vapours/results/htclow_results.hpp index 60e719b79..ef8976ff8 100644 --- a/libraries/libvapours/include/vapours/results/htclow_results.hpp +++ b/libraries/libvapours/include/vapours/results/htclow_results.hpp @@ -20,10 +20,13 @@ namespace ams::htclow { R_DEFINE_NAMESPACE_RESULT_MODULE(29); - R_DEFINE_ERROR_RESULT(ConnectionFailure, 1); - R_DEFINE_ERROR_RESULT(UnknownDriverType, 3); - R_DEFINE_ERROR_RESULT(NonBlockingReceiveFailed, 5); - R_DEFINE_ERROR_RESULT(ChannelNotExist, 10); + R_DEFINE_ERROR_RESULT(ConnectionFailure, 1); + R_DEFINE_ERROR_RESULT(UnknownDriverType, 3); + R_DEFINE_ERROR_RESULT(NonBlockingReceiveFailed, 5); + R_DEFINE_ERROR_RESULT(ChannelAlreadyExist, 9); + R_DEFINE_ERROR_RESULT(ChannelNotExist, 10); + + R_DEFINE_ERROR_RESULT(OutOfResource, 151); R_DEFINE_ERROR_RESULT(InvalidChannelState, 200); R_DEFINE_ERROR_RESULT(InvalidChannelStateDisconnected, 201); diff --git a/libraries/libvapours/include/vapours/util.hpp b/libraries/libvapours/include/vapours/util.hpp index 01cbeb5c5..a7cce0a9a 100644 --- a/libraries/libvapours/include/vapours/util.hpp +++ b/libraries/libvapours/include/vapours/util.hpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -39,7 +40,6 @@ #include #include #include -#include #include #include #include