From 0d089972a3ec5fb1a025c26f3b46aa7fb730aed2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 28 Oct 2026 16:07:05 +0100 Subject: [PATCH] sceNetAdhoc: Socket alerts don't stop calls that can complete at once On a PSP (pspautotests net/adhoc/alerts), PtpConnect on a connected socket and PtpFlush with nothing left to send return 0 with their alerts set, and the poll alert reports ALERT alone in revents. A connection PtpOpen started counts as connected once it's up, even if no call has looked at it since. Co-Authored-By: Claude Opus 5.5 --- Core/HLE/sceNetAdhoc.cpp | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 26d317e41d..c74fb7392d 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -3313,6 +3313,8 @@ int PollAdhocSocket(SceNetAdhocPollSd* sds, int count, int timeout, int nonblock if (sock->flags & ADHOC_F_ALERTPOLL) { sock->alerted_flags |= ADHOC_F_ALERTPOLL; + // Reported as ALERT alone (pspautotests net/adhoc/alerts). + sds[i].revents = ADHOC_EV_ALERT; return SCE_NET_ADHOC_ERROR_SOCKET_ALERTED; } @@ -5140,17 +5142,26 @@ int NetAdhocPtp_Connect(int id, int timeout, int flag, bool allowForcedConnect) auto& ptpsocket = socket->data.ptp; socket->nonblocking = flag; + // A connection PtpOpen started may have come up since. + if (ptpsocket.state == ADHOC_PTP_STATE_SYN_SENT && !serverHasRelay) { + struct sockaddr_in peer; + socklen_t peerLen = sizeof(peer); + if (getpeername(ptpsocket.id, (struct sockaddr *)&peer, &peerLen) == 0) { + ptpsocket.state = ADHOC_PTP_STATE_ESTABLISHED; + } + } + + // Connecting a connected socket returns 0 on the PSP, even with the connect alert set (pspautotests + // net/adhoc/alerts). Phantasy Star Portable 2 does that. + if (ptpsocket.state == ADHOC_PTP_STATE_ESTABLISHED) + return 0; + if (socket->flags & ADHOC_F_ALERTCONNECT) { socket->alerted_flags |= ADHOC_F_ALERTCONNECT; return hleLogError(Log::sceNet, SCE_NET_ADHOC_ERROR_SOCKET_ALERTED, "socket alerted"); } - // Connecting a connected socket returns 0 on the PSP (pspautotests net/adhoc/alerts). Phantasy Star - // Portable 2 does that. - if (ptpsocket.state == ADHOC_PTP_STATE_ESTABLISHED) - return 0; - // Valid Client Socket if (ptpsocket.state == ADHOC_PTP_STATE_CLOSED || ptpsocket.state == ADHOC_PTP_STATE_SYN_SENT) { hleEatMicro(50); @@ -5918,7 +5929,9 @@ static int sceNetAdhocPtpFlush(MIPSState *mips, int id, int timeout, int nonbloc auto& ptpsocket = socket->data.ptp; socket->nonblocking = nonblock; - if (socket->flags & ADHOC_F_ALERTFLUSH) { + // A flush with nothing left to send returns 0 even with the flush alert set (pspautotests + // net/adhoc/alerts). Data sent on a connected socket is already with the host. + if ((socket->flags & ADHOC_F_ALERTFLUSH) && ptpsocket.state != ADHOC_PTP_STATE_ESTABLISHED) { socket->alerted_flags |= ADHOC_F_ALERTFLUSH; return hleLogError(Log::sceNet, SCE_NET_ADHOC_ERROR_SOCKET_ALERTED, "socket alerted");