diff --git a/libraries/libstratosphere/source/htcs/impl/htcs_manager.cpp b/libraries/libstratosphere/source/htcs/impl/htcs_manager.cpp index 42dadd090..51e7a7296 100644 --- a/libraries/libstratosphere/source/htcs/impl/htcs_manager.cpp +++ b/libraries/libstratosphere/source/htcs/impl/htcs_manager.cpp @@ -131,7 +131,7 @@ namespace ams::htcs::impl { /* Invoke our implementation. */ s32 err; s64 recv_size; - const Result result = m_impl->Recv(std::addressof(err), std::addressof(recv_size), buffer, size, desc, flags); + const Result result = m_impl->Receive(std::addressof(err), std::addressof(recv_size), buffer, size, desc, flags); /* Set output. */ if (R_SUCCEEDED(result)) { diff --git a/libraries/libstratosphere/source/htcs/impl/htcs_manager_impl.cpp b/libraries/libstratosphere/source/htcs/impl/htcs_manager_impl.cpp index d6c71fb20..0c0b30daa 100644 --- a/libraries/libstratosphere/source/htcs/impl/htcs_manager_impl.cpp +++ b/libraries/libstratosphere/source/htcs/impl/htcs_manager_impl.cpp @@ -46,4 +46,140 @@ namespace ams::htcs::impl { return m_monitor.IsServiceAvailable(); } + Result HtcsManagerImpl::CreateSocket(s32 *out_err, s32 *out_desc, bool enable_disconnection_emulation) { + return m_service.CreateSocket(out_err, out_desc, enable_disconnection_emulation); + } + + Result HtcsManagerImpl::DestroySocket(s32 *out_err, s32 desc) { + return m_service.DestroySocket(out_err, desc); + } + + Result HtcsManagerImpl::Connect(s32 *out_err, s32 desc, const SockAddrHtcs &address) { + return m_service.Connect(out_err, desc, address); + } + + Result HtcsManagerImpl::Bind(s32 *out_err, s32 desc, const SockAddrHtcs &address) { + return m_service.Bind(out_err, desc, address); + } + + Result HtcsManagerImpl::Listen(s32 *out_err, s32 desc, s32 backlog_count) { + return m_service.Listen(out_err, desc, backlog_count); + } + + Result HtcsManagerImpl::Receive(s32 *out_err, s64 *out_size, char *buffer, size_t size, s32 desc, s32 flags) { + return m_service.Receive(out_err, out_size, buffer, size, desc, flags); + } + + Result HtcsManagerImpl::Send(s32 *out_err, s64 *out_size, const char *buffer, size_t size, s32 desc, s32 flags) { + return m_service.Send(out_err, out_size, buffer, size, desc, flags); + } + + Result HtcsManagerImpl::Shutdown(s32 *out_err, s32 desc, s32 how) { + return m_service.Shutdown(out_err, desc, how); + } + + Result HtcsManagerImpl::Fcntl(s32 *out_err, s32 *out_res, s32 desc, s32 command, s32 value) { + return m_service.Fcntl(out_err, out_res, desc, command, value); + } + + Result HtcsManagerImpl::AcceptStart(u32 *out_task_id, Handle *out_handle, s32 desc) { + return m_service.AcceptStart(out_task_id, out_handle, desc); + } + + Result HtcsManagerImpl::AcceptResults(s32 *out_err, s32 *out_desc, SockAddrHtcs *out_address, u32 task_id, s32 desc) { + return m_service.AcceptResults(out_err, out_desc, out_address, task_id, desc); + } + + Result HtcsManagerImpl::RecvStart(u32 *out_task_id, Handle *out_handle, s64 size, s32 desc, s32 flags) { + return m_service.ReceiveSmallStart(out_task_id, out_handle, size, desc, flags); + } + + Result HtcsManagerImpl::RecvResults(s32 *out_err, s64 *out_size, char *buffer, s64 buffer_size, u32 task_id, s32 desc) { + return m_service.ReceiveSmallResults(out_err, out_size, buffer, buffer_size, task_id, desc); + } + + Result HtcsManagerImpl::SendStart(u32 *out_task_id, Handle *out_handle, const char *buffer, s64 size, s32 desc, s32 flags) { + /* Start the send. */ + u32 task_id; + Handle handle; + R_TRY(m_service.SendSmallStart(std::addressof(task_id), std::addressof(handle), desc, size, flags)); + + /* Continue the send. */ + s64 continue_size; + const Result result = m_service.SendSmallContinue(std::addressof(continue_size), buffer, size, task_id, desc); + if (R_SUCCEEDED(result) || htcs::ResultUnknown2023::Includes(result) || htc::ResultUnknown2033::Includes(result)) { + *out_task_id = task_id; + *out_handle = handle; + } else { + os::SystemEventType event; + os::AttachReadableHandleToSystemEvent(std::addressof(event), handle, true, os::EventClearMode_ManualClear); + + s32 err; + s64 rsize; + m_service.SendSmallResults(std::addressof(err), std::addressof(rsize), task_id, desc); + + os::DestroySystemEvent(std::addressof(event)); + + return result; + } + + return ResultSuccess(); + } + + Result HtcsManagerImpl::SendLargeStart(u32 *out_task_id, Handle *out_handle, const char **buffers, const s64 *sizes, s32 count, s32 desc, s32 flags) { + /* NOTE: Nintendo aborts here, too. */ + AMS_ABORT("HtcsManagerImpl::SendLargeStart is not implemented"); + } + + Result HtcsManagerImpl::SendResults(s32 *out_err, s64 *out_size, u32 task_id, s32 desc) { + return m_service.SendSmallResults(out_err, out_size, task_id, desc); + } + + Result HtcsManagerImpl::StartSend(u32 *out_task_id, Handle *out_handle, s32 desc, s64 size, s32 flags) { + return m_service.SendStart(out_task_id, out_handle, desc, size, flags); + } + + Result HtcsManagerImpl::ContinueSend(s64 *out_size, const char *buffer, s64 buffer_size, u32 task_id, s32 desc) { + return m_service.SendContinue(out_size, buffer, buffer_size, task_id, desc); + } + + Result HtcsManagerImpl::EndSend(s32 *out_err, s64 *out_size, u32 task_id, s32 desc) { + return m_service.SendResults(out_err, out_size, task_id, desc); + } + + Result HtcsManagerImpl::StartRecv(u32 *out_task_id, Handle *out_handle, s64 size, s32 desc, s32 flags) { + return m_service.ReceiveStart(out_task_id, out_handle, size, desc, flags); + } + + Result HtcsManagerImpl::EndRecv(s32 *out_err, s64 *out_size, char *buffer, s64 buffer_size, u32 task_id, s32 desc) { + return m_service.ReceiveResults(out_err, out_size, buffer, buffer_size, task_id, desc); + } + + Result HtcsManagerImpl::StartSelect(u32 *out_task_id, Handle *out_handle, Span read_handles, Span write_handles, Span exception_handles, s64 tv_sec, s64 tv_usec) { + /* Start the select. */ + u32 task_id; + Handle handle; + const Result result = m_service.SelectStart(std::addressof(task_id), std::addressof(handle), read_handles, write_handles, exception_handles, tv_sec, tv_usec); + + /* Ensure our state ends up clean. */ + if (htcs::ResultUnknown2021::Includes(result)) { + os::SystemEventType event; + os::AttachReadableHandleToSystemEvent(std::addressof(event), handle, true, os::EventClearMode_ManualClear); + + s32 err, res; + m_service.SelectEnd(std::addressof(err), std::addressof(res), Span{}, Span{}, Span{}, task_id); + + os::DestroySystemEvent(std::addressof(event)); + } else { + *out_task_id = task_id; + *out_handle = handle; + } + + return result; + } + + Result HtcsManagerImpl::EndSelect(s32 *out_err, s32 *out_res, Span read_handles, Span write_handles, Span exception_handles, u32 task_id) { + return m_service.SelectEnd(out_err, out_res, read_handles, write_handles, exception_handles, task_id); + } + } diff --git a/libraries/libstratosphere/source/htcs/impl/htcs_manager_impl.hpp b/libraries/libstratosphere/source/htcs/impl/htcs_manager_impl.hpp index a2875fbbc..68047eb94 100644 --- a/libraries/libstratosphere/source/htcs/impl/htcs_manager_impl.hpp +++ b/libraries/libstratosphere/source/htcs/impl/htcs_manager_impl.hpp @@ -47,7 +47,7 @@ namespace ams::htcs::impl { Result Connect(s32 *out_err, s32 desc, const SockAddrHtcs &address); Result Bind(s32 *out_err, s32 desc, const SockAddrHtcs &address); Result Listen(s32 *out_err, s32 desc, s32 backlog_count); - Result Recv(s32 *out_err, s64 *out_size, char *buffer, size_t size, s32 desc, s32 flags); + Result Receive(s32 *out_err, s64 *out_size, char *buffer, size_t size, s32 desc, s32 flags); Result Send(s32 *out_err, s64 *out_size, const char *buffer, size_t size, s32 desc, s32 flags); Result Shutdown(s32 *out_err, s32 desc, s32 how); Result Fcntl(s32 *out_err, s32 *out_res, s32 desc, s32 command, s32 value); diff --git a/libraries/libstratosphere/source/htcs/impl/htcs_service.hpp b/libraries/libstratosphere/source/htcs/impl/htcs_service.hpp index 9968b81ec..e00b887c2 100644 --- a/libraries/libstratosphere/source/htcs/impl/htcs_service.hpp +++ b/libraries/libstratosphere/source/htcs/impl/htcs_service.hpp @@ -32,6 +32,36 @@ namespace ams::htcs::impl { : m_allocator(allocator), m_driver(drv), m_rpc_client(rc), m_data_channel_manager(dcm) { /* ... */ } public: /* TODO */ + public: + Result CreateSocket(s32 *out_err, s32 *out_desc, bool enable_disconnection_emulation); + Result DestroySocket(s32 *out_err, s32 desc); + Result Connect(s32 *out_err, s32 desc, const SockAddrHtcs &address); + Result Bind(s32 *out_err, s32 desc, const SockAddrHtcs &address); + Result Listen(s32 *out_err, s32 desc, s32 backlog_count); + Result Receive(s32 *out_err, s64 *out_size, char *buffer, size_t size, s32 desc, s32 flags); + Result Send(s32 *out_err, s64 *out_size, const char *buffer, size_t size, s32 desc, s32 flags); + Result Shutdown(s32 *out_err, s32 desc, s32 how); + Result Fcntl(s32 *out_err, s32 *out_res, s32 desc, s32 command, s32 value); + + Result AcceptStart(u32 *out_task_id, Handle *out_handle, s32 desc); + Result AcceptResults(s32 *out_err, s32 *out_desc, SockAddrHtcs *out_address, u32 task_id, s32 desc); + + Result ReceiveSmallStart(u32 *out_task_id, Handle *out_handle, s64 size, s32 desc, s32 flags); + Result ReceiveSmallResults(s32 *out_err, s64 *out_size, char *buffer, s64 buffer_size, u32 task_id, s32 desc); + + Result SendSmallStart(u32 *out_task_id, Handle *out_handle, s32 desc, s64 size, s32 flags); + Result SendSmallContinue(s64 *out_size, const char *buffer, s64 buffer_size, u32 task_id, s32 desc); + Result SendSmallResults(s32 *out_err, s64 *out_size, u32 task_id, s32 desc); + + Result SendStart(u32 *out_task_id, Handle *out_handle, s32 desc, s64 size, s32 flags); + Result SendContinue(s64 *out_size, const char *buffer, s64 buffer_size, u32 task_id, s32 desc); + Result SendResults(s32 *out_err, s64 *out_size, u32 task_id, s32 desc); + + Result ReceiveStart(u32 *out_task_id, Handle *out_handle, s64 size, s32 desc, s32 flags); + Result ReceiveResults(s32 *out_err, s64 *out_size, char *buffer, s64 buffer_size, u32 task_id, s32 desc); + + Result SelectStart(u32 *out_task_id, Handle *out_handle, Span read_handles, Span write_handles, Span exception_handles, s64 tv_sec, s64 tv_usec); + Result SelectEnd(s32 *out_err, s32 *out_res, Span read_handles, Span write_handles, Span exception_handles, u32 task_id); }; } diff --git a/libraries/libvapours/include/vapours/results/htcs_results.hpp b/libraries/libvapours/include/vapours/results/htcs_results.hpp index de4c6206e..14683cdcc 100644 --- a/libraries/libvapours/include/vapours/results/htcs_results.hpp +++ b/libraries/libvapours/include/vapours/results/htcs_results.hpp @@ -23,5 +23,7 @@ namespace ams::htcs { R_DEFINE_ERROR_RESULT(InvalidHandle, 9); R_DEFINE_ERROR_RESULT(InvalidSize, 2014); + R_DEFINE_ERROR_RESULT(Unknown2021, 2021); + R_DEFINE_ERROR_RESULT(Unknown2023, 2023); }