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 <noreply@anthropic.com>
This commit is contained in:
Henrik RydgårdandClaude Opus 5.5 committed 2026-10-30 23:50:28 +01:00
1 parent 6b9830a030
commit 1437c15f52
5 files changed
+12 -3

No files matched your search

+1
View File
@@ -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,
+1
View File
@@ -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";
+8 -2
View File
@@ -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)) {
+1
View File
@@ -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",