From 12dc05032b1c8dfdb000faf1ec883abff045cede Mon Sep 17 00:00:00 2001 From: FearlessTobi Date: Sun, 7 Aug 2022 23:54:51 +0200 Subject: [PATCH 1/3] ldn: Add better stubs and more data types Co-Authored-By: Narr the Reg <5944268+german77@users.noreply.github.com> Co-Authored-By: Morph <39850852+Morph1984@users.noreply.github.com> --- src/core/CMakeLists.txt | 3 +- src/core/hle/service/ldn/errors.h | 12 - src/core/hle/service/ldn/ldn.cpp | 433 +++++++++++++++++++++---- src/core/hle/service/ldn/ldn.h | 73 +++++ src/core/hle/service/ldn/ldn_results.h | 28 ++ src/core/hle/service/ldn/ldn_types.h | 298 +++++++++++++++++ 6 files changed, 774 insertions(+), 73 deletions(-) delete mode 100644 src/core/hle/service/ldn/errors.h create mode 100644 src/core/hle/service/ldn/ldn_results.h create mode 100644 src/core/hle/service/ldn/ldn_types.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 9dbe5bdca..d314ff1ce 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -504,9 +504,10 @@ add_library(core STATIC hle/service/jit/jit.h hle/service/lbl/lbl.cpp hle/service/lbl/lbl.h - hle/service/ldn/errors.h + hle/service/ldn/ldn_results.h hle/service/ldn/ldn.cpp hle/service/ldn/ldn.h + hle/service/ldn/ldn_types.h hle/service/ldr/ldr.cpp hle/service/ldr/ldr.h hle/service/lm/lm.cpp diff --git a/src/core/hle/service/ldn/errors.h b/src/core/hle/service/ldn/errors.h deleted file mode 100644 index 972a74806..000000000 --- a/src/core/hle/service/ldn/errors.h +++ /dev/null @@ -1,12 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "core/hle/result.h" - -namespace Service::LDN { - -constexpr Result ERROR_DISABLED{ErrorModule::LDN, 22}; - -} // namespace Service::LDN diff --git a/src/core/hle/service/ldn/ldn.cpp b/src/core/hle/service/ldn/ldn.cpp index 125d4dc4c..c8e1898f4 100644 --- a/src/core/hle/service/ldn/ldn.cpp +++ b/src/core/hle/service/ldn/ldn.cpp @@ -3,11 +3,12 @@ #include -#include "core/hle/ipc_helpers.h" -#include "core/hle/result.h" -#include "core/hle/service/ldn/errors.h" +#include "core/core.h" #include "core/hle/service/ldn/ldn.h" -#include "core/hle/service/sm/sm.h" +#include "core/internal_network/network.h" +#include "core/internal_network/network_interface.h" + +#undef CreateEvent namespace Service::LDN { @@ -96,81 +97,393 @@ public: } }; -class IUserLocalCommunicationService final - : public ServiceFramework { -public: - explicit IUserLocalCommunicationService(Core::System& system_) - : ServiceFramework{system_, "IUserLocalCommunicationService"} { - // clang-format off +IUserLocalCommunicationService::IUserLocalCommunicationService(Core::System& system_) + : ServiceFramework{system_, "IUserLocalCommunicationService", ServiceThreadType::CreateNew}, + service_context{system, "IUserLocalCommunicationService"}, room_network{ + system_.GetRoomNetwork()} { + // clang-format off static const FunctionInfo functions[] = { {0, &IUserLocalCommunicationService::GetState, "GetState"}, - {1, nullptr, "GetNetworkInfo"}, + {1, &IUserLocalCommunicationService::GetNetworkInfo, "GetNetworkInfo"}, {2, nullptr, "GetIpv4Address"}, - {3, nullptr, "GetDisconnectReason"}, - {4, nullptr, "GetSecurityParameter"}, - {5, nullptr, "GetNetworkConfig"}, - {100, nullptr, "AttachStateChangeEvent"}, - {101, nullptr, "GetNetworkInfoLatestUpdate"}, - {102, nullptr, "Scan"}, - {103, nullptr, "ScanPrivate"}, + {3, &IUserLocalCommunicationService::GetDisconnectReason, "GetDisconnectReason"}, + {4, &IUserLocalCommunicationService::GetSecurityParameter, "GetSecurityParameter"}, + {5, &IUserLocalCommunicationService::GetNetworkConfig, "GetNetworkConfig"}, + {100, &IUserLocalCommunicationService::AttachStateChangeEvent, "AttachStateChangeEvent"}, + {101, &IUserLocalCommunicationService::GetNetworkInfoLatestUpdate, "GetNetworkInfoLatestUpdate"}, + {102, &IUserLocalCommunicationService::Scan, "Scan"}, + {103, &IUserLocalCommunicationService::ScanPrivate, "ScanPrivate"}, {104, nullptr, "SetWirelessControllerRestriction"}, - {200, nullptr, "OpenAccessPoint"}, - {201, nullptr, "CloseAccessPoint"}, - {202, nullptr, "CreateNetwork"}, - {203, nullptr, "CreateNetworkPrivate"}, - {204, nullptr, "DestroyNetwork"}, + {200, &IUserLocalCommunicationService::OpenAccessPoint, "OpenAccessPoint"}, + {201, &IUserLocalCommunicationService::CloseAccessPoint, "CloseAccessPoint"}, + {202, &IUserLocalCommunicationService::CreateNetwork, "CreateNetwork"}, + {203, &IUserLocalCommunicationService::CreateNetworkPrivate, "CreateNetworkPrivate"}, + {204, &IUserLocalCommunicationService::DestroyNetwork, "DestroyNetwork"}, {205, nullptr, "Reject"}, - {206, nullptr, "SetAdvertiseData"}, - {207, nullptr, "SetStationAcceptPolicy"}, - {208, nullptr, "AddAcceptFilterEntry"}, + {206, &IUserLocalCommunicationService::SetAdvertiseData, "SetAdvertiseData"}, + {207, &IUserLocalCommunicationService::SetStationAcceptPolicy, "SetStationAcceptPolicy"}, + {208, &IUserLocalCommunicationService::AddAcceptFilterEntry, "AddAcceptFilterEntry"}, {209, nullptr, "ClearAcceptFilter"}, - {300, nullptr, "OpenStation"}, - {301, nullptr, "CloseStation"}, - {302, nullptr, "Connect"}, + {300, &IUserLocalCommunicationService::OpenStation, "OpenStation"}, + {301, &IUserLocalCommunicationService::CloseStation, "CloseStation"}, + {302, &IUserLocalCommunicationService::Connect, "Connect"}, {303, nullptr, "ConnectPrivate"}, - {304, nullptr, "Disconnect"}, - {400, nullptr, "Initialize"}, - {401, nullptr, "Finalize"}, - {402, &IUserLocalCommunicationService::Initialize2, "Initialize2"}, // 7.0.0+ + {304, &IUserLocalCommunicationService::Disconnect, "Disconnect"}, + {400, &IUserLocalCommunicationService::Initialize, "Initialize"}, + {401, &IUserLocalCommunicationService::Finalize, "Finalize"}, + {402, &IUserLocalCommunicationService::Initialize2, "Initialize2"}, }; - // clang-format on + // clang-format on - RegisterHandlers(functions); - } + RegisterHandlers(functions); - void GetState(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_LDN, "(STUBBED) called"); + state_change_event = + service_context.CreateEvent("IUserLocalCommunicationService:StateChangeEvent"); +} - IPC::ResponseBuilder rb{ctx, 3}; +IUserLocalCommunicationService::~IUserLocalCommunicationService() { + service_context.CloseEvent(state_change_event); +} - // Indicate a network error, as we do not actually emulate LDN - rb.Push(static_cast(State::Error)); +void IUserLocalCommunicationService::OnEventFired() { + state_change_event->GetWritableEvent().Signal(); +} - rb.Push(ResultSuccess); - } +void IUserLocalCommunicationService::GetState(Kernel::HLERequestContext& ctx) { + State state = State::Error; + LOG_WARNING(Service_LDN, "(STUBBED) called, state = {}", state); - void Initialize2(Kernel::HLERequestContext& ctx) { - LOG_DEBUG(Service_LDN, "called"); + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.PushEnum(state); +} - is_initialized = true; +void IUserLocalCommunicationService::GetNetworkInfo(Kernel::HLERequestContext& ctx) { + const auto write_buffer_size = ctx.GetWriteBufferSize(); + if (write_buffer_size != sizeof(NetworkInfo)) { + LOG_ERROR(Service_LDN, "Invalid buffer size {}", write_buffer_size); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERROR_DISABLED); + rb.Push(ResultBadInput); + return; } -private: - enum class State { - None, - Initialized, - AccessPointOpened, - AccessPointCreated, - StationOpened, - StationConnected, - Error, - }; + NetworkInfo networkInfo{}; + const auto rc = ResultSuccess; + if (rc.IsError()) { + LOG_ERROR(Service_LDN, "NetworkInfo is not valid {}", rc.raw); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(rc); + return; + } - bool is_initialized{}; -}; + LOG_WARNING(Service_LDN, "(STUBBED) called, ssid='{}', nodes={}", + networkInfo.common.ssid.GetStringValue(), networkInfo.ldn.node_count); + + ctx.WriteBuffer(networkInfo); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(rc); +} + +void IUserLocalCommunicationService::GetDisconnectReason(Kernel::HLERequestContext& ctx) { + const auto disconnect_reason = DisconnectReason::None; + + LOG_WARNING(Service_LDN, "(STUBBED) called, disconnect_reason={}", disconnect_reason); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.PushEnum(disconnect_reason); +} + +void IUserLocalCommunicationService::GetSecurityParameter(Kernel::HLERequestContext& ctx) { + SecurityParameter security_parameter; + NetworkInfo info; + const Result rc = ResultSuccess; + + if (rc.IsError()) { + LOG_ERROR(Service_LDN, "NetworkInfo is not valid {}", rc.raw); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(rc); + return; + } + + security_parameter.session_id = info.network_id.session_id; + std::memcpy(security_parameter.data.data(), info.ldn.security_parameter.data(), + sizeof(SecurityParameter::data)); + + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 10}; + rb.Push(rc); + rb.PushRaw(security_parameter); +} + +void IUserLocalCommunicationService::GetNetworkConfig(Kernel::HLERequestContext& ctx) { + NetworkConfig config; + NetworkInfo info; + const Result rc = ResultSuccess; + + if (rc.IsError()) { + LOG_ERROR(Service_LDN, "NetworkConfig is not valid {}", rc.raw); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(rc); + return; + } + + config.intent_id = info.network_id.intent_id; + config.channel = info.common.channel; + config.node_count_max = info.ldn.node_count_max; + config.local_communication_version = info.ldn.nodes[0].local_communication_version; + + LOG_WARNING(Service_LDN, + "(STUBBED) called, intent_id={}/{}, channel={}, node_count_max={}, " + "local_communication_version={}", + config.intent_id.local_communication_id, config.intent_id.scene_id, config.channel, + config.node_count_max, config.local_communication_version); + + IPC::ResponseBuilder rb{ctx, 10}; + rb.Push(rc); + rb.PushRaw(config); +} + +void IUserLocalCommunicationService::AttachStateChangeEvent(Kernel::HLERequestContext& ctx) { + LOG_INFO(Service_LDN, "called"); + + IPC::ResponseBuilder rb{ctx, 2, 1}; + rb.Push(ResultSuccess); + rb.PushCopyObjects(state_change_event->GetReadableEvent()); +} + +void IUserLocalCommunicationService::GetNetworkInfoLatestUpdate(Kernel::HLERequestContext& ctx) { + const std::size_t network_buffer_size = ctx.GetWriteBufferSize(0); + const std::size_t node_buffer_count = ctx.GetWriteBufferSize(1) / sizeof(NodeLatestUpdate); + + if (node_buffer_count == 0 || network_buffer_size != sizeof(NetworkInfo)) { + LOG_ERROR(Service_LDN, "Invalid buffer size {}, {}", network_buffer_size, + node_buffer_count); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultBadInput); + return; + } + + NetworkInfo info; + std::vector latest_update{}; + latest_update.resize(node_buffer_count); + + const auto rc = ResultSuccess; + if (rc.IsError()) { + LOG_ERROR(Service_LDN, "NetworkInfo is not valid {}", rc.raw); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(rc); + return; + } + + LOG_WARNING(Service_LDN, "(STUBBED) called, ssid='{}', nodes={}", + info.common.ssid.GetStringValue(), info.ldn.node_count); + + ctx.WriteBuffer(info, 0); + ctx.WriteBuffer(latest_update, 1); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void IUserLocalCommunicationService::Scan(Kernel::HLERequestContext& ctx) { + ScanImpl(ctx); +} + +void IUserLocalCommunicationService::ScanPrivate(Kernel::HLERequestContext& ctx) { + ScanImpl(ctx, true); +} + +void IUserLocalCommunicationService::ScanImpl(Kernel::HLERequestContext& ctx, bool is_private) { + IPC::RequestParser rp{ctx}; + const auto channel{rp.PopEnum()}; + const auto scan_filter{rp.PopRaw()}; + + const std::size_t network_info_size = ctx.GetWriteBufferSize() / sizeof(NetworkInfo); + + if (network_info_size == 0) { + LOG_ERROR(Service_LDN, "Invalid buffer size {}", network_info_size); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultBadInput); + return; + } + + u16 count = 0; + std::vector networks_info{}; + networks_info.resize(network_info_size); + + LOG_WARNING(Service_LDN, + "(STUBBED) called, channel={}, filter_scan_flag={}, filter_network_type={}", + channel, scan_filter.flag, scan_filter.network_type); + + ctx.WriteBuffer(networks_info); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(count); +} + +void IUserLocalCommunicationService::OpenAccessPoint(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void IUserLocalCommunicationService::CloseAccessPoint(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void IUserLocalCommunicationService::CreateNetwork(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + CreateNetworkImpl(ctx, false); +} + +void IUserLocalCommunicationService::CreateNetworkPrivate(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + CreateNetworkImpl(ctx, true); +} + +void IUserLocalCommunicationService::CreateNetworkImpl(Kernel::HLERequestContext& ctx, + bool is_private) { + IPC::RequestParser rp{ctx}; + + const auto security_config{rp.PopRaw()}; + [[maybe_unused]] const auto security_parameter{is_private ? rp.PopRaw() + : SecurityParameter{}}; + const auto user_config{rp.PopRaw()}; + rp.Pop(); // Padding + const auto network_Config{rp.PopRaw()}; + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} +void IUserLocalCommunicationService::DestroyNetwork(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void IUserLocalCommunicationService::SetAdvertiseData(Kernel::HLERequestContext& ctx) { + std::vector read_buffer = ctx.ReadBuffer(); + + LOG_WARNING(Service_LDN, "(STUBBED) called, size {}", read_buffer.size()); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void IUserLocalCommunicationService::SetStationAcceptPolicy(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void IUserLocalCommunicationService::AddAcceptFilterEntry(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void IUserLocalCommunicationService::OpenStation(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void IUserLocalCommunicationService::CloseStation(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void IUserLocalCommunicationService::Connect(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + IPC::RequestParser rp{ctx}; + + [[maybe_unused]] const auto securityConfig{rp.PopRaw()}; + const auto user_config{rp.PopRaw()}; + const auto local_communication_version{rp.Pop()}; + [[maybe_unused]] const auto option{rp.Pop()}; + + std::vector read_buffer = ctx.ReadBuffer(); + NetworkInfo networkInfo{}; + + if (read_buffer.size() != sizeof(NetworkInfo)) { + LOG_ERROR(Frontend, "NetworkInfo doesn't match read_buffer size!"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultBadInput); + return; + } + + std::memcpy(&networkInfo, read_buffer.data(), read_buffer.size()); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void IUserLocalCommunicationService::Disconnect(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} +void IUserLocalCommunicationService::Initialize(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + const auto rc = InitializeImpl(ctx); + if (rc.IsError()) { + LOG_ERROR(Service_LDN, "Network isn't initialized, rc={}", rc.raw); + } + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(rc); +} + +void IUserLocalCommunicationService::Finalize(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + is_initialized = false; + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + +void IUserLocalCommunicationService::Initialize2(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + const auto rc = InitializeImpl(ctx); + if (rc.IsError()) { + LOG_ERROR(Service_LDN, "Network isn't initialized, rc={}", rc.raw); + } + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(rc); +} + +Result IUserLocalCommunicationService::InitializeImpl(Kernel::HLERequestContext& ctx) { + const auto network_interface = Network::GetSelectedNetworkInterface(); + if (!network_interface) { + return ResultAirplaneModeEnabled; + } + + is_initialized = true; + // TODO (flTobi): Change this to ResultSuccess when LDN is fully implemented + return ResultAirplaneModeEnabled; +} class LDNS final : public ServiceFramework { public: @@ -273,7 +586,7 @@ public: LOG_WARNING(Service_LDN, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERROR_DISABLED); + rb.Push(ResultDisabled); } }; diff --git a/src/core/hle/service/ldn/ldn.h b/src/core/hle/service/ldn/ldn.h index a0031ac71..331455e3f 100644 --- a/src/core/hle/service/ldn/ldn.h +++ b/src/core/hle/service/ldn/ldn.h @@ -3,6 +3,14 @@ #pragma once +#include "core/hle/ipc_helpers.h" +#include "core/hle/kernel/k_event.h" +#include "core/hle/result.h" +#include "core/hle/service/kernel_helpers.h" +#include "core/hle/service/ldn/ldn_results.h" +#include "core/hle/service/ldn/ldn_types.h" +#include "core/hle/service/sm/sm.h" + namespace Core { class System; } @@ -16,4 +24,69 @@ namespace Service::LDN { /// Registers all LDN services with the specified service manager. void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); +class IUserLocalCommunicationService final + : public ServiceFramework { +public: + explicit IUserLocalCommunicationService(Core::System& system_); + ~IUserLocalCommunicationService() override; + + void GetState(Kernel::HLERequestContext& ctx); + + void GetNetworkInfo(Kernel::HLERequestContext& ctx); + + void GetDisconnectReason(Kernel::HLERequestContext& ctx); + + void GetSecurityParameter(Kernel::HLERequestContext& ctx); + + void GetNetworkConfig(Kernel::HLERequestContext& ctx); + + void AttachStateChangeEvent(Kernel::HLERequestContext& ctx); + + void GetNetworkInfoLatestUpdate(Kernel::HLERequestContext& ctx); + + void Scan(Kernel::HLERequestContext& ctx); + void ScanPrivate(Kernel::HLERequestContext& ctx); + void ScanImpl(Kernel::HLERequestContext& ctx, bool is_private = false); + + void OpenAccessPoint(Kernel::HLERequestContext& ctx); + + void CloseAccessPoint(Kernel::HLERequestContext& ctx); + + void CreateNetwork(Kernel::HLERequestContext& ctx); + void CreateNetworkPrivate(Kernel::HLERequestContext& ctx); + void CreateNetworkImpl(Kernel::HLERequestContext& ctx, bool is_private); + + void DestroyNetwork(Kernel::HLERequestContext& ctx); + + void SetAdvertiseData(Kernel::HLERequestContext& ctx); + + void SetStationAcceptPolicy(Kernel::HLERequestContext& ctx); + + void AddAcceptFilterEntry(Kernel::HLERequestContext& ctx); + + void OpenStation(Kernel::HLERequestContext& ctx); + + void CloseStation(Kernel::HLERequestContext& ctx); + + void Disconnect(Kernel::HLERequestContext& ctx); + + void Connect(Kernel::HLERequestContext& ctx); + + void Initialize(Kernel::HLERequestContext& ctx); + + void Finalize(Kernel::HLERequestContext& ctx); + + void Initialize2(Kernel::HLERequestContext& ctx); + Result InitializeImpl(Kernel::HLERequestContext& ctx); + +private: + void OnEventFired(); + + KernelHelpers::ServiceContext service_context; + Kernel::KEvent* state_change_event; + Network::RoomNetwork& room_network; + + bool is_initialized{}; +}; + } // namespace Service::LDN diff --git a/src/core/hle/service/ldn/ldn_results.h b/src/core/hle/service/ldn/ldn_results.h new file mode 100644 index 000000000..8b6b436b7 --- /dev/null +++ b/src/core/hle/service/ldn/ldn_results.h @@ -0,0 +1,28 @@ +// Copyright 2022 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/result.h" + +namespace Service::LDN { + +constexpr Result ResultAdvertiseDataTooLarge{ErrorModule::LDN, 10}; +constexpr Result ResultAuthenticationFailed{ErrorModule::LDN, 20}; +constexpr Result ResultDisabled{ErrorModule::LDN, 22}; +constexpr Result ResultAirplaneModeEnabled{ErrorModule::LDN, 23}; +constexpr Result ResultInvalidNodeCount{ErrorModule::LDN, 30}; +constexpr Result ResultConnectionFailed{ErrorModule::LDN, 31}; +constexpr Result ResultBadState{ErrorModule::LDN, 32}; +constexpr Result ResultNoIpAddress{ErrorModule::LDN, 33}; +constexpr Result ResultInvalidBufferCount{ErrorModule::LDN, 50}; +constexpr Result ResultAccessPointConnectionFailed{ErrorModule::LDN, 65}; +constexpr Result ResultAuthenticationTimeout{ErrorModule::LDN, 66}; +constexpr Result ResultMaximumNodeCount{ErrorModule::LDN, 67}; +constexpr Result ResultBadInput{ErrorModule::LDN, 96}; +constexpr Result ResultLocalCommunicationIdNotFound{ErrorModule::LDN, 97}; +constexpr Result ResultLocalCommunicationVersionTooLow{ErrorModule::LDN, 113}; +constexpr Result ResultLocalCommunicationVersionTooHigh{ErrorModule::LDN, 114}; + +} // namespace Service::LDN diff --git a/src/core/hle/service/ldn/ldn_types.h b/src/core/hle/service/ldn/ldn_types.h new file mode 100644 index 000000000..1132b2eb6 --- /dev/null +++ b/src/core/hle/service/ldn/ldn_types.h @@ -0,0 +1,298 @@ +// Copyright 2022 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include + +#include "common/common_funcs.h" +#include "common/common_types.h" +#include "network/network.h" + +namespace Service::LDN { + +constexpr size_t SsidLengthMax = 32; +constexpr size_t AdvertiseDataSizeMax = 384; +constexpr size_t UserNameBytesMax = 32; +constexpr int NodeCountMax = 8; +constexpr int StationCountMax = NodeCountMax - 1; +constexpr size_t PassphraseLengthMax = 64; + +enum class SecurityMode : u16 { + All, + Retail, + Debug, +}; + +enum class NodeStateChange : u8 { + None, + Connect, + Disconnect, + DisconnectAndConnect, +}; + +inline NodeStateChange operator|(NodeStateChange a, NodeStateChange b) { + return static_cast(static_cast(a) | static_cast(b)); +} + +inline NodeStateChange operator|=(NodeStateChange& a, NodeStateChange b) { + return a = a | b; +} + +enum class ScanFilterFlag : u32 { + None = 0, + LocalCommunicationId = 1 << 0, + SessionId = 1 << 1, + NetworkType = 1 << 2, + Ssid = 1 << 4, + SceneId = 1 << 5, + IntentId = LocalCommunicationId | SceneId, + NetworkId = IntentId | SessionId, +}; + +enum class NetworkType : u32 { + None, + General, + Ldn, + All, +}; + +enum class PackedNetworkType : u8 { + None, + General, + Ldn, + All, +}; + +enum class State : u32 { + None, + Initialized, + AccessPointOpened, + AccessPointCreated, + StationOpened, + StationConnected, + Error, +}; + +enum class DisconnectReason : s16 { + Unknown = -1, + None, + DisconnectedByUser, + DisconnectedBySystem, + DestroyedByUser, + DestroyedBySystem, + Rejected, + SignalLost, +}; + +enum class NetworkError { + Unknown = -1, + None = 0, + PortUnreachable, + TooManyPlayers, + VersionTooLow, + VersionTooHigh, + ConnectFailure, + ConnectNotFound, + ConnectTimeout, + ConnectRejected, + RejectFailed, +}; + +enum class AcceptPolicy : u8 { + AcceptAll, + RejectAll, + BlackList, + WhiteList, +}; + +enum class WifiChannel : s16 { + Default = 0, + wifi24_1 = 1, + wifi24_6 = 6, + wifi24_11 = 11, + wifi50_36 = 36, + wifi50_40 = 40, + wifi50_44 = 44, + wifi50_48 = 48, +}; + +enum class LinkLevel : s8 { + Bad, + Low, + Good, + Excelent, +}; + +struct NodeLatestUpdate { + NodeStateChange state_change; + INSERT_PADDING_BYTES(0x7); // Unknown +}; +static_assert(sizeof(NodeLatestUpdate) == 0x8, "NodeLatestUpdate is an invalid size"); + +struct SessionId { + u64 high; + u64 low; + +public: + bool operator==(const SessionId& b) const { + return (low == b.low) && (high == b.high); + } +}; +static_assert(sizeof(SessionId) == 0x10, "SessionId is an invalid size"); + +struct IntentId { + u64 local_communication_id; + INSERT_PADDING_BYTES(0x2); // Reserved + u16 scene_id; + INSERT_PADDING_BYTES(0x4); // Reserved +}; +static_assert(sizeof(IntentId) == 0x10, "IntentId is an invalid size"); + +struct NetworkId { + IntentId intent_id; + SessionId session_id; +}; +static_assert(sizeof(NetworkId) == 0x20, "NetworkId is an invalid size"); + +struct Ssid { + u8 length; + std::array raw; + +public: + std::string GetStringValue() const { + return std::string(raw.data(), length); + } +}; +static_assert(sizeof(Ssid) == 0x22, "Ssid is an invalid size"); + +struct Ipv4Address { + union { + u32 raw{}; + std::array bytes; + }; + +public: + std::string GetStringValue() const { + return fmt::format("{}.{}.{}.{}", bytes[3], bytes[2], bytes[1], bytes[0]); + } +}; +static_assert(sizeof(Ipv4Address) == 0x4, "Ipv4Address is an invalid size"); + +struct MacAddress { + std::array raw{}; + + friend bool operator==(const MacAddress& lhs, const MacAddress& rhs) = default; +}; +static_assert(sizeof(MacAddress) == 0x6, "MacAddress is an invalid size"); + +struct ScanFilter { + NetworkId network_id; + NetworkType network_type; + MacAddress mac_address; + Ssid ssid; + INSERT_PADDING_BYTES(0x10); + ScanFilterFlag flag; +}; +static_assert(sizeof(ScanFilter) == 0x60, "ScanFilter is an invalid size"); + +struct CommonNetworkInfo { + MacAddress bssid; + Ssid ssid; + WifiChannel channel; + LinkLevel link_level; + PackedNetworkType network_type; + INSERT_PADDING_BYTES(0x4); +}; +static_assert(sizeof(CommonNetworkInfo) == 0x30, "CommonNetworkInfo is an invalid size"); + +struct NodeInfo { + Ipv4Address ipv4_address; + MacAddress mac_address; + s8 node_id; + u8 is_connected; + std::array user_name; + INSERT_PADDING_BYTES(0x1); // Reserved + s16 local_communication_version; + INSERT_PADDING_BYTES(0x10); // Reserved +}; +static_assert(sizeof(NodeInfo) == 0x40, "NodeInfo is an invalid size"); + +struct LdnNetworkInfo { + std::array security_parameter; + SecurityMode security_mode; + AcceptPolicy station_accept_policy; + u8 has_action_frame; + INSERT_PADDING_BYTES(0x2); // Padding + u8 node_count_max; + u8 node_count; + std::array nodes; + INSERT_PADDING_BYTES(0x2); // Reserved + u16 advertise_data_size; + std::array advertise_data; + INSERT_PADDING_BYTES(0x8C); // Reserved + u64 random_authentication_id; +}; +static_assert(sizeof(LdnNetworkInfo) == 0x430, "LdnNetworkInfo is an invalid size"); + +struct NetworkInfo { + NetworkId network_id; + CommonNetworkInfo common; + LdnNetworkInfo ldn; +}; +static_assert(sizeof(NetworkInfo) == 0x480, "NetworkInfo is an invalid size"); + +struct SecurityConfig { + SecurityMode security_mode; + u16 passphrase_size; + std::array passphrase; +}; +static_assert(sizeof(SecurityConfig) == 0x44, "SecurityConfig is an invalid size"); + +struct UserConfig { + std::array user_name; + INSERT_PADDING_BYTES(0xF); // Reserved +}; +static_assert(sizeof(UserConfig) == 0x30, "UserConfig is an invalid size"); + +#pragma pack(push, 4) +struct ConnectRequest { + SecurityConfig security_config; + UserConfig user_config; + u32 local_communication_version; + u32 option_unknown; + NetworkInfo network_info; +}; +static_assert(sizeof(ConnectRequest) == 0x4FC, "ConnectRequest is an invalid size"); +#pragma pack(pop) + +struct SecurityParameter { + std::array data; // Data, used with the same key derivation as SecurityConfig + SessionId session_id; +}; +static_assert(sizeof(SecurityParameter) == 0x20, "SecurityParameter is an invalid size"); + +struct NetworkConfig { + IntentId intent_id; + WifiChannel channel; + u8 node_count_max; + INSERT_PADDING_BYTES(0x1); // Reserved + u16 local_communication_version; + INSERT_PADDING_BYTES(0xA); // Reserved +}; +static_assert(sizeof(NetworkConfig) == 0x20, "NetworkConfig is an invalid size"); + +struct AddressEntry { + Ipv4Address ipv4_address; + MacAddress mac_address; + INSERT_PADDING_BYTES(0x2); // Reserved +}; +static_assert(sizeof(AddressEntry) == 0xC, "AddressEntry is an invalid size"); + +struct AddressList { + std::array addresses; +}; +static_assert(sizeof(AddressList) == 0x60, "AddressList is an invalid size"); + +} // namespace Service::LDN From 8eb2c73381c2ed35767b51fde4102ec31d5ab5a1 Mon Sep 17 00:00:00 2001 From: Narr the Reg Date: Mon, 8 Aug 2022 12:49:48 -0500 Subject: [PATCH 2/3] core: ldn: Address review comments --- src/core/hle/service/ldn/ldn.cpp | 86 ++++++++++++++------------ src/core/hle/service/ldn/ldn.h | 1 - src/core/hle/service/ldn/ldn_results.h | 5 +- src/core/hle/service/ldn/ldn_types.h | 20 +----- 4 files changed, 51 insertions(+), 61 deletions(-) diff --git a/src/core/hle/service/ldn/ldn.cpp b/src/core/hle/service/ldn/ldn.cpp index c8e1898f4..ff4169f8e 100644 --- a/src/core/hle/service/ldn/ldn.cpp +++ b/src/core/hle/service/ldn/ldn.cpp @@ -8,6 +8,7 @@ #include "core/internal_network/network.h" #include "core/internal_network/network_interface.h" +// This is defined by synchapi.h and conflicts with ServiceContext::CreateEvent #undef CreateEvent namespace Service::LDN { @@ -168,7 +169,7 @@ void IUserLocalCommunicationService::GetNetworkInfo(Kernel::HLERequestContext& c return; } - NetworkInfo networkInfo{}; + NetworkInfo network_info{}; const auto rc = ResultSuccess; if (rc.IsError()) { LOG_ERROR(Service_LDN, "NetworkInfo is not valid {}", rc.raw); @@ -178,9 +179,9 @@ void IUserLocalCommunicationService::GetNetworkInfo(Kernel::HLERequestContext& c } LOG_WARNING(Service_LDN, "(STUBBED) called, ssid='{}', nodes={}", - networkInfo.common.ssid.GetStringValue(), networkInfo.ldn.node_count); + network_info.common.ssid.GetStringValue(), network_info.ldn.node_count); - ctx.WriteBuffer(networkInfo); + ctx.WriteBuffer(network_info); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(rc); } @@ -267,8 +268,7 @@ void IUserLocalCommunicationService::GetNetworkInfoLatestUpdate(Kernel::HLEReque } NetworkInfo info; - std::vector latest_update{}; - latest_update.resize(node_buffer_count); + std::vector latest_update(node_buffer_count); const auto rc = ResultSuccess; if (rc.IsError()) { @@ -311,14 +311,13 @@ void IUserLocalCommunicationService::ScanImpl(Kernel::HLERequestContext& ctx, bo } u16 count = 0; - std::vector networks_info{}; - networks_info.resize(network_info_size); + std::vector network_infos(network_info_size); LOG_WARNING(Service_LDN, "(STUBBED) called, channel={}, filter_scan_flag={}, filter_network_type={}", channel, scan_filter.flag, scan_filter.network_type); - ctx.WriteBuffer(networks_info); + ctx.WriteBuffer(network_infos); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); @@ -340,31 +339,39 @@ void IUserLocalCommunicationService::CloseAccessPoint(Kernel::HLERequestContext& } void IUserLocalCommunicationService::CreateNetwork(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_LDN, "(STUBBED) called"); - - CreateNetworkImpl(ctx, false); -} - -void IUserLocalCommunicationService::CreateNetworkPrivate(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_LDN, "(STUBBED) called"); - - CreateNetworkImpl(ctx, true); -} - -void IUserLocalCommunicationService::CreateNetworkImpl(Kernel::HLERequestContext& ctx, - bool is_private) { IPC::RequestParser rp{ctx}; + struct Parameters { + SecurityConfig security_config; + UserConfig user_config; + INSERT_PADDING_WORDS_NOINIT(1); + NetworkConfig network_config; + }; + static_assert(sizeof(Parameters) == 0x98, "Parameters has incorrect size."); - const auto security_config{rp.PopRaw()}; - [[maybe_unused]] const auto security_parameter{is_private ? rp.PopRaw() - : SecurityParameter{}}; - const auto user_config{rp.PopRaw()}; - rp.Pop(); // Padding - const auto network_Config{rp.PopRaw()}; + LOG_WARNING(Service_LDN, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } + +void IUserLocalCommunicationService::CreateNetworkPrivate(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + struct Parameters { + SecurityConfig security_config; + SecurityParameter security_parameter; + UserConfig user_config; + NetworkConfig network_config; + }; + static_assert(sizeof(Parameters) == 0xB8, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw()}; + + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + void IUserLocalCommunicationService::DestroyNetwork(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service_LDN, "(STUBBED) called"); @@ -413,14 +420,18 @@ void IUserLocalCommunicationService::Connect(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service_LDN, "(STUBBED) called"); IPC::RequestParser rp{ctx}; + struct Parameters { + SecurityConfig security_config; + UserConfig user_config; + u32 local_communication_version; + u32 option; + }; + static_assert(sizeof(Parameters) == 0x7C, "Parameters has incorrect size."); - [[maybe_unused]] const auto securityConfig{rp.PopRaw()}; - const auto user_config{rp.PopRaw()}; - const auto local_communication_version{rp.Pop()}; - [[maybe_unused]] const auto option{rp.Pop()}; + const auto parameters{rp.PopRaw()}; - std::vector read_buffer = ctx.ReadBuffer(); - NetworkInfo networkInfo{}; + const std::vector read_buffer = ctx.ReadBuffer(); + NetworkInfo network_info{}; if (read_buffer.size() != sizeof(NetworkInfo)) { LOG_ERROR(Frontend, "NetworkInfo doesn't match read_buffer size!"); @@ -429,7 +440,7 @@ void IUserLocalCommunicationService::Connect(Kernel::HLERequestContext& ctx) { return; } - std::memcpy(&networkInfo, read_buffer.data(), read_buffer.size()); + std::memcpy(&network_info, read_buffer.data(), read_buffer.size()); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); @@ -445,9 +456,6 @@ void IUserLocalCommunicationService::Initialize(Kernel::HLERequestContext& ctx) LOG_WARNING(Service_LDN, "(STUBBED) called"); const auto rc = InitializeImpl(ctx); - if (rc.IsError()) { - LOG_ERROR(Service_LDN, "Network isn't initialized, rc={}", rc.raw); - } IPC::ResponseBuilder rb{ctx, 2}; rb.Push(rc); @@ -466,9 +474,6 @@ void IUserLocalCommunicationService::Initialize2(Kernel::HLERequestContext& ctx) LOG_WARNING(Service_LDN, "(STUBBED) called"); const auto rc = InitializeImpl(ctx); - if (rc.IsError()) { - LOG_ERROR(Service_LDN, "Network isn't initialized, rc={}", rc.raw); - } IPC::ResponseBuilder rb{ctx, 2}; rb.Push(rc); @@ -477,6 +482,7 @@ void IUserLocalCommunicationService::Initialize2(Kernel::HLERequestContext& ctx) Result IUserLocalCommunicationService::InitializeImpl(Kernel::HLERequestContext& ctx) { const auto network_interface = Network::GetSelectedNetworkInterface(); if (!network_interface) { + LOG_ERROR(Service_LDN, "No network interface is set"); return ResultAirplaneModeEnabled; } diff --git a/src/core/hle/service/ldn/ldn.h b/src/core/hle/service/ldn/ldn.h index 331455e3f..4ab8f7a9b 100644 --- a/src/core/hle/service/ldn/ldn.h +++ b/src/core/hle/service/ldn/ldn.h @@ -54,7 +54,6 @@ public: void CreateNetwork(Kernel::HLERequestContext& ctx); void CreateNetworkPrivate(Kernel::HLERequestContext& ctx); - void CreateNetworkImpl(Kernel::HLERequestContext& ctx, bool is_private); void DestroyNetwork(Kernel::HLERequestContext& ctx); diff --git a/src/core/hle/service/ldn/ldn_results.h b/src/core/hle/service/ldn/ldn_results.h index 8b6b436b7..f340bda42 100644 --- a/src/core/hle/service/ldn/ldn_results.h +++ b/src/core/hle/service/ldn/ldn_results.h @@ -1,6 +1,5 @@ -// Copyright 2022 yuzu Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. +// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later #pragma once diff --git a/src/core/hle/service/ldn/ldn_types.h b/src/core/hle/service/ldn/ldn_types.h index 1132b2eb6..0c07a7397 100644 --- a/src/core/hle/service/ldn/ldn_types.h +++ b/src/core/hle/service/ldn/ldn_types.h @@ -1,6 +1,5 @@ -// Copyright 2022 yuzu emulator team -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. +// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later #pragma once @@ -32,14 +31,6 @@ enum class NodeStateChange : u8 { DisconnectAndConnect, }; -inline NodeStateChange operator|(NodeStateChange a, NodeStateChange b) { - return static_cast(static_cast(a) | static_cast(b)); -} - -inline NodeStateChange operator|=(NodeStateChange& a, NodeStateChange b) { - return a = a | b; -} - enum class ScanFilterFlag : u32 { None = 0, LocalCommunicationId = 1 << 0, @@ -135,10 +126,7 @@ struct SessionId { u64 high; u64 low; -public: - bool operator==(const SessionId& b) const { - return (low == b.low) && (high == b.high); - } + bool operator==(const SessionId&) const = default; }; static_assert(sizeof(SessionId) == 0x10, "SessionId is an invalid size"); @@ -160,7 +148,6 @@ struct Ssid { u8 length; std::array raw; -public: std::string GetStringValue() const { return std::string(raw.data(), length); } @@ -173,7 +160,6 @@ struct Ipv4Address { std::array bytes; }; -public: std::string GetStringValue() const { return fmt::format("{}.{}.{}.{}", bytes[3], bytes[2], bytes[1], bytes[0]); } From 56115f7732e2b03b8122c10b3c3f69edb6ed7baa Mon Sep 17 00:00:00 2001 From: german77 Date: Thu, 11 Aug 2022 23:12:32 -0500 Subject: [PATCH 3/3] core: ldn: Address review comments part 2 --- src/core/hle/service/ldn/ldn.cpp | 691 ++++++++++++++++--------------- src/core/hle/service/ldn/ldn.h | 66 --- 2 files changed, 360 insertions(+), 397 deletions(-) diff --git a/src/core/hle/service/ldn/ldn.cpp b/src/core/hle/service/ldn/ldn.cpp index ff4169f8e..c11daff54 100644 --- a/src/core/hle/service/ldn/ldn.cpp +++ b/src/core/hle/service/ldn/ldn.cpp @@ -5,6 +5,8 @@ #include "core/core.h" #include "core/hle/service/ldn/ldn.h" +#include "core/hle/service/ldn/ldn_results.h" +#include "core/hle/service/ldn/ldn_types.h" #include "core/internal_network/network.h" #include "core/internal_network/network_interface.h" @@ -98,11 +100,14 @@ public: } }; -IUserLocalCommunicationService::IUserLocalCommunicationService(Core::System& system_) - : ServiceFramework{system_, "IUserLocalCommunicationService", ServiceThreadType::CreateNew}, - service_context{system, "IUserLocalCommunicationService"}, room_network{ - system_.GetRoomNetwork()} { - // clang-format off +class IUserLocalCommunicationService final + : public ServiceFramework { +public: + explicit IUserLocalCommunicationService(Core::System& system_) + : ServiceFramework{system_, "IUserLocalCommunicationService", ServiceThreadType::CreateNew}, + service_context{system, "IUserLocalCommunicationService"}, room_network{ + system_.GetRoomNetwork()} { + // clang-format off static const FunctionInfo functions[] = { {0, &IUserLocalCommunicationService::GetState, "GetState"}, {1, &IUserLocalCommunicationService::GetNetworkInfo, "GetNetworkInfo"}, @@ -134,362 +139,386 @@ IUserLocalCommunicationService::IUserLocalCommunicationService(Core::System& sys {401, &IUserLocalCommunicationService::Finalize, "Finalize"}, {402, &IUserLocalCommunicationService::Initialize2, "Initialize2"}, }; - // clang-format on + // clang-format on - RegisterHandlers(functions); + RegisterHandlers(functions); - state_change_event = - service_context.CreateEvent("IUserLocalCommunicationService:StateChangeEvent"); -} - -IUserLocalCommunicationService::~IUserLocalCommunicationService() { - service_context.CloseEvent(state_change_event); -} - -void IUserLocalCommunicationService::OnEventFired() { - state_change_event->GetWritableEvent().Signal(); -} - -void IUserLocalCommunicationService::GetState(Kernel::HLERequestContext& ctx) { - State state = State::Error; - LOG_WARNING(Service_LDN, "(STUBBED) called, state = {}", state); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.PushEnum(state); -} - -void IUserLocalCommunicationService::GetNetworkInfo(Kernel::HLERequestContext& ctx) { - const auto write_buffer_size = ctx.GetWriteBufferSize(); - - if (write_buffer_size != sizeof(NetworkInfo)) { - LOG_ERROR(Service_LDN, "Invalid buffer size {}", write_buffer_size); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultBadInput); - return; + state_change_event = + service_context.CreateEvent("IUserLocalCommunicationService:StateChangeEvent"); } - NetworkInfo network_info{}; - const auto rc = ResultSuccess; - if (rc.IsError()) { - LOG_ERROR(Service_LDN, "NetworkInfo is not valid {}", rc.raw); + ~IUserLocalCommunicationService() { + service_context.CloseEvent(state_change_event); + } + + void OnEventFired() { + state_change_event->GetWritableEvent().Signal(); + } + + void GetState(Kernel::HLERequestContext& ctx) { + State state = State::Error; + LOG_WARNING(Service_LDN, "(STUBBED) called, state = {}", state); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.PushEnum(state); + } + + void GetNetworkInfo(Kernel::HLERequestContext& ctx) { + const auto write_buffer_size = ctx.GetWriteBufferSize(); + + if (write_buffer_size != sizeof(NetworkInfo)) { + LOG_ERROR(Service_LDN, "Invalid buffer size {}", write_buffer_size); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultBadInput); + return; + } + + NetworkInfo network_info{}; + const auto rc = ResultSuccess; + if (rc.IsError()) { + LOG_ERROR(Service_LDN, "NetworkInfo is not valid {}", rc.raw); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(rc); + return; + } + + LOG_WARNING(Service_LDN, "(STUBBED) called, ssid='{}', nodes={}", + network_info.common.ssid.GetStringValue(), network_info.ldn.node_count); + + ctx.WriteBuffer(network_info); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(rc); - return; } - LOG_WARNING(Service_LDN, "(STUBBED) called, ssid='{}', nodes={}", - network_info.common.ssid.GetStringValue(), network_info.ldn.node_count); + void GetDisconnectReason(Kernel::HLERequestContext& ctx) { + const auto disconnect_reason = DisconnectReason::None; - ctx.WriteBuffer(network_info); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(rc); -} + LOG_WARNING(Service_LDN, "(STUBBED) called, disconnect_reason={}", disconnect_reason); -void IUserLocalCommunicationService::GetDisconnectReason(Kernel::HLERequestContext& ctx) { - const auto disconnect_reason = DisconnectReason::None; + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.PushEnum(disconnect_reason); + } - LOG_WARNING(Service_LDN, "(STUBBED) called, disconnect_reason={}", disconnect_reason); + void GetSecurityParameter(Kernel::HLERequestContext& ctx) { + SecurityParameter security_parameter{}; + NetworkInfo info{}; + const Result rc = ResultSuccess; - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.PushEnum(disconnect_reason); -} + if (rc.IsError()) { + LOG_ERROR(Service_LDN, "NetworkInfo is not valid {}", rc.raw); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(rc); + return; + } -void IUserLocalCommunicationService::GetSecurityParameter(Kernel::HLERequestContext& ctx) { - SecurityParameter security_parameter; - NetworkInfo info; - const Result rc = ResultSuccess; + security_parameter.session_id = info.network_id.session_id; + std::memcpy(security_parameter.data.data(), info.ldn.security_parameter.data(), + sizeof(SecurityParameter::data)); + + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 10}; + rb.Push(rc); + rb.PushRaw(security_parameter); + } + + void GetNetworkConfig(Kernel::HLERequestContext& ctx) { + NetworkConfig config{}; + NetworkInfo info{}; + const Result rc = ResultSuccess; + + if (rc.IsError()) { + LOG_ERROR(Service_LDN, "NetworkConfig is not valid {}", rc.raw); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(rc); + return; + } + + config.intent_id = info.network_id.intent_id; + config.channel = info.common.channel; + config.node_count_max = info.ldn.node_count_max; + config.local_communication_version = info.ldn.nodes[0].local_communication_version; + + LOG_WARNING(Service_LDN, + "(STUBBED) called, intent_id={}/{}, channel={}, node_count_max={}, " + "local_communication_version={}", + config.intent_id.local_communication_id, config.intent_id.scene_id, + config.channel, config.node_count_max, config.local_communication_version); + + IPC::ResponseBuilder rb{ctx, 10}; + rb.Push(rc); + rb.PushRaw(config); + } + + void AttachStateChangeEvent(Kernel::HLERequestContext& ctx) { + LOG_INFO(Service_LDN, "called"); + + IPC::ResponseBuilder rb{ctx, 2, 1}; + rb.Push(ResultSuccess); + rb.PushCopyObjects(state_change_event->GetReadableEvent()); + } + + void GetNetworkInfoLatestUpdate(Kernel::HLERequestContext& ctx) { + const std::size_t network_buffer_size = ctx.GetWriteBufferSize(0); + const std::size_t node_buffer_count = ctx.GetWriteBufferSize(1) / sizeof(NodeLatestUpdate); + + if (node_buffer_count == 0 || network_buffer_size != sizeof(NetworkInfo)) { + LOG_ERROR(Service_LDN, "Invalid buffer size {}, {}", network_buffer_size, + node_buffer_count); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultBadInput); + return; + } + + NetworkInfo info; + std::vector latest_update(node_buffer_count); + + const auto rc = ResultSuccess; + if (rc.IsError()) { + LOG_ERROR(Service_LDN, "NetworkInfo is not valid {}", rc.raw); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(rc); + return; + } + + LOG_WARNING(Service_LDN, "(STUBBED) called, ssid='{}', nodes={}", + info.common.ssid.GetStringValue(), info.ldn.node_count); + + ctx.WriteBuffer(info, 0); + ctx.WriteBuffer(latest_update, 1); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void Scan(Kernel::HLERequestContext& ctx) { + ScanImpl(ctx); + } + + void ScanPrivate(Kernel::HLERequestContext& ctx) { + ScanImpl(ctx, true); + } + + void ScanImpl(Kernel::HLERequestContext& ctx, bool is_private = false) { + IPC::RequestParser rp{ctx}; + const auto channel{rp.PopEnum()}; + const auto scan_filter{rp.PopRaw()}; + + const std::size_t network_info_size = ctx.GetWriteBufferSize() / sizeof(NetworkInfo); + + if (network_info_size == 0) { + LOG_ERROR(Service_LDN, "Invalid buffer size {}", network_info_size); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultBadInput); + return; + } + + u16 count = 0; + std::vector network_infos(network_info_size); + + LOG_WARNING(Service_LDN, + "(STUBBED) called, channel={}, filter_scan_flag={}, filter_network_type={}", + channel, scan_filter.flag, scan_filter.network_type); + + ctx.WriteBuffer(network_infos); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(count); + } + + void OpenAccessPoint(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void CloseAccessPoint(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void CreateNetwork(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + struct Parameters { + SecurityConfig security_config; + UserConfig user_config; + INSERT_PADDING_WORDS_NOINIT(1); + NetworkConfig network_config; + }; + static_assert(sizeof(Parameters) == 0x98, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw()}; + + LOG_WARNING(Service_LDN, + "(STUBBED) called, passphrase_size={}, security_mode={}, " + "local_communication_version={}", + parameters.security_config.passphrase_size, + parameters.security_config.security_mode, + parameters.network_config.local_communication_version); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void CreateNetworkPrivate(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + struct Parameters { + SecurityConfig security_config; + SecurityParameter security_parameter; + UserConfig user_config; + NetworkConfig network_config; + }; + static_assert(sizeof(Parameters) == 0xB8, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw()}; + + LOG_WARNING(Service_LDN, + "(STUBBED) called, passphrase_size={}, security_mode={}, " + "local_communication_version={}", + parameters.security_config.passphrase_size, + parameters.security_config.security_mode, + parameters.network_config.local_communication_version); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void DestroyNetwork(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void SetAdvertiseData(Kernel::HLERequestContext& ctx) { + std::vector read_buffer = ctx.ReadBuffer(); + + LOG_WARNING(Service_LDN, "(STUBBED) called, size {}", read_buffer.size()); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void SetStationAcceptPolicy(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void AddAcceptFilterEntry(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void OpenStation(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void CloseStation(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void Connect(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + struct Parameters { + SecurityConfig security_config; + UserConfig user_config; + u32 local_communication_version; + u32 option; + }; + static_assert(sizeof(Parameters) == 0x7C, "Parameters has incorrect size."); + + const auto parameters{rp.PopRaw()}; + + LOG_WARNING(Service_LDN, + "(STUBBED) called, passphrase_size={}, security_mode={}, " + "local_communication_version={}", + parameters.security_config.passphrase_size, + parameters.security_config.security_mode, + parameters.local_communication_version); + + const std::vector read_buffer = ctx.ReadBuffer(); + NetworkInfo network_info{}; + + if (read_buffer.size() != sizeof(NetworkInfo)) { + LOG_ERROR(Frontend, "NetworkInfo doesn't match read_buffer size!"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultBadInput); + return; + } + + std::memcpy(&network_info, read_buffer.data(), read_buffer.size()); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void Disconnect(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + void Initialize(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + const auto rc = InitializeImpl(ctx); - if (rc.IsError()) { - LOG_ERROR(Service_LDN, "NetworkInfo is not valid {}", rc.raw); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(rc); - return; } - security_parameter.session_id = info.network_id.session_id; - std::memcpy(security_parameter.data.data(), info.ldn.security_parameter.data(), - sizeof(SecurityParameter::data)); + void Finalize(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); - LOG_WARNING(Service_LDN, "(STUBBED) called"); + is_initialized = false; - IPC::ResponseBuilder rb{ctx, 10}; - rb.Push(rc); - rb.PushRaw(security_parameter); -} + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } -void IUserLocalCommunicationService::GetNetworkConfig(Kernel::HLERequestContext& ctx) { - NetworkConfig config; - NetworkInfo info; - const Result rc = ResultSuccess; + void Initialize2(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + const auto rc = InitializeImpl(ctx); - if (rc.IsError()) { - LOG_ERROR(Service_LDN, "NetworkConfig is not valid {}", rc.raw); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(rc); - return; } - config.intent_id = info.network_id.intent_id; - config.channel = info.common.channel; - config.node_count_max = info.ldn.node_count_max; - config.local_communication_version = info.ldn.nodes[0].local_communication_version; + Result InitializeImpl(Kernel::HLERequestContext& ctx) { + const auto network_interface = Network::GetSelectedNetworkInterface(); + if (!network_interface) { + LOG_ERROR(Service_LDN, "No network interface is set"); + return ResultAirplaneModeEnabled; + } - LOG_WARNING(Service_LDN, - "(STUBBED) called, intent_id={}/{}, channel={}, node_count_max={}, " - "local_communication_version={}", - config.intent_id.local_communication_id, config.intent_id.scene_id, config.channel, - config.node_count_max, config.local_communication_version); - - IPC::ResponseBuilder rb{ctx, 10}; - rb.Push(rc); - rb.PushRaw(config); -} - -void IUserLocalCommunicationService::AttachStateChangeEvent(Kernel::HLERequestContext& ctx) { - LOG_INFO(Service_LDN, "called"); - - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(ResultSuccess); - rb.PushCopyObjects(state_change_event->GetReadableEvent()); -} - -void IUserLocalCommunicationService::GetNetworkInfoLatestUpdate(Kernel::HLERequestContext& ctx) { - const std::size_t network_buffer_size = ctx.GetWriteBufferSize(0); - const std::size_t node_buffer_count = ctx.GetWriteBufferSize(1) / sizeof(NodeLatestUpdate); - - if (node_buffer_count == 0 || network_buffer_size != sizeof(NetworkInfo)) { - LOG_ERROR(Service_LDN, "Invalid buffer size {}, {}", network_buffer_size, - node_buffer_count); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultBadInput); - return; - } - - NetworkInfo info; - std::vector latest_update(node_buffer_count); - - const auto rc = ResultSuccess; - if (rc.IsError()) { - LOG_ERROR(Service_LDN, "NetworkInfo is not valid {}", rc.raw); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(rc); - return; - } - - LOG_WARNING(Service_LDN, "(STUBBED) called, ssid='{}', nodes={}", - info.common.ssid.GetStringValue(), info.ldn.node_count); - - ctx.WriteBuffer(info, 0); - ctx.WriteBuffer(latest_update, 1); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void IUserLocalCommunicationService::Scan(Kernel::HLERequestContext& ctx) { - ScanImpl(ctx); -} - -void IUserLocalCommunicationService::ScanPrivate(Kernel::HLERequestContext& ctx) { - ScanImpl(ctx, true); -} - -void IUserLocalCommunicationService::ScanImpl(Kernel::HLERequestContext& ctx, bool is_private) { - IPC::RequestParser rp{ctx}; - const auto channel{rp.PopEnum()}; - const auto scan_filter{rp.PopRaw()}; - - const std::size_t network_info_size = ctx.GetWriteBufferSize() / sizeof(NetworkInfo); - - if (network_info_size == 0) { - LOG_ERROR(Service_LDN, "Invalid buffer size {}", network_info_size); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultBadInput); - return; - } - - u16 count = 0; - std::vector network_infos(network_info_size); - - LOG_WARNING(Service_LDN, - "(STUBBED) called, channel={}, filter_scan_flag={}, filter_network_type={}", - channel, scan_filter.flag, scan_filter.network_type); - - ctx.WriteBuffer(network_infos); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(count); -} - -void IUserLocalCommunicationService::OpenAccessPoint(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_LDN, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void IUserLocalCommunicationService::CloseAccessPoint(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_LDN, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void IUserLocalCommunicationService::CreateNetwork(Kernel::HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - struct Parameters { - SecurityConfig security_config; - UserConfig user_config; - INSERT_PADDING_WORDS_NOINIT(1); - NetworkConfig network_config; - }; - static_assert(sizeof(Parameters) == 0x98, "Parameters has incorrect size."); - - LOG_WARNING(Service_LDN, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void IUserLocalCommunicationService::CreateNetworkPrivate(Kernel::HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - struct Parameters { - SecurityConfig security_config; - SecurityParameter security_parameter; - UserConfig user_config; - NetworkConfig network_config; - }; - static_assert(sizeof(Parameters) == 0xB8, "Parameters has incorrect size."); - - const auto parameters{rp.PopRaw()}; - - LOG_WARNING(Service_LDN, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void IUserLocalCommunicationService::DestroyNetwork(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_LDN, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void IUserLocalCommunicationService::SetAdvertiseData(Kernel::HLERequestContext& ctx) { - std::vector read_buffer = ctx.ReadBuffer(); - - LOG_WARNING(Service_LDN, "(STUBBED) called, size {}", read_buffer.size()); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void IUserLocalCommunicationService::SetStationAcceptPolicy(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_LDN, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void IUserLocalCommunicationService::AddAcceptFilterEntry(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_LDN, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void IUserLocalCommunicationService::OpenStation(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_LDN, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void IUserLocalCommunicationService::CloseStation(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_LDN, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void IUserLocalCommunicationService::Connect(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_LDN, "(STUBBED) called"); - - IPC::RequestParser rp{ctx}; - struct Parameters { - SecurityConfig security_config; - UserConfig user_config; - u32 local_communication_version; - u32 option; - }; - static_assert(sizeof(Parameters) == 0x7C, "Parameters has incorrect size."); - - const auto parameters{rp.PopRaw()}; - - const std::vector read_buffer = ctx.ReadBuffer(); - NetworkInfo network_info{}; - - if (read_buffer.size() != sizeof(NetworkInfo)) { - LOG_ERROR(Frontend, "NetworkInfo doesn't match read_buffer size!"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultBadInput); - return; - } - - std::memcpy(&network_info, read_buffer.data(), read_buffer.size()); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void IUserLocalCommunicationService::Disconnect(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_LDN, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} -void IUserLocalCommunicationService::Initialize(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_LDN, "(STUBBED) called"); - - const auto rc = InitializeImpl(ctx); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(rc); -} - -void IUserLocalCommunicationService::Finalize(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_LDN, "(STUBBED) called"); - - is_initialized = false; - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void IUserLocalCommunicationService::Initialize2(Kernel::HLERequestContext& ctx) { - LOG_WARNING(Service_LDN, "(STUBBED) called"); - - const auto rc = InitializeImpl(ctx); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(rc); -} - -Result IUserLocalCommunicationService::InitializeImpl(Kernel::HLERequestContext& ctx) { - const auto network_interface = Network::GetSelectedNetworkInterface(); - if (!network_interface) { - LOG_ERROR(Service_LDN, "No network interface is set"); + is_initialized = true; + // TODO (flTobi): Change this to ResultSuccess when LDN is fully implemented return ResultAirplaneModeEnabled; } - is_initialized = true; - // TODO (flTobi): Change this to ResultSuccess when LDN is fully implemented - return ResultAirplaneModeEnabled; -} + KernelHelpers::ServiceContext service_context; + Kernel::KEvent* state_change_event; + Network::RoomNetwork& room_network; + + bool is_initialized{}; +}; class LDNS final : public ServiceFramework { public: diff --git a/src/core/hle/service/ldn/ldn.h b/src/core/hle/service/ldn/ldn.h index 4ab8f7a9b..6afe2ea6f 100644 --- a/src/core/hle/service/ldn/ldn.h +++ b/src/core/hle/service/ldn/ldn.h @@ -7,8 +7,6 @@ #include "core/hle/kernel/k_event.h" #include "core/hle/result.h" #include "core/hle/service/kernel_helpers.h" -#include "core/hle/service/ldn/ldn_results.h" -#include "core/hle/service/ldn/ldn_types.h" #include "core/hle/service/sm/sm.h" namespace Core { @@ -24,68 +22,4 @@ namespace Service::LDN { /// Registers all LDN services with the specified service manager. void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); -class IUserLocalCommunicationService final - : public ServiceFramework { -public: - explicit IUserLocalCommunicationService(Core::System& system_); - ~IUserLocalCommunicationService() override; - - void GetState(Kernel::HLERequestContext& ctx); - - void GetNetworkInfo(Kernel::HLERequestContext& ctx); - - void GetDisconnectReason(Kernel::HLERequestContext& ctx); - - void GetSecurityParameter(Kernel::HLERequestContext& ctx); - - void GetNetworkConfig(Kernel::HLERequestContext& ctx); - - void AttachStateChangeEvent(Kernel::HLERequestContext& ctx); - - void GetNetworkInfoLatestUpdate(Kernel::HLERequestContext& ctx); - - void Scan(Kernel::HLERequestContext& ctx); - void ScanPrivate(Kernel::HLERequestContext& ctx); - void ScanImpl(Kernel::HLERequestContext& ctx, bool is_private = false); - - void OpenAccessPoint(Kernel::HLERequestContext& ctx); - - void CloseAccessPoint(Kernel::HLERequestContext& ctx); - - void CreateNetwork(Kernel::HLERequestContext& ctx); - void CreateNetworkPrivate(Kernel::HLERequestContext& ctx); - - void DestroyNetwork(Kernel::HLERequestContext& ctx); - - void SetAdvertiseData(Kernel::HLERequestContext& ctx); - - void SetStationAcceptPolicy(Kernel::HLERequestContext& ctx); - - void AddAcceptFilterEntry(Kernel::HLERequestContext& ctx); - - void OpenStation(Kernel::HLERequestContext& ctx); - - void CloseStation(Kernel::HLERequestContext& ctx); - - void Disconnect(Kernel::HLERequestContext& ctx); - - void Connect(Kernel::HLERequestContext& ctx); - - void Initialize(Kernel::HLERequestContext& ctx); - - void Finalize(Kernel::HLERequestContext& ctx); - - void Initialize2(Kernel::HLERequestContext& ctx); - Result InitializeImpl(Kernel::HLERequestContext& ctx); - -private: - void OnEventFired(); - - KernelHelpers::ServiceContext service_context; - Kernel::KEvent* state_change_event; - Network::RoomNetwork& room_network; - - bool is_initialized{}; -}; - } // namespace Service::LDN