mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-05-21 10:25:08 -04:00
htc: declare and begin impl of HtclowManagerImpl interface
This commit is contained in:
parent
968ce12492
commit
e20c2450ce
20 changed files with 405 additions and 9 deletions
|
@ -36,6 +36,8 @@ namespace ams::htclow {
|
||||||
|
|
||||||
struct ChannelConfig {
|
struct ChannelConfig {
|
||||||
bool flow_control_enabled;
|
bool flow_control_enabled;
|
||||||
|
bool handshake_enabled;
|
||||||
|
size_t max_packet_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr bool IsStateTransitionAllowed(ChannelState from, ChannelState to) {
|
constexpr bool IsStateTransitionAllowed(ChannelState from, ChannelState to) {
|
||||||
|
|
|
@ -21,6 +21,7 @@ namespace ams::htclow {
|
||||||
|
|
||||||
enum class ModuleId : u8 {
|
enum class ModuleId : u8 {
|
||||||
Htcfs = 1,
|
Htcfs = 1,
|
||||||
|
|
||||||
Htcmisc = 3,
|
Htcmisc = 3,
|
||||||
Htcs = 4,
|
Htcs = 4,
|
||||||
};
|
};
|
||||||
|
|
|
@ -57,8 +57,8 @@ namespace ams::htc::server::driver {
|
||||||
R_TRY(m_manager->Open(GetHtclowChannel(channel, m_module_id)));
|
R_TRY(m_manager->Open(GetHtclowChannel(channel, m_module_id)));
|
||||||
|
|
||||||
/* Set the send/receive buffers. */
|
/* Set the send/receive buffers. */
|
||||||
m_manager->SetReceiveBuffer(receive_buffer, receive_buffer_size);
|
m_manager->SetReceiveBuffer(GetHtclowChannel(channel, m_module_id), receive_buffer, receive_buffer_size);
|
||||||
m_manager->SetSendBuffer(send_buffer, send_buffer_size);
|
m_manager->SetSendBuffer(GetHtclowChannel(channel, m_module_id), send_buffer, send_buffer_size);
|
||||||
|
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
@ -151,7 +151,7 @@ namespace ams::htc::server::driver {
|
||||||
size_t received = 0;
|
size_t received = 0;
|
||||||
do {
|
do {
|
||||||
size_t cur_received;
|
size_t cur_received;
|
||||||
const Result result = this->ReceiveInternal(std::addressof(cur_received), static_cast<u8 *>(dst) + received, static_cast<size_t>(src_size) - received, channel, option);
|
const Result result = this->ReceiveInternal(std::addressof(cur_received), static_cast<u8 *>(dst) + received, static_cast<size_t>(dst_size) - received, channel, option);
|
||||||
|
|
||||||
if (R_FAILED(result)) {
|
if (R_FAILED(result)) {
|
||||||
if (htclow::ResultChannelReceiveBufferEmpty::Includes(result)) {
|
if (htclow::ResultChannelReceiveBufferEmpty::Includes(result)) {
|
||||||
|
|
|
@ -59,4 +59,9 @@ namespace ams::htclow::driver {
|
||||||
return m_open_driver;
|
return m_open_driver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DriverManager::SetDebugDriver(IDriver *driver) {
|
||||||
|
m_debug_driver = driver;
|
||||||
|
m_driver_type = impl::DriverType::Debug;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,8 @@ namespace ams::htclow::driver {
|
||||||
Result OpenDriver(impl::DriverType driver_type);
|
Result OpenDriver(impl::DriverType driver_type);
|
||||||
|
|
||||||
IDriver *GetCurrentDriver();
|
IDriver *GetCurrentDriver();
|
||||||
|
|
||||||
|
void SetDebugDriver(IDriver *driver);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
#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),
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
|
@ -36,8 +36,104 @@ namespace ams::htclow {
|
||||||
return m_impl->CloseDriver();
|
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() {
|
void HtclowManager::Disconnect() {
|
||||||
return m_impl->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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
|
#include "driver/htclow_i_driver.hpp"
|
||||||
|
|
||||||
namespace ams::htclow {
|
namespace ams::htclow {
|
||||||
|
|
||||||
|
@ -31,7 +32,45 @@ namespace ams::htclow {
|
||||||
Result OpenDriver(impl::DriverType driver_type);
|
Result OpenDriver(impl::DriverType driver_type);
|
||||||
void CloseDriver();
|
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();
|
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);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,8 +56,116 @@ namespace ams::htclow {
|
||||||
AMS_ABORT("HtclowManagerImpl::CloseDriver");
|
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() {
|
void HtclowManagerImpl::Disconnect() {
|
||||||
AMS_ABORT("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");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,45 @@ namespace ams::htclow {
|
||||||
Result OpenDriver(impl::DriverType driver_type);
|
Result OpenDriver(impl::DriverType driver_type);
|
||||||
void CloseDriver();
|
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();
|
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);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,10 @@ namespace ams::htclow::mux {
|
||||||
|
|
||||||
void UpdateChannelState();
|
void UpdateChannelState();
|
||||||
void UpdateMuxState();
|
void UpdateMuxState();
|
||||||
|
public:
|
||||||
|
Result Open(impl::ChannelInternalType channel);
|
||||||
|
|
||||||
|
os::EventType *GetTaskEvent(u32 task_id);
|
||||||
private:
|
private:
|
||||||
Result CheckChannelExist(impl::ChannelInternalType channel);
|
Result CheckChannelExist(impl::ChannelInternalType channel);
|
||||||
|
|
||||||
|
|
|
@ -16,9 +16,20 @@
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
#include "htclow_mux_channel_impl.hpp"
|
#include "htclow_mux_channel_impl.hpp"
|
||||||
#include "../ctrl/htclow_ctrl_state_machine.hpp"
|
#include "../ctrl/htclow_ctrl_state_machine.hpp"
|
||||||
|
#include "../htclow_default_channel_config.hpp"
|
||||||
|
|
||||||
namespace ams::htclow::mux {
|
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) {
|
void ChannelImpl::SetVersion(s16 version) {
|
||||||
/* Sanity check the version. */
|
/* Sanity check the version. */
|
||||||
AMS_ASSERT(version <= ProtocolVersion);
|
AMS_ASSERT(version <= ProtocolVersion);
|
||||||
|
|
|
@ -43,10 +43,10 @@ namespace ams::htclow::mux {
|
||||||
RingBuffer m_receive_buffer;
|
RingBuffer m_receive_buffer;
|
||||||
s16 m_version;
|
s16 m_version;
|
||||||
ChannelConfig m_config;
|
ChannelConfig m_config;
|
||||||
|
u64 m_offset;
|
||||||
u64 m_total_send_size;
|
u64 m_total_send_size;
|
||||||
u64 m_next_max_data;
|
u64 m_next_max_data;
|
||||||
u64 m_cur_max_data;
|
u64 m_cur_max_data;
|
||||||
u64 m_offset;
|
|
||||||
std::optional<u64> m_share;
|
std::optional<u64> m_share;
|
||||||
os::Event m_state_change_event;
|
os::Event m_state_change_event;
|
||||||
ChannelState m_state;
|
ChannelState m_state;
|
||||||
|
|
|
@ -43,4 +43,28 @@ namespace ams::htclow::mux {
|
||||||
return this->GetChannelImpl(it->second);
|
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<const impl::ChannelInternalType, int>{channel, idx});
|
||||||
|
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,8 @@ namespace ams::htclow::mux {
|
||||||
bool Exists(impl::ChannelInternalType channel) const {
|
bool Exists(impl::ChannelInternalType channel) const {
|
||||||
return m_map.find(channel) != m_map.end();
|
return m_map.find(channel) != m_map.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result AddChannel(impl::ChannelInternalType channel);
|
||||||
private:
|
private:
|
||||||
public:
|
public:
|
||||||
MapType &GetMap() {
|
MapType &GetMap() {
|
||||||
|
|
|
@ -18,6 +18,14 @@
|
||||||
|
|
||||||
namespace ams::htclow::mux {
|
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) {
|
void TaskManager::NotifyDisconnect(impl::ChannelInternalType channel) {
|
||||||
for (auto i = 0; i < MaxTaskCount; ++i) {
|
for (auto i = 0; i < MaxTaskCount; ++i) {
|
||||||
if (m_valid[i] && m_tasks[i].channel == channel) {
|
if (m_valid[i] && m_tasks[i].channel == channel) {
|
||||||
|
|
|
@ -51,6 +51,8 @@ namespace ams::htclow::mux {
|
||||||
public:
|
public:
|
||||||
TaskManager() : m_valid() { /* ... */ }
|
TaskManager() : m_valid() { /* ... */ }
|
||||||
|
|
||||||
|
os::EventType *GetTaskEvent(u32 task_id);
|
||||||
|
|
||||||
void NotifyDisconnect(impl::ChannelInternalType channel);
|
void NotifyDisconnect(impl::ChannelInternalType channel);
|
||||||
void NotifyReceiveData(impl::ChannelInternalType channel, size_t size);
|
void NotifyReceiveData(impl::ChannelInternalType channel, size_t size);
|
||||||
void NotifySendReady();
|
void NotifySendReady();
|
||||||
|
|
|
@ -20,10 +20,13 @@ namespace ams::htclow {
|
||||||
|
|
||||||
R_DEFINE_NAMESPACE_RESULT_MODULE(29);
|
R_DEFINE_NAMESPACE_RESULT_MODULE(29);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RESULT(ConnectionFailure, 1);
|
R_DEFINE_ERROR_RESULT(ConnectionFailure, 1);
|
||||||
R_DEFINE_ERROR_RESULT(UnknownDriverType, 3);
|
R_DEFINE_ERROR_RESULT(UnknownDriverType, 3);
|
||||||
R_DEFINE_ERROR_RESULT(NonBlockingReceiveFailed, 5);
|
R_DEFINE_ERROR_RESULT(NonBlockingReceiveFailed, 5);
|
||||||
R_DEFINE_ERROR_RESULT(ChannelNotExist, 10);
|
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(InvalidChannelState, 200);
|
||||||
R_DEFINE_ERROR_RESULT(InvalidChannelStateDisconnected, 201);
|
R_DEFINE_ERROR_RESULT(InvalidChannelStateDisconnected, 201);
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <vapours/util/util_type_traits.hpp>
|
#include <vapours/util/util_type_traits.hpp>
|
||||||
#include <vapours/util/util_alignment.hpp>
|
#include <vapours/util/util_alignment.hpp>
|
||||||
#include <vapours/util/util_size.hpp>
|
#include <vapours/util/util_size.hpp>
|
||||||
|
#include <vapours/util/util_int_util.hpp>
|
||||||
#include <vapours/util/util_aligned_buffer.hpp>
|
#include <vapours/util/util_aligned_buffer.hpp>
|
||||||
#include <vapours/util/util_endian.hpp>
|
#include <vapours/util/util_endian.hpp>
|
||||||
#include <vapours/util/util_exchange.hpp>
|
#include <vapours/util/util_exchange.hpp>
|
||||||
|
@ -39,7 +40,6 @@
|
||||||
#include <vapours/util/util_uuid.hpp>
|
#include <vapours/util/util_uuid.hpp>
|
||||||
#include <vapours/util/util_bounded_map.hpp>
|
#include <vapours/util/util_bounded_map.hpp>
|
||||||
#include <vapours/util/util_overlap.hpp>
|
#include <vapours/util/util_overlap.hpp>
|
||||||
#include <vapours/util/util_int_util.hpp>
|
|
||||||
#include <vapours/util/util_string_util.hpp>
|
#include <vapours/util/util_string_util.hpp>
|
||||||
#include <vapours/util/util_string_view.hpp>
|
#include <vapours/util/util_string_view.hpp>
|
||||||
#include <vapours/util/util_variadic.hpp>
|
#include <vapours/util/util_variadic.hpp>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue