mirror of
https://git.eden-emu.dev/archive/citron
synced 2026-04-17 10:10:45 -04:00
service/ldn: Implement SetProtocol and SetWirelessAudioPolicy commands
Adds support for LDN service commands introduced in firmware 20.0.0+: - Command 105: SetWirelessAudioPolicy (stubbed) - Command 106: SetProtocol This enables ACNH Update 3.0 and other games using newer SDK versions to properly initialize LDN for local multiplayer functionality. Signed-off-by: Zephyron <zephyron@citron-emu.org>
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
|
// SPDX-FileCopyrightText: Copyright 2026 citron Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
@@ -128,6 +129,21 @@ enum class WirelessControllerRestriction : u32 {
|
|||||||
Default,
|
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 {
|
struct ConnectOption {
|
||||||
union {
|
union {
|
||||||
u32 raw;
|
u32 raw;
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ ISystemLocalCommunicationService::ISystemLocalCommunicationService(Core::System&
|
|||||||
{102, D<&ISystemLocalCommunicationService::Scan>, "Scan"},
|
{102, D<&ISystemLocalCommunicationService::Scan>, "Scan"},
|
||||||
{103, D<&ISystemLocalCommunicationService::ScanPrivate>, "ScanPrivate"},
|
{103, D<&ISystemLocalCommunicationService::ScanPrivate>, "ScanPrivate"},
|
||||||
{104, D<&ISystemLocalCommunicationService::SetWirelessControllerRestriction>, "SetWirelessControllerRestriction"},
|
{104, D<&ISystemLocalCommunicationService::SetWirelessControllerRestriction>, "SetWirelessControllerRestriction"},
|
||||||
|
{105, D<&ISystemLocalCommunicationService::SetWirelessAudioPolicy>, "SetWirelessAudioPolicy"},
|
||||||
|
{106, D<&ISystemLocalCommunicationService::SetProtocol>, "SetProtocol"},
|
||||||
{200, D<&ISystemLocalCommunicationService::OpenAccessPoint>, "OpenAccessPoint"},
|
{200, D<&ISystemLocalCommunicationService::OpenAccessPoint>, "OpenAccessPoint"},
|
||||||
{201, D<&ISystemLocalCommunicationService::CloseAccessPoint>, "CloseAccessPoint"},
|
{201, D<&ISystemLocalCommunicationService::CloseAccessPoint>, "CloseAccessPoint"},
|
||||||
{202, D<&ISystemLocalCommunicationService::CreateNetwork>, "CreateNetwork"},
|
{202, D<&ISystemLocalCommunicationService::CreateNetwork>, "CreateNetwork"},
|
||||||
@@ -116,7 +118,38 @@ Result ISystemLocalCommunicationService::ScanPrivate(Out<s16> network_count, Wif
|
|||||||
}
|
}
|
||||||
|
|
||||||
Result ISystemLocalCommunicationService::SetWirelessControllerRestriction(WirelessControllerRestriction wireless_restriction) {
|
Result ISystemLocalCommunicationService::SetWirelessControllerRestriction(WirelessControllerRestriction wireless_restriction) {
|
||||||
LOG_WARNING(Service_LDN, "(STUBBED) called");
|
LOG_WARNING(Service_LDN, "(STUBBED) called, wireless_restriction={}",
|
||||||
|
static_cast<u32>(wireless_restriction));
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result ISystemLocalCommunicationService::SetWirelessAudioPolicy(WirelessAudioRestriction wireless_audio_restriction) {
|
||||||
|
LOG_WARNING(Service_LDN, "(STUBBED) called, wireless_audio_restriction={}",
|
||||||
|
static_cast<u32>(wireless_audio_restriction));
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result ISystemLocalCommunicationService::SetProtocol(Protocol protocol) {
|
||||||
|
LOG_INFO(Service_LDN, "called, protocol={}", static_cast<u32>(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<u32>(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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ private:
|
|||||||
Result ScanPrivate(Out<s16> network_count, WifiChannel channel, const ScanFilter& scan_filter,
|
Result ScanPrivate(Out<s16> network_count, WifiChannel channel, const ScanFilter& scan_filter,
|
||||||
OutArray<NetworkInfo, BufferAttr_HipcAutoSelect> out_network_info);
|
OutArray<NetworkInfo, BufferAttr_HipcAutoSelect> out_network_info);
|
||||||
Result SetWirelessControllerRestriction(WirelessControllerRestriction wireless_restriction);
|
Result SetWirelessControllerRestriction(WirelessControllerRestriction wireless_restriction);
|
||||||
|
Result SetWirelessAudioPolicy(WirelessAudioRestriction wireless_audio_restriction);
|
||||||
|
Result SetProtocol(Protocol protocol);
|
||||||
Result OpenAccessPoint();
|
Result OpenAccessPoint();
|
||||||
Result CloseAccessPoint();
|
Result CloseAccessPoint();
|
||||||
Result CreateNetwork(const CreateNetworkConfig& create_config);
|
Result CreateNetwork(const CreateNetworkConfig& create_config);
|
||||||
@@ -61,6 +63,8 @@ private:
|
|||||||
Result FinalizeSystem();
|
Result FinalizeSystem();
|
||||||
Result SetOperationMode(u32 mode);
|
Result SetOperationMode(u32 mode);
|
||||||
Result InitializeSystem2();
|
Result InitializeSystem2();
|
||||||
|
|
||||||
|
Protocol current_protocol{Protocol::NX};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Service::LDN
|
} // namespace Service::LDN
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ IUserLocalCommunicationService::IUserLocalCommunicationService(Core::System& sys
|
|||||||
{102, D<&IUserLocalCommunicationService::Scan>, "Scan"},
|
{102, D<&IUserLocalCommunicationService::Scan>, "Scan"},
|
||||||
{103, D<&IUserLocalCommunicationService::ScanPrivate>, "ScanPrivate"},
|
{103, D<&IUserLocalCommunicationService::ScanPrivate>, "ScanPrivate"},
|
||||||
{104, D<&IUserLocalCommunicationService::SetWirelessControllerRestriction>, "SetWirelessControllerRestriction"},
|
{104, D<&IUserLocalCommunicationService::SetWirelessControllerRestriction>, "SetWirelessControllerRestriction"},
|
||||||
|
{105, D<&IUserLocalCommunicationService::SetWirelessAudioPolicy>, "SetWirelessAudioPolicy"},
|
||||||
|
{106, D<&IUserLocalCommunicationService::SetProtocol>, "SetProtocol"},
|
||||||
{200, D<&IUserLocalCommunicationService::OpenAccessPoint>, "OpenAccessPoint"},
|
{200, D<&IUserLocalCommunicationService::OpenAccessPoint>, "OpenAccessPoint"},
|
||||||
{201, D<&IUserLocalCommunicationService::CloseAccessPoint>, "CloseAccessPoint"},
|
{201, D<&IUserLocalCommunicationService::CloseAccessPoint>, "CloseAccessPoint"},
|
||||||
{202, D<&IUserLocalCommunicationService::CreateNetwork>, "CreateNetwork"},
|
{202, D<&IUserLocalCommunicationService::CreateNetwork>, "CreateNetwork"},
|
||||||
@@ -189,7 +191,39 @@ Result IUserLocalCommunicationService::ScanPrivate(
|
|||||||
|
|
||||||
Result IUserLocalCommunicationService::SetWirelessControllerRestriction(
|
Result IUserLocalCommunicationService::SetWirelessControllerRestriction(
|
||||||
WirelessControllerRestriction wireless_restriction) {
|
WirelessControllerRestriction wireless_restriction) {
|
||||||
LOG_WARNING(Service_LDN, "(STUBBED) called");
|
LOG_WARNING(Service_LDN, "(STUBBED) called, wireless_restriction={}",
|
||||||
|
static_cast<u32>(wireless_restriction));
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result IUserLocalCommunicationService::SetWirelessAudioPolicy(
|
||||||
|
WirelessAudioRestriction wireless_audio_restriction) {
|
||||||
|
LOG_WARNING(Service_LDN, "(STUBBED) called, wireless_audio_restriction={}",
|
||||||
|
static_cast<u32>(wireless_audio_restriction));
|
||||||
|
R_SUCCEED();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result IUserLocalCommunicationService::SetProtocol(Protocol protocol) {
|
||||||
|
LOG_INFO(Service_LDN, "called, protocol={}", static_cast<u32>(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<u32>(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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,10 @@ private:
|
|||||||
|
|
||||||
Result SetWirelessControllerRestriction(WirelessControllerRestriction wireless_restriction);
|
Result SetWirelessControllerRestriction(WirelessControllerRestriction wireless_restriction);
|
||||||
|
|
||||||
|
Result SetWirelessAudioPolicy(WirelessAudioRestriction wireless_audio_restriction);
|
||||||
|
|
||||||
|
Result SetProtocol(Protocol protocol);
|
||||||
|
|
||||||
Result OpenAccessPoint();
|
Result OpenAccessPoint();
|
||||||
|
|
||||||
Result CloseAccessPoint();
|
Result CloseAccessPoint();
|
||||||
@@ -106,6 +110,7 @@ private:
|
|||||||
Network::RoomMember::CallbackHandle<Network::LDNPacket> ldn_packet_received;
|
Network::RoomMember::CallbackHandle<Network::LDNPacket> ldn_packet_received;
|
||||||
|
|
||||||
bool is_initialized{};
|
bool is_initialized{};
|
||||||
|
Protocol current_protocol{Protocol::NX};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Service::LDN
|
} // namespace Service::LDN
|
||||||
|
|||||||
Reference in New Issue
Block a user