From cf99f54a34654e575de377e993a1e607164835d8 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Sun, 7 Feb 2021 23:13:04 -0800 Subject: [PATCH] htc: skeleton much of the type hierarchy for htclow manager --- .../include/stratosphere/htclow.hpp | 1 + .../htclow/htclow_channel_types.hpp | 30 +++++++++ .../htclow/htclow_module_types.hpp | 31 ++++++++++ .../htclow/impl/htclow_internal_types.hpp | 61 +++++++++++++++++++ .../source/htclow/ctrl/htclow_ctrl_packet.hpp | 25 ++++++++ .../ctrl/htclow_ctrl_packet_factory.hpp | 40 ++++++++++++ .../htclow/ctrl/htclow_ctrl_send_buffer.hpp | 34 +++++++++++ .../htclow/ctrl/htclow_ctrl_service.hpp | 58 ++++++++++++++++++ .../ctrl/htclow_ctrl_settings_holder.hpp | 31 ++++++++++ .../source/htclow/ctrl/htclow_ctrl_state.hpp | 25 ++++++++ .../htclow/ctrl/htclow_ctrl_state_machine.hpp | 44 +++++++++++++ .../htclow/driver/htclow_driver_manager.hpp | 34 +++++++++++ .../source/htclow/driver/htclow_i_driver.hpp | 34 +++++++++++ .../source/htclow/htclow_listener.hpp | 39 ++++++++++++ .../source/htclow/htclow_manager.cpp | 43 +++++++++++++ .../source/htclow/htclow_manager.hpp | 37 +++++++++++ .../source/htclow/htclow_manager_holder.cpp | 31 +++++----- .../source/htclow/htclow_manager_impl.cpp | 40 ++++++++++++ .../source/htclow/htclow_manager_impl.hpp | 50 +++++++++++++++ .../source/htclow/htclow_packet.hpp | 25 ++++++++ .../source/htclow/htclow_packet_factory.hpp | 28 +++++++++ .../source/htclow/htclow_worker.hpp | 42 +++++++++++++ .../source/htclow/mux/htclow_mux.hpp | 39 ++++++++++++ .../mux/htclow_mux_channel_impl_map.hpp | 56 +++++++++++++++++ .../mux/htclow_mux_global_send_buffer.hpp | 38 ++++++++++++ .../htclow/mux/htclow_mux_task_manager.hpp | 40 ++++++++++++ 26 files changed, 942 insertions(+), 14 deletions(-) create mode 100644 libraries/libstratosphere/include/stratosphere/htclow/htclow_channel_types.hpp create mode 100644 libraries/libstratosphere/include/stratosphere/htclow/htclow_module_types.hpp create mode 100644 libraries/libstratosphere/include/stratosphere/htclow/impl/htclow_internal_types.hpp create mode 100644 libraries/libstratosphere/source/htclow/ctrl/htclow_ctrl_packet.hpp create mode 100644 libraries/libstratosphere/source/htclow/ctrl/htclow_ctrl_packet_factory.hpp create mode 100644 libraries/libstratosphere/source/htclow/ctrl/htclow_ctrl_send_buffer.hpp create mode 100644 libraries/libstratosphere/source/htclow/ctrl/htclow_ctrl_service.hpp create mode 100644 libraries/libstratosphere/source/htclow/ctrl/htclow_ctrl_settings_holder.hpp create mode 100644 libraries/libstratosphere/source/htclow/ctrl/htclow_ctrl_state.hpp create mode 100644 libraries/libstratosphere/source/htclow/ctrl/htclow_ctrl_state_machine.hpp create mode 100644 libraries/libstratosphere/source/htclow/driver/htclow_driver_manager.hpp create mode 100644 libraries/libstratosphere/source/htclow/driver/htclow_i_driver.hpp create mode 100644 libraries/libstratosphere/source/htclow/htclow_listener.hpp create mode 100644 libraries/libstratosphere/source/htclow/htclow_manager.cpp create mode 100644 libraries/libstratosphere/source/htclow/htclow_manager.hpp create mode 100644 libraries/libstratosphere/source/htclow/htclow_manager_impl.cpp create mode 100644 libraries/libstratosphere/source/htclow/htclow_manager_impl.hpp create mode 100644 libraries/libstratosphere/source/htclow/htclow_packet.hpp create mode 100644 libraries/libstratosphere/source/htclow/htclow_packet_factory.hpp create mode 100644 libraries/libstratosphere/source/htclow/htclow_worker.hpp create mode 100644 libraries/libstratosphere/source/htclow/mux/htclow_mux.hpp create mode 100644 libraries/libstratosphere/source/htclow/mux/htclow_mux_channel_impl_map.hpp create mode 100644 libraries/libstratosphere/source/htclow/mux/htclow_mux_global_send_buffer.hpp create mode 100644 libraries/libstratosphere/source/htclow/mux/htclow_mux_task_manager.hpp diff --git a/libraries/libstratosphere/include/stratosphere/htclow.hpp b/libraries/libstratosphere/include/stratosphere/htclow.hpp index 4d21e65f7..07be9c057 100644 --- a/libraries/libstratosphere/include/stratosphere/htclow.hpp +++ b/libraries/libstratosphere/include/stratosphere/htclow.hpp @@ -15,4 +15,5 @@ */ #pragma once #include +#include #include diff --git a/libraries/libstratosphere/include/stratosphere/htclow/htclow_channel_types.hpp b/libraries/libstratosphere/include/stratosphere/htclow/htclow_channel_types.hpp new file mode 100644 index 000000000..c72487fdb --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/htclow/htclow_channel_types.hpp @@ -0,0 +1,30 @@ +/* + * 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 + +namespace ams::htclow { + + using ChannelId = u16; + + struct ChannelType { + bool _is_initialized; + ModuleId _module_id; + ChannelId _channel_id; + }; + +} diff --git a/libraries/libstratosphere/include/stratosphere/htclow/htclow_module_types.hpp b/libraries/libstratosphere/include/stratosphere/htclow/htclow_module_types.hpp new file mode 100644 index 000000000..ef8c92e3f --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/htclow/htclow_module_types.hpp @@ -0,0 +1,31 @@ +/* + * 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 + +namespace ams::htclow { + + enum class ModuleId : u8 { + /* ... */ + }; + + struct ModuleType { + bool _is_initialized; + ModuleId _id; + }; + +} diff --git a/libraries/libstratosphere/include/stratosphere/htclow/impl/htclow_internal_types.hpp b/libraries/libstratosphere/include/stratosphere/htclow/impl/htclow_internal_types.hpp new file mode 100644 index 000000000..30bcb5860 --- /dev/null +++ b/libraries/libstratosphere/include/stratosphere/htclow/impl/htclow_internal_types.hpp @@ -0,0 +1,61 @@ +/* + * 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 + +namespace ams::htclow::impl { + + struct ChannelInternalType { + ChannelId channel_id; + s8 reserved; + ModuleId module_id; + }; + static_assert(sizeof(ChannelInternalType) == 4); + + ALWAYS_INLINE ChannelInternalType ConvertChannelType(ChannelType channel) { + return { + .channel_id = channel._channel_id, + .reserved = 0, + .module_id = channel._module_id, + }; + } + + ALWAYS_INLINE bool operator==(const ChannelInternalType &lhs, const ChannelInternalType &rhs) { + return lhs.module_id == rhs.module_id && lhs.reserved == rhs.reserved && lhs.channel_id == rhs.channel_id; + } + + ALWAYS_INLINE bool operator!=(const ChannelInternalType &lhs, const ChannelInternalType &rhs) { + return !(lhs == rhs); + } + + ALWAYS_INLINE bool operator<(const ChannelInternalType &lhs, const ChannelInternalType &rhs) { + return lhs.module_id < rhs.module_id || lhs.reserved < rhs.reserved || lhs.channel_id < rhs.channel_id; + } + + ALWAYS_INLINE bool operator>(const ChannelInternalType &lhs, const ChannelInternalType &rhs) { + return rhs < lhs; + } + + ALWAYS_INLINE bool operator<=(const ChannelInternalType &lhs, const ChannelInternalType &rhs) { + return !(lhs > rhs); + } + + ALWAYS_INLINE bool operator>=(const ChannelInternalType &lhs, const ChannelInternalType &rhs) { + return !(lhs < rhs); + } + +} diff --git a/libraries/libstratosphere/source/htclow/ctrl/htclow_ctrl_packet.hpp b/libraries/libstratosphere/source/htclow/ctrl/htclow_ctrl_packet.hpp new file mode 100644 index 000000000..630b8ede1 --- /dev/null +++ b/libraries/libstratosphere/source/htclow/ctrl/htclow_ctrl_packet.hpp @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2019-2020 Adubbz, 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 + +namespace ams::htclow::ctrl { + + class HtcctrlPacket : public util::IntrusiveListBaseNode { + /* TODO */ + }; + +} diff --git a/libraries/libstratosphere/source/htclow/ctrl/htclow_ctrl_packet_factory.hpp b/libraries/libstratosphere/source/htclow/ctrl/htclow_ctrl_packet_factory.hpp new file mode 100644 index 000000000..d370ee39c --- /dev/null +++ b/libraries/libstratosphere/source/htclow/ctrl/htclow_ctrl_packet_factory.hpp @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2019-2020 Adubbz, 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 + +namespace ams::htclow::ctrl { + + class HtcctrlPacketFactory { + private: + mem::StandardAllocator *m_allocator; + u32 m_seed; + public: + HtcctrlPacketFactory(mem::StandardAllocator *allocator) : m_allocator(allocator) { + /* Get the current time. */ + const u64 time = os::GetSystemTick().GetInt64Value(); + + /* Set the random seed. */ + { + util::TinyMT rng; + rng.Initialize(reinterpret_cast(std::addressof(time)), sizeof(time) / sizeof(u32)); + + m_seed = rng.GenerateRandomU32(); + } + } + }; + +} diff --git a/libraries/libstratosphere/source/htclow/ctrl/htclow_ctrl_send_buffer.hpp b/libraries/libstratosphere/source/htclow/ctrl/htclow_ctrl_send_buffer.hpp new file mode 100644 index 000000000..5bf7ff413 --- /dev/null +++ b/libraries/libstratosphere/source/htclow/ctrl/htclow_ctrl_send_buffer.hpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2019-2020 Adubbz, 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_ctrl_packet.hpp" + +namespace ams::htclow::ctrl { + + class HtcctrlPacketFactory; + + class HtcctrlSendBuffer { + private: + using PacketList = util::IntrusiveListBaseTraits::ListType; + private: + HtcctrlPacketFactory *m_packet_factory; + PacketList m_packet_list; + public: + HtcctrlSendBuffer(HtcctrlPacketFactory *pf) : m_packet_factory(pf), m_packet_list() { /* ... */ } + }; + +} diff --git a/libraries/libstratosphere/source/htclow/ctrl/htclow_ctrl_service.hpp b/libraries/libstratosphere/source/htclow/ctrl/htclow_ctrl_service.hpp new file mode 100644 index 000000000..df0988614 --- /dev/null +++ b/libraries/libstratosphere/source/htclow/ctrl/htclow_ctrl_service.hpp @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2019-2020 Adubbz, 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_ctrl_settings_holder.hpp" +#include "htclow_ctrl_send_buffer.hpp" + +namespace ams::htclow { + + namespace ctrl { + + class HtcctrlPacketFactory; + class HtcctrlStateMachine; + + } + + namespace mux { + + class Mux; + + } + +} + +namespace ams::htclow::ctrl { + + class HtcctrlService { + private: + SettingsHolder m_settings_holder; + u8 m_beacon_response[0x1000]; + u8 m_1100[0x1000]; + HtcctrlPacketFactory *m_packet_factory; + HtcctrlStateMachine *m_state_machine; + mux::Mux *m_mux; + os::EventType m_event; + HtcctrlSendBuffer m_send_buffer; + os::SdkMutex m_mutex; + os::SdkConditionVariable m_condvar; + u8 m_2170[0x1000]; + u16 m_version; + public: + HtcctrlService(HtcctrlPacketFactory *pf, HtcctrlStateMachine *sm, mux::Mux *mux); + }; + +} diff --git a/libraries/libstratosphere/source/htclow/ctrl/htclow_ctrl_settings_holder.hpp b/libraries/libstratosphere/source/htclow/ctrl/htclow_ctrl_settings_holder.hpp new file mode 100644 index 000000000..762f57808 --- /dev/null +++ b/libraries/libstratosphere/source/htclow/ctrl/htclow_ctrl_settings_holder.hpp @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2019-2020 Adubbz, 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 + +namespace ams::htclow::ctrl { + + class SettingsHolder { + private: + char m_hardware_type[0x40]; + char m_target_name[0x40]; + char m_serial_number[0x40]; + char m_firmware_version[0x40]; + public: + SettingsHolder() { /* ... */ } + }; + +} diff --git a/libraries/libstratosphere/source/htclow/ctrl/htclow_ctrl_state.hpp b/libraries/libstratosphere/source/htclow/ctrl/htclow_ctrl_state.hpp new file mode 100644 index 000000000..0df654f61 --- /dev/null +++ b/libraries/libstratosphere/source/htclow/ctrl/htclow_ctrl_state.hpp @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2019-2020 Adubbz, 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 + +namespace ams::htclow::ctrl { + + enum HtcctrlState : u32 { + /* ... */ + }; + +} diff --git a/libraries/libstratosphere/source/htclow/ctrl/htclow_ctrl_state_machine.hpp b/libraries/libstratosphere/source/htclow/ctrl/htclow_ctrl_state_machine.hpp new file mode 100644 index 000000000..a662950ea --- /dev/null +++ b/libraries/libstratosphere/source/htclow/ctrl/htclow_ctrl_state_machine.hpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2019-2020 Adubbz, 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_ctrl_state.hpp" + +namespace ams::htclow::ctrl { + + class HtcctrlStateMachine { + private: + struct ServiceChannelState { + u32 _00; + u32 _04; + }; + + static constexpr int MaxChannelCount = 10; + + using MapType = util::FixedMap; + + static constexpr size_t MapRequiredMemorySize = MapType::GetRequiredMemorySize(MaxChannelCount); + private: + u8 m_map_buffer[MapRequiredMemorySize]; + MapType m_map; + HtcctrlState m_state; + HtcctrlState m_prev_state; + os::SdkMutex m_mutex; + public: + HtcctrlStateMachine(); + }; + +} diff --git a/libraries/libstratosphere/source/htclow/driver/htclow_driver_manager.hpp b/libraries/libstratosphere/source/htclow/driver/htclow_driver_manager.hpp new file mode 100644 index 000000000..caf909ee9 --- /dev/null +++ b/libraries/libstratosphere/source/htclow/driver/htclow_driver_manager.hpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2019-2020 Adubbz, 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_i_driver.hpp" + +namespace ams::htclow::driver { + + class DriverManager { + private: + std::optional m_driver_type{}; + /* TODO: SocketDriver m_socket_driver; */ + /* TODO: UsbDriver m_usb_driver; */ + /* TODO: PlainChannelDriver m_plain_channel_driver; */ + os::SdkMutex m_mutex{}; + IDriver *m_open_driver{}; + public: + DriverManager() = default; + }; + +} diff --git a/libraries/libstratosphere/source/htclow/driver/htclow_i_driver.hpp b/libraries/libstratosphere/source/htclow/driver/htclow_i_driver.hpp new file mode 100644 index 000000000..7ed703854 --- /dev/null +++ b/libraries/libstratosphere/source/htclow/driver/htclow_i_driver.hpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2019-2020 Adubbz, 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 + +namespace ams::htclow::driver { + + class IDriver { + public: + virtual Result Open() = 0; + virtual void Close() = 0; + virtual Result Connect(os::EventType *event) = 0; + virtual void Shutdown() = 0; + virtual Result Send(const void *src, int src_size) = 0; + virtual Result Receive(void *dst, int dst_size) = 0; + virtual void CancelSendReceive() = 0; + virtual void Suspend() = 0; + virtual void Resume() = 0; + }; + +} diff --git a/libraries/libstratosphere/source/htclow/htclow_listener.hpp b/libraries/libstratosphere/source/htclow/htclow_listener.hpp new file mode 100644 index 000000000..0526aea50 --- /dev/null +++ b/libraries/libstratosphere/source/htclow/htclow_listener.hpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2019-2020 Adubbz, 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_worker.hpp" + +namespace ams::htclow { + + class Listener { + private: + u32 m_thread_stack_size; + mem::StandardAllocator *m_allocator; + mux::Mux *m_mux; + ctrl::HtcctrlService *m_service; + Worker *m_worker; + os::EventType m_event; + os::ThreadType m_listen_thread; + void *m_listen_thread_stack; + driver::IDriver *m_driver; + bool m_thread_running; + bool m_cancelled; + public: + Listener(mem::StandardAllocator *allocator, mux::Mux *mux, ctrl::HtcctrlService *ctrl_srv, Worker *worker); + }; + +} diff --git a/libraries/libstratosphere/source/htclow/htclow_manager.cpp b/libraries/libstratosphere/source/htclow/htclow_manager.cpp new file mode 100644 index 000000000..527e4d50d --- /dev/null +++ b/libraries/libstratosphere/source/htclow/htclow_manager.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2019-2020 Adubbz, 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 "htclow_manager.hpp" +#include "htclow_manager_impl.hpp" + +namespace ams::htclow { + + HtclowManager::HtclowManager(mem::StandardAllocator *allocator) : m_allocator(allocator), m_impl(static_cast(allocator->Allocate(sizeof(HtclowManagerImpl), alignof(HtclowManagerImpl)))) { + std::construct_at(m_impl, m_allocator); + } + + HtclowManager::~HtclowManager() { + std::destroy_at(m_impl); + m_allocator->Free(m_impl); + } + + Result HtclowManager::OpenDriver(impl::DriverType driver_type) { + return m_impl->OpenDriver(driver_type); + } + + void HtclowManager::CloseDriver() { + return m_impl->CloseDriver(); + } + + void HtclowManager::Disconnect() { + return m_impl->Disconnect(); + } + +} diff --git a/libraries/libstratosphere/source/htclow/htclow_manager.hpp b/libraries/libstratosphere/source/htclow/htclow_manager.hpp new file mode 100644 index 000000000..c4160426b --- /dev/null +++ b/libraries/libstratosphere/source/htclow/htclow_manager.hpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2019-2020 Adubbz, 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 + +namespace ams::htclow { + + class HtclowManagerImpl; + + class HtclowManager { + private: + mem::StandardAllocator *m_allocator; + HtclowManagerImpl *m_impl; + public: + HtclowManager(mem::StandardAllocator *allocator); + ~HtclowManager(); + public: + Result OpenDriver(impl::DriverType driver_type); + void CloseDriver(); + + void Disconnect(); + }; + +} diff --git a/libraries/libstratosphere/source/htclow/htclow_manager_holder.cpp b/libraries/libstratosphere/source/htclow/htclow_manager_holder.cpp index 07ce8894c..d97854b94 100644 --- a/libraries/libstratosphere/source/htclow/htclow_manager_holder.cpp +++ b/libraries/libstratosphere/source/htclow/htclow_manager_holder.cpp @@ -14,6 +14,7 @@ * along with this program. If not, see . */ #include +#include "htclow_manager.hpp" namespace ams::htclow::HtclowManagerHolder { @@ -39,14 +40,14 @@ namespace ams::htclow::HtclowManagerHolder { /* Initialize the allocator for the manager. */ g_allocator.Initialize(g_heap_buffer, sizeof(g_heap_buffer)); - /* TODO: Allocate the manager. */ - /* g_manager = g_allocator.Allocate(sizeof(HtclowManager), alignof(HtclowManager)); */ + /* Allocate the manager. */ + g_manager = static_cast(g_allocator.Allocate(sizeof(HtclowManager), alignof(HtclowManager))); - /* TODO: Construct the manager. */ - /* std::construct_at(g_manager, std::addressof(g_allocator)); */ + /* Construct the manager. */ + std::construct_at(g_manager, std::addressof(g_allocator)); - /* TODO: Open the driver. */ - /* R_ABORT_UNLESS(g_manager->OpenDriver(g_default_driver_type)); */ + /* Open the driver. */ + R_ABORT_UNLESS(g_manager->OpenDriver(g_default_driver_type)); } AMS_ASSERT(g_holder_reference_count > 0); @@ -58,16 +59,16 @@ namespace ams::htclow::HtclowManagerHolder { AMS_ASSERT(g_holder_reference_count > 0); if ((--g_holder_reference_count) == 0) { - /* TODO: Disconnect. */ - /* g_manager->Disconnect(); */ + /* Disconnect. */ + g_manager->Disconnect(); - /* TODO: Close the driver. */ - /* g_manager->CloseDriver(); */ + /* Close the driver. */ + g_manager->CloseDriver(); - /* TODO: Destroy the manager. */ - /* std::destroy_at(g_manager); */ - /* g_allocator.Free(g_manager); */ - /* g_manager = nullptr; */ + /* Destroy the manager. */ + std::destroy_at(g_manager); + g_allocator.Free(g_manager); + g_manager = nullptr; /* Finalize the allocator. */ g_allocator.Finalize(); @@ -75,6 +76,8 @@ namespace ams::htclow::HtclowManagerHolder { } HtclowManager *GetHtclowManager() { + std::scoped_lock lk(g_holder_mutex); + return g_manager; } diff --git a/libraries/libstratosphere/source/htclow/htclow_manager_impl.cpp b/libraries/libstratosphere/source/htclow/htclow_manager_impl.cpp new file mode 100644 index 000000000..e65f5c538 --- /dev/null +++ b/libraries/libstratosphere/source/htclow/htclow_manager_impl.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2019-2020 Adubbz, 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 "htclow_manager_impl.hpp" + +namespace ams::htclow { + + HtclowManagerImpl::HtclowManagerImpl(mem::StandardAllocator *allocator) + : m_packet_factory(allocator), m_driver_manager(), m_mux(std::addressof(m_packet_factory), std::addressof(m_ctrl_state_machine)), + m_ctrl_packet_factory(allocator), m_ctrl_state_machine(), m_ctrl_service(std::addressof(m_ctrl_packet_factory), std::addressof(m_ctrl_state_machine), std::addressof(m_mux)), + m_worker(allocator, std::addressof(m_mux), std::addressof(m_ctrl_service)), + m_listener(allocator, std::addressof(m_mux), std::addressof(m_ctrl_service), std::addressof(m_worker)) + { + /* ... */ + } + + HtclowManagerImpl::~HtclowManagerImpl() { + /* ... */ + } + + //Result HtclowManagerImpl::OpenDriver(impl::DriverType driver_type); + // + //void HtclowManagerImpl::CloseDriver(); + // + //void HtclowManagerImpl::Disconnect(); + +} diff --git a/libraries/libstratosphere/source/htclow/htclow_manager_impl.hpp b/libraries/libstratosphere/source/htclow/htclow_manager_impl.hpp new file mode 100644 index 000000000..8bdac84b1 --- /dev/null +++ b/libraries/libstratosphere/source/htclow/htclow_manager_impl.hpp @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2019-2020 Adubbz, 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_factory.hpp" +#include "driver/htclow_driver_manager.hpp" +#include "mux/htclow_mux.hpp" +#include "ctrl/htclow_ctrl_packet_factory.hpp" +#include "ctrl/htclow_ctrl_state_machine.hpp" +#include "ctrl/htclow_ctrl_service.hpp" +#include "htclow_worker.hpp" +#include "htclow_listener.hpp" + +namespace ams::htclow { + + class HtclowManagerImpl { + private: + PacketFactory m_packet_factory; + driver::DriverManager m_driver_manager; + mux::Mux m_mux; + ctrl::HtcctrlPacketFactory m_ctrl_packet_factory; + ctrl::HtcctrlStateMachine m_ctrl_state_machine; + ctrl::HtcctrlService m_ctrl_service; + Worker m_worker; + Listener m_listener; + bool m_is_driver_open; + public: + HtclowManagerImpl(mem::StandardAllocator *allocator); + ~HtclowManagerImpl(); + public: + Result OpenDriver(impl::DriverType driver_type); + void CloseDriver(); + + void Disconnect(); + }; + +} diff --git a/libraries/libstratosphere/source/htclow/htclow_packet.hpp b/libraries/libstratosphere/source/htclow/htclow_packet.hpp new file mode 100644 index 000000000..89241c4be --- /dev/null +++ b/libraries/libstratosphere/source/htclow/htclow_packet.hpp @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2019-2020 Adubbz, 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 + +namespace ams::htclow { + + class Packet : public util::IntrusiveListBaseNode { + /* TODO */ + }; + +} diff --git a/libraries/libstratosphere/source/htclow/htclow_packet_factory.hpp b/libraries/libstratosphere/source/htclow/htclow_packet_factory.hpp new file mode 100644 index 000000000..2a4f44093 --- /dev/null +++ b/libraries/libstratosphere/source/htclow/htclow_packet_factory.hpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2019-2020 Adubbz, 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 + +namespace ams::htclow { + + class PacketFactory { + private: + mem::StandardAllocator *m_allocator; + public: + PacketFactory(mem::StandardAllocator *allocator) : m_allocator(allocator) { /* ... */ } + }; + +} diff --git a/libraries/libstratosphere/source/htclow/htclow_worker.hpp b/libraries/libstratosphere/source/htclow/htclow_worker.hpp new file mode 100644 index 000000000..cc7b5fd8e --- /dev/null +++ b/libraries/libstratosphere/source/htclow/htclow_worker.hpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2019-2020 Adubbz, 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 "driver/htclow_i_driver.hpp" +#include "ctrl/htclow_ctrl_service.hpp" +#include "mux/htclow_mux.hpp" + +namespace ams::htclow { + + class Worker { + private: + u32 m_thread_stack_size; + u8 m_04[0x7C024]; /* TODO... not knowing what an almost 128 KB field is is embarassing. */ + mem::StandardAllocator *m_allocator; + mux::Mux *m_mux; + ctrl::HtcctrlService *m_service; + driver::IDriver *m_driver; + os::ThreadType m_receive_thread; + os::ThreadType m_send_thread; + os::EventType m_event; + void *m_receive_thread_stack; + void *m_send_thread_stack; + u8 m_7C400; + public: + Worker(mem::StandardAllocator *allocator, mux::Mux *mux, ctrl::HtcctrlService *ctrl_srv); + }; + +} diff --git a/libraries/libstratosphere/source/htclow/mux/htclow_mux.hpp b/libraries/libstratosphere/source/htclow/mux/htclow_mux.hpp new file mode 100644 index 000000000..03e4c0152 --- /dev/null +++ b/libraries/libstratosphere/source/htclow/mux/htclow_mux.hpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2019-2020 Adubbz, 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_mux_task_manager.hpp" +#include "htclow_mux_channel_impl_map.hpp" +#include "htclow_mux_global_send_buffer.hpp" + +namespace ams::htclow::mux { + + class Mux { + private: + PacketFactory *m_packet_factory; + ctrl::HtcctrlStateMachine *m_state_machine; + TaskManager m_task_manager; + os::EventType m_wake_event; + ChannelImplMap m_channel_impl_map; + GlobalSendBuffer m_global_send_buffer; + os::SdkMutex m_mutex; + bool m_is_sleeping; + u16 m_version; + public: + Mux(PacketFactory *pf, ctrl::HtcctrlStateMachine *sm); + }; + +} 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 new file mode 100644 index 000000000..e5acfdcc2 --- /dev/null +++ b/libraries/libstratosphere/source/htclow/mux/htclow_mux_channel_impl_map.hpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2019-2020 Adubbz, 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_mux_task_manager.hpp" + +namespace ams::htclow { + + class PacketFactory; + + namespace ctrl { + + class HtcctrlStateMachine; + + } + +} + +namespace ams::htclow::mux { + + class ChannelImplMap { + NON_COPYABLE(ChannelImplMap); + NON_MOVEABLE(ChannelImplMap); + public: + static constexpr int MaxChannelCount = 64; + + using MapType = util::FixedMap; + + static constexpr size_t MapRequiredMemorySize = MapType::GetRequiredMemorySize(MaxChannelCount); + private: + PacketFactory *m_packet_factory; + ctrl::HtcctrlStateMachine *m_state_machine; + TaskManager *m_task_manager; + os::EventType *m_event; + u8 m_map_buffer[MapRequiredMemorySize]; + MapType m_map; + u8 m_storage[0x5200]; /* TODO */ + bool m_storage_valid[MaxChannelCount]; + public: + ChannelImplMap(PacketFactory *pf, ctrl::HtcctrlStateMachine *sm, TaskManager *tm, os::EventType *ev); + }; + +} diff --git a/libraries/libstratosphere/source/htclow/mux/htclow_mux_global_send_buffer.hpp b/libraries/libstratosphere/source/htclow/mux/htclow_mux_global_send_buffer.hpp new file mode 100644 index 000000000..c9273c4fd --- /dev/null +++ b/libraries/libstratosphere/source/htclow/mux/htclow_mux_global_send_buffer.hpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2019-2020 Adubbz, 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 { + + class PacketFactory; + +} + +namespace ams::htclow::mux { + + class GlobalSendBuffer { + private: + using PacketList = util::IntrusiveListBaseTraits::ListType; + private: + PacketFactory *m_packet_factory; + PacketList m_packet_list; + public: + GlobalSendBuffer(PacketFactory *pf) : m_packet_factory(pf), m_packet_list() { /* ... */ } + }; + +} diff --git a/libraries/libstratosphere/source/htclow/mux/htclow_mux_task_manager.hpp b/libraries/libstratosphere/source/htclow/mux/htclow_mux_task_manager.hpp new file mode 100644 index 000000000..6e9033c30 --- /dev/null +++ b/libraries/libstratosphere/source/htclow/mux/htclow_mux_task_manager.hpp @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2019-2020 Adubbz, 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 + +namespace ams::htclow::mux { + + constexpr inline int MaxTaskCount = 0x80; + + class TaskManager { + private: + struct Task { + impl::ChannelInternalType channel; + os::EventType event; + u8 _30; + u8 _31; + u8 _32; + u64 _38; + }; + private: + bool m_valid[MaxTaskCount]; + Task m_tasks[MaxTaskCount]; + public: + TaskManager() : m_valid() { /* ... */ } + }; + +}