mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-12-18 08:22:04 +00:00
htcfs: implement OpenDirectory/CloseDirectory
This commit is contained in:
parent
b371487525
commit
e79417c37c
9 changed files with 209 additions and 13 deletions
|
@ -819,6 +819,7 @@ namespace ams::sf::impl {
|
||||||
|
|
||||||
/* Useful defines. */
|
/* Useful defines. */
|
||||||
using ArgsTypeForInvoke = typename CommandMeta::ArgsTypeForInvoke;
|
using ArgsTypeForInvoke = typename CommandMeta::ArgsTypeForInvoke;
|
||||||
|
using ArgsType = typename CommandMeta::ArgsType;
|
||||||
using BufferArrayType = std::array<cmif::PointerAndSize, CommandMeta::NumBuffers>;
|
using BufferArrayType = std::array<cmif::PointerAndSize, CommandMeta::NumBuffers>;
|
||||||
using OutRawHolderType = OutRawHolder<CommandMeta::OutDataSize, CommandMeta::OutDataAlign>;
|
using OutRawHolderType = OutRawHolder<CommandMeta::OutDataSize, CommandMeta::OutDataAlign>;
|
||||||
using OutHandleHolderType = OutHandleHolder<CommandMeta::NumOutMoveHandles, CommandMeta::NumOutCopyHandles>;
|
using OutHandleHolderType = OutHandleHolder<CommandMeta::NumOutMoveHandles, CommandMeta::NumOutCopyHandles>;
|
||||||
|
@ -1004,8 +1005,8 @@ namespace ams::sf::impl {
|
||||||
|
|
||||||
/* Argument deserialization. */
|
/* Argument deserialization. */
|
||||||
private:
|
private:
|
||||||
template<size_t Index, typename T = typename std::tuple_element<Index, ArgsTypeForInvoke>::type>
|
template<size_t Index, typename T = typename std::tuple_element<Index, ArgsType>::type>
|
||||||
NX_CONSTEXPR T DeserializeArgumentImpl(const cmif::ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data, const OutRawHolderType &out_raw_holder, const BufferArrayType &buffers, OutHandleHolderType &out_handles_holder, InOutObjectHolderType &in_out_objects_holder) {
|
NX_CONSTEXPR typename std::tuple_element<Index, ArgsTypeForInvoke>::type DeserializeArgumentImpl(const cmif::ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data, const OutRawHolderType &out_raw_holder, const BufferArrayType &buffers, OutHandleHolderType &out_handles_holder, InOutObjectHolderType &in_out_objects_holder) {
|
||||||
constexpr auto Info = CommandMeta::ArgumentSerializationInfos[Index];
|
constexpr auto Info = CommandMeta::ArgumentSerializationInfos[Index];
|
||||||
if constexpr (Info.arg_type == ArgumentType::InData) {
|
if constexpr (Info.arg_type == ArgumentType::InData) {
|
||||||
/* New in rawdata. */
|
/* New in rawdata. */
|
||||||
|
@ -1051,8 +1052,8 @@ namespace ams::sf::impl {
|
||||||
constexpr auto Attributes = CommandMeta::BufferAttributes[Info.buffer_index];
|
constexpr auto Attributes = CommandMeta::BufferAttributes[Info.buffer_index];
|
||||||
if constexpr (Attributes & SfBufferAttr_In) {
|
if constexpr (Attributes & SfBufferAttr_In) {
|
||||||
/* TODO: AMS_ABORT_UNLESS()? N does not bother. */
|
/* TODO: AMS_ABORT_UNLESS()? N does not bother. */
|
||||||
static_assert(std::is_reference<T>::value);
|
using InvokeType = typename std::tuple_element<Index, ArgsTypeForInvoke>::type;
|
||||||
static_assert(std::is_const<typename std::remove_reference<T>::type>::value);
|
static_assert(std::same_as<InvokeType, const T &>);
|
||||||
return *reinterpret_cast<const T *>(buffers[Info.buffer_index].GetAddress());
|
return *reinterpret_cast<const T *>(buffers[Info.buffer_index].GetAddress());
|
||||||
} else if constexpr (Attributes & SfBufferAttr_Out) {
|
} else if constexpr (Attributes & SfBufferAttr_Out) {
|
||||||
return T(buffers[Info.buffer_index]);
|
return T(buffers[Info.buffer_index]);
|
||||||
|
|
|
@ -43,5 +43,4 @@ namespace ams::htcfs {
|
||||||
return GetReference(g_client_storage);
|
return GetReference(g_client_storage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,9 @@ namespace ams::htcfs {
|
||||||
ClientImpl m_impl;
|
ClientImpl m_impl;
|
||||||
public:
|
public:
|
||||||
Client(htclow::HtclowManager *manager) : m_impl(manager) { /* ... */ }
|
Client(htclow::HtclowManager *manager) : m_impl(manager) { /* ... */ }
|
||||||
|
public:
|
||||||
|
Result OpenDirectory(s32 *out_handle, const char *path, fs::OpenDirectoryMode mode, bool case_sensitive) { return m_impl.OpenDirectory(out_handle, path, mode, case_sensitive); }
|
||||||
|
Result CloseDirectory(s32 handle) { return m_impl.CloseDirectory(handle); }
|
||||||
};
|
};
|
||||||
|
|
||||||
void InitializeClient(htclow::HtclowManager *manager);
|
void InitializeClient(htclow::HtclowManager *manager);
|
||||||
|
|
|
@ -29,6 +29,10 @@ namespace ams::htcfs {
|
||||||
|
|
||||||
constinit u8 g_cache[32_KB];
|
constinit u8 g_cache[32_KB];
|
||||||
|
|
||||||
|
ALWAYS_INLINE Result ConvertNativeResult(s64 value) {
|
||||||
|
return result::impl::MakeResult(value);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ClientImpl::ClientImpl(htclow::HtclowManager *manager)
|
ClientImpl::ClientImpl(htclow::HtclowManager *manager)
|
||||||
|
@ -188,6 +192,26 @@ namespace ams::htcfs {
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result ClientImpl::CheckResponseHeader(const Header &response, PacketType packet_type) {
|
||||||
|
/* Perform base checks. */
|
||||||
|
R_TRY(this->CheckResponseHeaderWithoutVersion(response, packet_type));
|
||||||
|
|
||||||
|
/* Check the version. */
|
||||||
|
R_UNLESS(response.version == m_header_factory.GetVersion(), htcfs::ResultUnexpectedResponseProtocolVersion());
|
||||||
|
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result ClientImpl::CheckResponseHeader(const Header &response, PacketType packet_type, s64 body_size) {
|
||||||
|
/* Perform base checks. */
|
||||||
|
R_TRY(this->CheckResponseHeader(response, packet_type));
|
||||||
|
|
||||||
|
/* Check the body size. */
|
||||||
|
R_UNLESS(response.body_size == body_size, htcfs::ResultUnexpectedResponseBodySize());
|
||||||
|
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
Result ClientImpl::GetMaxProtocolVersion(s16 *out) {
|
Result ClientImpl::GetMaxProtocolVersion(s16 *out) {
|
||||||
/* Create space for request and response. */
|
/* Create space for request and response. */
|
||||||
Header request, response;
|
Header request, response;
|
||||||
|
@ -283,4 +307,110 @@ namespace ams::htcfs {
|
||||||
return ResultSuccess();
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result ClientImpl::InitializeRpcChannel() {
|
||||||
|
/* Check that we're not cancelled. */
|
||||||
|
R_UNLESS(!m_event.TryWait(), htcfs::ResultConnectionFailure());
|
||||||
|
|
||||||
|
/* Check that we're connected. */
|
||||||
|
R_UNLESS(m_connected, htcfs::ResultConnectionFailure());
|
||||||
|
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result ClientImpl::SendRequest(const Header &request, const void *arg1, size_t arg1_size, const void *arg2, size_t arg2_size) {
|
||||||
|
/* Try to perform an optimized send. */
|
||||||
|
if (sizeof(request) + arg1_size + arg2_size < sizeof(m_packet_buffer)) {
|
||||||
|
/* Setup our packet buffer. */
|
||||||
|
std::memcpy(m_packet_buffer, std::addressof(request), sizeof(request));
|
||||||
|
if (arg1_size > 0) {
|
||||||
|
std::memcpy(m_packet_buffer + sizeof(request), arg1, arg1_size);
|
||||||
|
}
|
||||||
|
if (arg2_size > 0) {
|
||||||
|
std::memcpy(m_packet_buffer + sizeof(request) + arg1_size, arg2, arg2_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send the request. */
|
||||||
|
R_TRY(this->SendToRpcChannel(m_packet_buffer, sizeof(request) + arg1_size + arg2_size));
|
||||||
|
} else {
|
||||||
|
/* We can't perform a single optimized send, so perform three separate sends. */
|
||||||
|
R_TRY(this->SendToRpcChannel(std::addressof(request), sizeof(request)));
|
||||||
|
|
||||||
|
if (arg1_size > 0) {
|
||||||
|
R_TRY(this->SendToRpcChannel(arg1, arg1_size));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arg2_size > 0) {
|
||||||
|
R_TRY(this->SendToRpcChannel(arg2, arg2_size));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result ClientImpl::OpenDirectory(s32 *out_handle, const char *path, fs::OpenDirectoryMode mode, bool case_sensitive) {
|
||||||
|
/* Lock ourselves. */
|
||||||
|
std::scoped_lock lk(m_mutex);
|
||||||
|
|
||||||
|
/* Initialize our rpc channel. */
|
||||||
|
R_TRY(this->InitializeRpcChannel());
|
||||||
|
|
||||||
|
/* Create space for request and response. */
|
||||||
|
Header request, response;
|
||||||
|
|
||||||
|
/* Create header for the request. */
|
||||||
|
const auto path_len = std::strlen(path);
|
||||||
|
m_header_factory.MakeOpenDirectoryHeader(std::addressof(request), path_len, mode, case_sensitive);
|
||||||
|
|
||||||
|
/* Send the request to the host. */
|
||||||
|
R_TRY(this->SendRequest(request, path, path_len));
|
||||||
|
|
||||||
|
/* Receive response from the host. */
|
||||||
|
R_TRY(this->ReceiveFromRpcChannel(std::addressof(response), sizeof(response)));
|
||||||
|
|
||||||
|
/* Check the response header. */
|
||||||
|
R_TRY(this->CheckResponseHeader(response, request.packet_type, 0));
|
||||||
|
|
||||||
|
/* Check that we succeeded. */
|
||||||
|
R_TRY(ConvertHtcfsResult(response.params[0]));
|
||||||
|
|
||||||
|
/* Check our operation's result. */
|
||||||
|
R_TRY(ConvertNativeResult(response.params[1]));
|
||||||
|
|
||||||
|
/* Set the output handle. */
|
||||||
|
*out_handle = static_cast<s32>(response.params[2]);
|
||||||
|
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result ClientImpl::CloseDirectory(s32 handle) {
|
||||||
|
/* Lock ourselves. */
|
||||||
|
std::scoped_lock lk(m_mutex);
|
||||||
|
|
||||||
|
/* Initialize our rpc channel. */
|
||||||
|
R_TRY(this->InitializeRpcChannel());
|
||||||
|
|
||||||
|
/* Create space for request and response. */
|
||||||
|
Header request, response;
|
||||||
|
|
||||||
|
/* Create header for the request. */
|
||||||
|
m_header_factory.MakeCloseDirectoryHeader(std::addressof(request), handle);
|
||||||
|
|
||||||
|
/* Send the request to the host. */
|
||||||
|
R_TRY(this->SendRequest(request));
|
||||||
|
|
||||||
|
/* Receive response from the host. */
|
||||||
|
R_TRY(this->ReceiveFromRpcChannel(std::addressof(response), sizeof(response)));
|
||||||
|
|
||||||
|
/* Check the response header. */
|
||||||
|
R_TRY(this->CheckResponseHeader(response, request.packet_type, 0));
|
||||||
|
|
||||||
|
/* Check that we succeeded. */
|
||||||
|
R_TRY(ConvertHtcfsResult(response.params[0]));
|
||||||
|
|
||||||
|
/* Check our operation's result. */
|
||||||
|
R_TRY(ConvertNativeResult(response.params[1]));
|
||||||
|
|
||||||
|
return ResultSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,9 @@ namespace ams::htcfs {
|
||||||
void Start();
|
void Start();
|
||||||
void Cancel();
|
void Cancel();
|
||||||
void Wait();
|
void Wait();
|
||||||
|
public:
|
||||||
|
Result OpenDirectory(s32 *out_handle, const char *path, fs::OpenDirectoryMode mode, bool case_sensitive);
|
||||||
|
Result CloseDirectory(s32 handle);
|
||||||
private:
|
private:
|
||||||
int WaitAny(htclow::ChannelState state, os::EventType *event);
|
int WaitAny(htclow::ChannelState state, os::EventType *event);
|
||||||
|
|
||||||
|
@ -59,15 +62,23 @@ namespace ams::htcfs {
|
||||||
void TearDownProtocol();
|
void TearDownProtocol();
|
||||||
|
|
||||||
Result CheckResponseHeaderWithoutVersion(const Header &response, PacketType packet_type);
|
Result CheckResponseHeaderWithoutVersion(const Header &response, PacketType packet_type);
|
||||||
|
Result CheckResponseHeader(const Header &response, PacketType packet_type);
|
||||||
|
Result CheckResponseHeader(const Header &response, PacketType packet_type, s64 body_size);
|
||||||
|
|
||||||
Result GetMaxProtocolVersion(s16 *out);
|
Result GetMaxProtocolVersion(s16 *out);
|
||||||
Result SetProtocolVersion(s16 version);
|
Result SetProtocolVersion(s16 version);
|
||||||
|
|
||||||
|
Result InitializeRpcChannel();
|
||||||
|
|
||||||
Result SendToRpcChannel(const void *src, s64 size);
|
Result SendToRpcChannel(const void *src, s64 size);
|
||||||
Result ReceiveFromRpcChannel(void *dst, s64 size);
|
Result ReceiveFromRpcChannel(void *dst, s64 size);
|
||||||
|
|
||||||
Result SendToHtclow(const void *src, s64 size, htclow::Channel *channel);
|
Result SendToHtclow(const void *src, s64 size, htclow::Channel *channel);
|
||||||
Result ReceiveFromHtclow(void *dst, s64 size, htclow::Channel *channel);
|
Result ReceiveFromHtclow(void *dst, s64 size, htclow::Channel *channel);
|
||||||
|
|
||||||
|
Result SendRequest(const Header &request) { return this->SendRequest(request, nullptr, 0, nullptr, 0); }
|
||||||
|
Result SendRequest(const Header &request, const void *arg1, size_t arg1_size) { return this->SendRequest(request, arg1, arg1_size, nullptr, 0); }
|
||||||
|
Result SendRequest(const Header &request, const void *arg1, size_t arg1_size, const void *arg2, size_t arg2_size);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,14 +15,14 @@
|
||||||
*/
|
*/
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
#include "htcfs_directory_service_object.hpp"
|
#include "htcfs_directory_service_object.hpp"
|
||||||
|
#include "htcfs_client.hpp"
|
||||||
|
|
||||||
namespace ams::htcfs {
|
namespace ams::htcfs {
|
||||||
|
|
||||||
DirectoryServiceObject::DirectoryServiceObject(s32 handle) : m_handle(handle) { /* ... */ }
|
DirectoryServiceObject::DirectoryServiceObject(s32 handle) : m_handle(handle) { /* ... */ }
|
||||||
|
|
||||||
DirectoryServiceObject::~DirectoryServiceObject() {
|
DirectoryServiceObject::~DirectoryServiceObject() {
|
||||||
/* TODO */
|
htcfs::GetClient().CloseDirectory(m_handle);
|
||||||
AMS_ABORT("htcfs::GetClient().CloseDirectory(m_handle);");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DirectoryServiceObject::GetEntryCount(ams::sf::Out<s64> out) {
|
Result DirectoryServiceObject::GetEntryCount(ams::sf::Out<s64> out) {
|
||||||
|
|
|
@ -15,9 +15,37 @@
|
||||||
*/
|
*/
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
#include "htcfs_file_system_service_object.hpp"
|
#include "htcfs_file_system_service_object.hpp"
|
||||||
|
#include "htcfs_file_service_object.hpp"
|
||||||
|
#include "htcfs_directory_service_object.hpp"
|
||||||
|
#include "htcfs_client.hpp"
|
||||||
|
|
||||||
namespace ams::htcfs {
|
namespace ams::htcfs {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
struct DirectoryServiceObjectAllocatorTag;
|
||||||
|
struct FileServiceObjectAllocatorTag;
|
||||||
|
|
||||||
|
using DirectoryServiceObjectAllocator = ams::sf::ExpHeapStaticAllocator<4_KB, DirectoryServiceObjectAllocatorTag>;
|
||||||
|
using FileServiceObjectAllocator = ams::sf::ExpHeapStaticAllocator<4_KB, FileServiceObjectAllocatorTag>;
|
||||||
|
using DirectoryServiceObjectFactory = ams::sf::ObjectFactory<typename DirectoryServiceObjectAllocator::Policy>;
|
||||||
|
using FileServiceObjectFactory = ams::sf::ObjectFactory<typename FileServiceObjectAllocator::Policy>;
|
||||||
|
|
||||||
|
class StaticAllocatorInitializer {
|
||||||
|
public:
|
||||||
|
StaticAllocatorInitializer() {
|
||||||
|
DirectoryServiceObjectAllocator::Initialize(lmem::CreateOption_ThreadSafe);
|
||||||
|
FileServiceObjectAllocator::Initialize(lmem::CreateOption_ThreadSafe);
|
||||||
|
}
|
||||||
|
} g_static_allocator_initializer;
|
||||||
|
|
||||||
|
constexpr bool IsValidPath(const tma::Path &path) {
|
||||||
|
const auto len = util::Strnlen(path.str, fs::EntryNameLengthMax + 1);
|
||||||
|
return 0 < len && len < static_cast<int>(fs::EntryNameLengthMax + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
Result FileSystemServiceObject::OpenFile(sf::Out<sf::SharedPointer<tma::IFileAccessor>> out, const tma::Path &path, u32 open_mode, bool case_sensitive) {
|
Result FileSystemServiceObject::OpenFile(sf::Out<sf::SharedPointer<tma::IFileAccessor>> out, const tma::Path &path, u32 open_mode, bool case_sensitive) {
|
||||||
AMS_ABORT("FileSystemServiceObject::OpenFile");
|
AMS_ABORT("FileSystemServiceObject::OpenFile");
|
||||||
}
|
}
|
||||||
|
@ -39,7 +67,16 @@ namespace ams::htcfs {
|
||||||
}
|
}
|
||||||
|
|
||||||
Result FileSystemServiceObject::OpenDirectory(sf::Out<sf::SharedPointer<tma::IDirectoryAccessor>> out, const tma::Path &path, s32 open_mode, bool case_sensitive) {
|
Result FileSystemServiceObject::OpenDirectory(sf::Out<sf::SharedPointer<tma::IDirectoryAccessor>> out, const tma::Path &path, s32 open_mode, bool case_sensitive) {
|
||||||
AMS_ABORT("FileSystemServiceObject::OpenDirectory");
|
/* Check that the path is valid. */
|
||||||
|
R_UNLESS(IsValidPath(path), htcfs::ResultInvalidArgument());
|
||||||
|
|
||||||
|
/* Open the directory. */
|
||||||
|
s32 handle;
|
||||||
|
R_TRY(htcfs::GetClient().OpenDirectory(std::addressof(handle), path.str, static_cast<fs::OpenDirectoryMode>(open_mode), case_sensitive));
|
||||||
|
|
||||||
|
/* Set the output directory. */
|
||||||
|
*out = DirectoryServiceObjectFactory::CreateSharedEmplaced<tma::IDirectoryAccessor, DirectoryServiceObject>(handle);
|
||||||
|
return ResultSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result FileSystemServiceObject::DirectoryExists(sf::Out<bool> out, const tma::Path &path, bool case_sensitive) {
|
Result FileSystemServiceObject::DirectoryExists(sf::Out<bool> out, const tma::Path &path, bool case_sensitive) {
|
||||||
|
|
|
@ -102,6 +102,9 @@ namespace ams::htcfs {
|
||||||
out->params[2] = param2;
|
out->params[2] = param2;
|
||||||
out->params[3] = param3;
|
out->params[3] = param3;
|
||||||
out->params[4] = param4;
|
out->params[4] = param4;
|
||||||
|
|
||||||
|
/* Clear reserved. */
|
||||||
|
out->reserved = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MakeGetMaxProtocolVersionHeader(Header *out) {
|
void MakeGetMaxProtocolVersionHeader(Header *out) {
|
||||||
|
@ -111,6 +114,14 @@ namespace ams::htcfs {
|
||||||
void MakeSetProtocolVersionHeader(Header *out, s16 version) {
|
void MakeSetProtocolVersionHeader(Header *out, s16 version) {
|
||||||
return this->MakeRequestHeader(out, PacketType::SetProtocolVersion, 0, version);
|
return this->MakeRequestHeader(out, PacketType::SetProtocolVersion, 0, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MakeOpenDirectoryHeader(Header *out, int path_len, fs::OpenDirectoryMode mode, bool case_sensitive) {
|
||||||
|
return this->MakeRequestHeader(out, PacketType::OpenDirectory, path_len, static_cast<s64>(mode), case_sensitive ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MakeCloseDirectoryHeader(Header *out, s32 handle) {
|
||||||
|
return this->MakeRequestHeader(out, PacketType::CloseDirectory, 0, handle);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,12 +22,16 @@ namespace ams::htcfs {
|
||||||
|
|
||||||
R_DEFINE_ERROR_RESULT(InvalidArgument, 3);
|
R_DEFINE_ERROR_RESULT(InvalidArgument, 3);
|
||||||
|
|
||||||
|
|
||||||
|
R_DEFINE_ERROR_RANGE(ConnectionFailure, 100, 199);
|
||||||
R_DEFINE_ERROR_RESULT(HtclowChannelClosed, 101);
|
R_DEFINE_ERROR_RESULT(HtclowChannelClosed, 101);
|
||||||
|
|
||||||
|
R_DEFINE_ERROR_RANGE(UnexpectedResponse, 110, 119);
|
||||||
R_DEFINE_ERROR_RESULT(UnexpectedResponseProtocolId, 111);
|
R_DEFINE_ERROR_RESULT(UnexpectedResponseProtocolId, 111);
|
||||||
R_DEFINE_ERROR_RESULT(UnexpectedResponseProtocolVersion, 112);
|
R_DEFINE_ERROR_RESULT(UnexpectedResponseProtocolVersion, 112);
|
||||||
R_DEFINE_ERROR_RESULT(UnexpectedResponsePacketCategory, 113);
|
R_DEFINE_ERROR_RESULT(UnexpectedResponsePacketCategory, 113);
|
||||||
R_DEFINE_ERROR_RESULT(UnexpectedResponsePacketType, 114);
|
R_DEFINE_ERROR_RESULT(UnexpectedResponsePacketType, 114);
|
||||||
|
R_DEFINE_ERROR_RESULT(UnexpectedResponseBodySize, 115);
|
||||||
|
|
||||||
R_DEFINE_ERROR_RESULT(UnknownError, 211);
|
R_DEFINE_ERROR_RESULT(UnknownError, 211);
|
||||||
R_DEFINE_ERROR_RESULT(UnsupportedProtocolVersion, 212);
|
R_DEFINE_ERROR_RESULT(UnsupportedProtocolVersion, 212);
|
||||||
|
|
Loading…
Reference in a new issue