htc: declare and begin impl of HtclowManagerImpl interface

This commit is contained in:
Michael Scire
2021-02-09 12:36:37 -08:00
committed by SciresM
parent 968ce12492
commit e20c2450ce
20 changed files with 405 additions and 9 deletions

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -16,9 +16,20 @@
#include <stratosphere.hpp>
#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);

View File

@@ -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<u64> m_share;
os::Event m_state_change_event;
ChannelState m_state;

View File

@@ -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<const impl::ChannelInternalType, int>{channel, idx});
return ResultSuccess();
}
}

View File

@@ -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() {

View File

@@ -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) {

View File

@@ -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();