From 1437c15f526cdc86ce9b3a71e3ce207e4ff4d7bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 30 Oct 2026 23:20:54 +0100 Subject: [PATCH] sceNetApctl: Fail GetState before Init, let GetLocalEtherAddr work in infrastructure mode - Fixes #22857 PES 2009 calls sceNetApctlGetState first and only calls sceNetApctlInit when it fails with 0x80410a0d. We returned success, so Init was never called, apctl's state never advanced and the Netconf dialog waited on "Connecting to the access point" forever. A PSP returns 0x80410a0d before Init and after Term (pspautotests net/adhoc/apctlinit). After that the game polls sceNetGetLocalEtherAddr until it succeeds, which we only allowed in ad hoc mode. Also allow it once apctl has connected. It still fails with apctl initialized but not connected, as the test shows. Co-Authored-By: Claude Opus 5.5 --- Core/HLE/ErrorCodes.h | 1 + Core/HLE/sceKernel.cpp | 1 + Core/HLE/sceNet.cpp | 10 ++++++++-- pspautotests | 2 +- test.py | 1 + 5 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Core/HLE/ErrorCodes.h b/Core/HLE/ErrorCodes.h index 5138c083b9..9e5f02433f 100644 --- a/Core/HLE/ErrorCodes.h +++ b/Core/HLE/ErrorCodes.h @@ -576,6 +576,7 @@ enum PSPErrorCode : u32 { SCE_NET_APCTL_ERROR_INVALID_ID = 0x80410a09, SCE_NET_APCTL_ERROR_WLAN_SUSPENDED = 0x80410a0a, SCE_NET_APCTL_ERROR_TIMEOUT = 0x80410a0b, + SCE_NET_APCTL_ERROR_NOT_INITIALIZED = 0x80410a0d, // pspnet_adhoc_auth SCE_NET_ADHOC_ERROR_AUTH_ALREADY_INITIALIZED = 0x80410601, diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index 9fbbffac20..69babbc91b 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -1709,6 +1709,7 @@ const char *KernelErrorToString(u32 err) { case SCE_NET_APCTL_ERROR_INVALID_ID: return "SCE_NET_APCTL_ERROR_INVALID_ID"; case SCE_NET_APCTL_ERROR_WLAN_SUSPENDED: return "SCE_NET_APCTL_ERROR_WLAN_SUSPENDED"; case SCE_NET_APCTL_ERROR_TIMEOUT: return "SCE_NET_APCTL_ERROR_TIMEOUT"; + case SCE_NET_APCTL_ERROR_NOT_INITIALIZED: return "SCE_NET_APCTL_ERROR_NOT_INITIALIZED"; // pspnet_adhoc_auth case SCE_NET_ADHOC_ERROR_AUTH_ALREADY_INITIALIZED: return "SCE_NET_ADHOC_ERROR_AUTH_ALREADY_INITIALIZED"; diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index f4ae6d5b5a..da46d943f5 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -1124,8 +1124,11 @@ static u32 sceWlanGetEtherAddr(u32 addrAddr) { static u32 sceNetGetLocalEtherAddr(u32 addrAddr) { // FIXME: Return 0x80410180 (pspnet[_core] error code?) before successful attempt to Create/Connect/Join a Group? (ie. adhocctlCurrentMode == ADHOCCTL_MODE_NONE) - if (adhocctlCurrentMode == ADHOCCTL_MODE_NONE) + // Fails while apctl is initialized but not connected (pspautotests net/adhoc/apctlinit). PES 2009 polls it + // until it succeeds once apctl has connected. + if (adhocctlCurrentMode == ADHOCCTL_MODE_NONE && !__NetApctlConnected()) { return hleLogDebug(Log::sceNet, 0x80410180, "address not available?"); + } return sceWlanGetEtherAddr(addrAddr); } @@ -1602,7 +1605,10 @@ bool __NetApctlConnected() { } static int sceNetApctlGetState(u32 pStateAddr) { - //if (!netApctlInited) return hleLogError(Log::sceNet, SCE_NET_APCTL_ERROR_NOT_IN_BSS, "apctl not in bss"); + // PES 2009 only calls sceNetApctlInit when this fails. pspautotests net/adhoc/apctlinit + if (!g_netApctlInited) { + return hleLogWarning(Log::sceNet, SCE_NET_APCTL_ERROR_NOT_INITIALIZED, "not initialized"); + } // Valid Arguments if (Memory::IsValidAddress(pStateAddr)) { diff --git a/pspautotests b/pspautotests index bef628fd88..866a27a25c 160000 --- a/pspautotests +++ b/pspautotests @@ -1 +1 @@ -Subproject commit bef628fd88627d3ef206184d696f62537e48985b +Subproject commit 866a27a25c10692c3d267683d61cb60373de98a0 diff --git a/test.py b/test.py index 8eedebed45..649fc9b567 100755 --- a/test.py +++ b/test.py @@ -366,6 +366,7 @@ tests_good = [ "net/inet/errnothread", "net/adhoc/abandon", "net/adhoc/alerts", + "net/adhoc/apctlinit", "net/adhoc/discover", "net/adhoc/gamemode", "net/adhoc/limits",