diff --git a/src/core/hle/service/ldn/ldn_types.h b/src/core/hle/service/ldn/ldn_types.h index 6198aa07b..249fa32b0 100644 --- a/src/core/hle/service/ldn/ldn_types.h +++ b/src/core/hle/service/ldn/ldn_types.h @@ -1,4 +1,5 @@ // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 citron Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later #pragma once @@ -128,6 +129,21 @@ enum class WirelessControllerRestriction : u32 { Default, }; +enum class WirelessAudioRestriction : u32 { + Disabled, + Enabled, +}; + +// Protocol enum for SetProtocol command (18.0.0+) +// On NX, permission bitmask is 0xA (allows Protocol 1 and 3 only) +enum class Protocol : u32 { + Default = 0, + NX = 1, + // S2 = 2, // Switch 2 only + NXAndOunce = 3, + // S2_Alt = 4, // Switch 2 only +}; + struct ConnectOption { union { u32 raw; diff --git a/src/core/hle/service/ldn/system_local_communication_service.cpp b/src/core/hle/service/ldn/system_local_communication_service.cpp index 0d44f6004..9b8472806 100644 --- a/src/core/hle/service/ldn/system_local_communication_service.cpp +++ b/src/core/hle/service/ldn/system_local_communication_service.cpp @@ -22,6 +22,8 @@ ISystemLocalCommunicationService::ISystemLocalCommunicationService(Core::System& {102, D<&ISystemLocalCommunicationService::Scan>, "Scan"}, {103, D<&ISystemLocalCommunicationService::ScanPrivate>, "ScanPrivate"}, {104, D<&ISystemLocalCommunicationService::SetWirelessControllerRestriction>, "SetWirelessControllerRestriction"}, + {105, D<&ISystemLocalCommunicationService::SetWirelessAudioPolicy>, "SetWirelessAudioPolicy"}, + {106, D<&ISystemLocalCommunicationService::SetProtocol>, "SetProtocol"}, {200, D<&ISystemLocalCommunicationService::OpenAccessPoint>, "OpenAccessPoint"}, {201, D<&ISystemLocalCommunicationService::CloseAccessPoint>, "CloseAccessPoint"}, {202, D<&ISystemLocalCommunicationService::CreateNetwork>, "CreateNetwork"}, @@ -116,7 +118,38 @@ Result ISystemLocalCommunicationService::ScanPrivate(Out network_count, Wif } Result ISystemLocalCommunicationService::SetWirelessControllerRestriction(WirelessControllerRestriction wireless_restriction) { - LOG_WARNING(Service_LDN, "(STUBBED) called"); + LOG_WARNING(Service_LDN, "(STUBBED) called, wireless_restriction={}", + static_cast(wireless_restriction)); + R_SUCCEED(); +} + +Result ISystemLocalCommunicationService::SetWirelessAudioPolicy(WirelessAudioRestriction wireless_audio_restriction) { + LOG_WARNING(Service_LDN, "(STUBBED) called, wireless_audio_restriction={}", + static_cast(wireless_audio_restriction)); + R_SUCCEED(); +} + +Result ISystemLocalCommunicationService::SetProtocol(Protocol protocol) { + LOG_INFO(Service_LDN, "called, protocol={}", static_cast(protocol)); + + // On NX, the protocol permission bitmask is 0xA (allows 1 and 3) + // The SDK passes value 1 for Protocol 0/1, and 3 is passed directly if specified + // Input must be non-zero, and BIT(input) must be set in permission bitmask + const u32 protocol_value = static_cast(protocol); + + // For NX compatibility, we accept protocols 1 (NX) and 3 (NXAndOunce) + // Protocol 0 (Default) is typically converted to 1 by the SDK before calling + if (protocol_value == 0) { + // Default is treated as NX + current_protocol = Protocol::NX; + } else if (protocol_value == 1 || protocol_value == 3) { + current_protocol = protocol; + } else { + // Invalid protocol for NX - but we'll accept it as a stub + LOG_WARNING(Service_LDN, "Invalid protocol value {} for NX, accepting anyway", protocol_value); + current_protocol = protocol; + } + R_SUCCEED(); } diff --git a/src/core/hle/service/ldn/system_local_communication_service.h b/src/core/hle/service/ldn/system_local_communication_service.h index ead4d73c1..e39538b4e 100644 --- a/src/core/hle/service/ldn/system_local_communication_service.h +++ b/src/core/hle/service/ldn/system_local_communication_service.h @@ -39,6 +39,8 @@ private: Result ScanPrivate(Out network_count, WifiChannel channel, const ScanFilter& scan_filter, OutArray out_network_info); Result SetWirelessControllerRestriction(WirelessControllerRestriction wireless_restriction); + Result SetWirelessAudioPolicy(WirelessAudioRestriction wireless_audio_restriction); + Result SetProtocol(Protocol protocol); Result OpenAccessPoint(); Result CloseAccessPoint(); Result CreateNetwork(const CreateNetworkConfig& create_config); @@ -61,6 +63,8 @@ private: Result FinalizeSystem(); Result SetOperationMode(u32 mode); Result InitializeSystem2(); + + Protocol current_protocol{Protocol::NX}; }; } // namespace Service::LDN diff --git a/src/core/hle/service/ldn/user_local_communication_service.cpp b/src/core/hle/service/ldn/user_local_communication_service.cpp index 5e69a9054..a7463bd02 100644 --- a/src/core/hle/service/ldn/user_local_communication_service.cpp +++ b/src/core/hle/service/ldn/user_local_communication_service.cpp @@ -37,6 +37,8 @@ IUserLocalCommunicationService::IUserLocalCommunicationService(Core::System& sys {102, D<&IUserLocalCommunicationService::Scan>, "Scan"}, {103, D<&IUserLocalCommunicationService::ScanPrivate>, "ScanPrivate"}, {104, D<&IUserLocalCommunicationService::SetWirelessControllerRestriction>, "SetWirelessControllerRestriction"}, + {105, D<&IUserLocalCommunicationService::SetWirelessAudioPolicy>, "SetWirelessAudioPolicy"}, + {106, D<&IUserLocalCommunicationService::SetProtocol>, "SetProtocol"}, {200, D<&IUserLocalCommunicationService::OpenAccessPoint>, "OpenAccessPoint"}, {201, D<&IUserLocalCommunicationService::CloseAccessPoint>, "CloseAccessPoint"}, {202, D<&IUserLocalCommunicationService::CreateNetwork>, "CreateNetwork"}, @@ -189,7 +191,39 @@ Result IUserLocalCommunicationService::ScanPrivate( Result IUserLocalCommunicationService::SetWirelessControllerRestriction( WirelessControllerRestriction wireless_restriction) { - LOG_WARNING(Service_LDN, "(STUBBED) called"); + LOG_WARNING(Service_LDN, "(STUBBED) called, wireless_restriction={}", + static_cast(wireless_restriction)); + R_SUCCEED(); +} + +Result IUserLocalCommunicationService::SetWirelessAudioPolicy( + WirelessAudioRestriction wireless_audio_restriction) { + LOG_WARNING(Service_LDN, "(STUBBED) called, wireless_audio_restriction={}", + static_cast(wireless_audio_restriction)); + R_SUCCEED(); +} + +Result IUserLocalCommunicationService::SetProtocol(Protocol protocol) { + LOG_INFO(Service_LDN, "called, protocol={}", static_cast(protocol)); + + // On NX, the protocol permission bitmask is 0xA (allows 1 and 3) + // The SDK passes value 1 for Protocol 0/1, and 3 is passed directly if specified + // Input must be non-zero, and BIT(input) must be set in permission bitmask + const u32 protocol_value = static_cast(protocol); + + // For NX compatibility, we accept protocols 1 (NX) and 3 (NXAndOunce) + // Protocol 0 (Default) is typically converted to 1 by the SDK before calling + if (protocol_value == 0) { + // Default is treated as NX + current_protocol = Protocol::NX; + } else if (protocol_value == 1 || protocol_value == 3) { + current_protocol = protocol; + } else { + // Invalid protocol for NX - but we'll accept it as a stub + LOG_WARNING(Service_LDN, "Invalid protocol value {} for NX, accepting anyway", protocol_value); + current_protocol = protocol; + } + R_SUCCEED(); } diff --git a/src/core/hle/service/ldn/user_local_communication_service.h b/src/core/hle/service/ldn/user_local_communication_service.h index 3c963f425..c4e4242d4 100644 --- a/src/core/hle/service/ldn/user_local_communication_service.h +++ b/src/core/hle/service/ldn/user_local_communication_service.h @@ -53,6 +53,10 @@ private: Result SetWirelessControllerRestriction(WirelessControllerRestriction wireless_restriction); + Result SetWirelessAudioPolicy(WirelessAudioRestriction wireless_audio_restriction); + + Result SetProtocol(Protocol protocol); + Result OpenAccessPoint(); Result CloseAccessPoint(); @@ -106,6 +110,7 @@ private: Network::RoomMember::CallbackHandle ldn_packet_received; bool is_initialized{}; + Protocol current_protocol{Protocol::NX}; }; } // namespace Service::LDN