From 79d31d4b85bffd261bda8e64aff0ea506fc0dc4d Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Wed, 8 Dec 2021 04:34:17 +0700 Subject: [PATCH 1/6] Allow Sending PDP to non-existing MAC address (except invalid mac address). Fixes an issue on NBA Ballers Rebound where players unable to enter Multiplayer Menu again after getting connection issue. --- Core/HLE/sceNetAdhoc.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 37339d251b..c16832e63a 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -1508,7 +1508,7 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int // Valid Data Buffer if (data != NULL) { // Valid Destination Address - if (daddr != NULL) { + if (daddr != NULL && !isZeroMAC(daddr)) { // Log Destination // Schedule Timeout Removal //if (flag) timeout = 0; @@ -1580,7 +1580,8 @@ static int sceNetAdhocPdpSend(int id, const char *mac, u32 port, void *data, int // Does PDP can Timeout? There is no concept of Timeout when sending UDP due to no ACK, but might happen if the socket buffer is full, not sure about PDP since some games did use the timeout arg return hleLogDebug(SCENET, ERROR_NET_ADHOC_TIMEOUT, "timeout?"); // ERROR_NET_ADHOC_INVALID_ADDR; } - //VERBOSE_LOG(SCENET, "sceNetAdhocPdpSend[%i:%u]: Unknown Target Peer %s:%u\n", id, getLocalPort(pdpsocket.id), mac2str(daddr, tmpmac), ntohs(target.sin_port)); + VERBOSE_LOG(SCENET, "sceNetAdhocPdpSend[%i:%u]: Unknown Target Peer %s:%u (faking success)\n", id, getLocalPort(pdpsocket.id), mac2str(daddr).c_str(), ntohs(target.sin_port)); + return 0; // faking success } // Broadcast Target From 6d1a0692489bc425a5987325fc46e5f507a4d313 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Wed, 8 Dec 2021 04:37:16 +0700 Subject: [PATCH 2/6] Added another returned error code on PdpCreate --- Core/HLE/sceNet.cpp | 2 +- Core/HLE/sceNet.h | 1 + Core/HLE/sceNetAdhoc.cpp | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index a93ed56821..6565a3191c 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -53,7 +53,7 @@ #define INADDR_NONE 0xFFFFFFFF #endif -static bool netInited; +bool netInited; bool netInetInited; u32 netDropRate = 0; diff --git a/Core/HLE/sceNet.h b/Core/HLE/sceNet.h index 911b61e5eb..d34ab560dd 100644 --- a/Core/HLE/sceNet.h +++ b/Core/HLE/sceNet.h @@ -309,6 +309,7 @@ private: u32_le argsAddr = 0; }; +extern bool netInited; extern bool netInetInited; extern bool netApctlInited; extern u32 netApctlState; diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index c16832e63a..7cb6d0bedf 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -1289,6 +1289,9 @@ static int sceNetAdhocPdpCreate(const char *mac, int port, int bufferSize, u32 f return -1; } + if (!netInited) + return 0x800201CA; //PSP_LWMUTEX_ERROR_NO_SUCH_LWMUTEX; + // Library is initialized SceNetEtherAddr * saddr = (SceNetEtherAddr *)mac; if (netAdhocInited) { From f1e4b41f1265a418450e9637e6317b650fa59e65 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Wed, 8 Dec 2021 04:46:42 +0700 Subject: [PATCH 3/6] Discard PDP packets from an IP that can't be resolved to Player's MAC address (simple version) to prevent confusing the game, since the source MAC won't be updated and may contains invalid MAC. Added TODO to handle unresolvable packets properly. --- Core/HLE/sceNetAdhoc.cpp | 145 +++++++++++++++++++++++++-------------- 1 file changed, 93 insertions(+), 52 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index 7cb6d0bedf..dd2800a935 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -457,13 +457,41 @@ int DoBlockingPdpRecv(int uid, AdhocSocketRequest& req, s64& result) { return 0; } + int ret; + int sockerr; + SceNetEtherAddr mac; struct sockaddr_in sin; - socklen_t sinlen = sizeof(sin); + socklen_t sinlen; + + sinlen = sizeof(sin); memset(&sin, 0, sinlen); // On Windows: MSG_TRUNC are not supported on recvfrom (socket error WSAEOPNOTSUPP), so we use dummy buffer as an alternative - int ret = recvfrom(uid, dummyPeekBuf64k, dummyPeekBuf64kSize, MSG_PEEK | MSG_NOSIGNAL, (struct sockaddr*)&sin, &sinlen); - int sockerr = errno; + ret = recvfrom(uid, dummyPeekBuf64k, dummyPeekBuf64kSize, MSG_PEEK | MSG_NOSIGNAL, (struct sockaddr*)&sin, &sinlen); + sockerr = errno; + + // Discard packets from IP that can't be translated into MAC address to prevent confusing the game, since the sender MAC won't be updated and may contains invalid/undefined value. + // TODO: In order to discard packets from unresolvable IP (can't be translated into player's MAC) properly, we'll need to manage the socket buffer ourself, + // by reading the whole available data, separates each datagram and discard unresolvable one, so we can calculate the correct number of available data to recv on GetPdpStat too. + // We may also need to implement encryption (or a simple checksum will do) in order to validate the packet to findout whether it came from PPSSPP or a different App that may be sending/broadcasting data to the same port being used by a game + // (in case the IP was resolvable but came from a different App, which will need to be discarded too) + if (ret != SOCKET_ERROR && !resolveIP(sin.sin_addr.s_addr, &mac)) { + // Remove the packet from socket buffer + sinlen = sizeof(sin); + memset(&sin, 0, sinlen); + recvfrom(uid, dummyPeekBuf64k, dummyPeekBuf64kSize, MSG_NOSIGNAL, (struct sockaddr*)&sin, &sinlen); + // Try again later, until timeout reached + u64 now = (u64)(time_now_d() * 1000000.0); + if (req.timeout != 0 && now - req.startTime > req.timeout) { + result = ERROR_NET_ADHOC_TIMEOUT; + DEBUG_LOG(SCENET, "sceNetAdhocPdpRecv[%i]: Discard Timeout", req.id); + return 0; + } + else + return -1; + } + + // At this point we assumed that the packet is a valid PPSSPP packet if (ret > 0 && *req.length > 0) memcpy(req.buffer, dummyPeekBuf64k, std::min(ret, *req.length)); @@ -477,9 +505,6 @@ int DoBlockingPdpRecv(int uid, AdhocSocketRequest& req, s64& result) { if (ret >= 0) { DEBUG_LOG(SCENET, "sceNetAdhocPdpRecv[%i:%u]: Received %u bytes from %s:%u\n", req.id, getLocalPort(uid), ret, ip2str(sin.sin_addr).c_str(), ntohs(sin.sin_port)); - // Peer MAC - SceNetEtherAddr mac; - // Find Peer MAC if (resolveIP(sin.sin_addr.s_addr, &mac)) { // Provide Sender Information @@ -520,9 +545,6 @@ int DoBlockingPdpRecv(int uid, AdhocSocketRequest& req, s64& result) { WARN_LOG(SCENET, "sceNetAdhocPdpRecv[%i:%u]: Peeked %u/%u bytes from %s:%u\n", req.id, getLocalPort(uid), ret, *req.length, ip2str(sin.sin_addr).c_str(), ntohs(sin.sin_port)); *req.length = ret; - // Peer MAC - SceNetEtherAddr mac; - // Find Peer MAC if (resolveIP(sin.sin_addr.s_addr, &mac)) { // Provide Sender Information @@ -1760,51 +1782,73 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * // Sender Address struct sockaddr_in sin; - - // Set Address Length (so we get the sender ip) - socklen_t sinlen = sizeof(sin); - memset(&sin, 0, sinlen); - //sin.sin_len = (uint8_t)sinlen; + socklen_t sinlen; // Acquire Network Lock //_acquireNetworkLock(); - // TODO: Use a different thread (similar to sceIo) for recvfrom, recv & accept to prevent blocking-socket from blocking emulation (ie. Hot Shots Tennis:GaG) + SceNetEtherAddr mac; int received = 0; - int error = 0; + int error; - // Receive Data. PDP always sent in full size or nothing(failed), recvfrom will always receive in full size as requested (blocking) or failed (non-blocking). If available UDP data is larger than buffer, excess data is lost. - // Should peek first for the available data size if it's more than len return ERROR_NET_ADHOC_NOT_ENOUGH_SPACE along with required size in len to prevent losing excess data - // On Windows: MSG_TRUNC are not supported on recvfrom (socket error WSAEOPNOTSUPP), so we use dummy buffer as an alternative - received = recvfrom(pdpsocket.id, dummyPeekBuf64k, dummyPeekBuf64kSize, MSG_PEEK | MSG_NOSIGNAL, (struct sockaddr*)&sin, &sinlen); - if (received > 0 && *len > 0) - memcpy(buf, dummyPeekBuf64k, std::min(received, *len)); + int disCnt = 16; + while (--disCnt > 0) + { + // Receive Data. PDP always sent in full size or nothing(failed), recvfrom will always receive in full size as requested (blocking) or failed (non-blocking). If available UDP data is larger than buffer, excess data is lost. + // Should peek first for the available data size if it's more than len return ERROR_NET_ADHOC_NOT_ENOUGH_SPACE along with required size in len to prevent losing excess data + // On Windows: MSG_TRUNC are not supported on recvfrom (socket error WSAEOPNOTSUPP), so we use dummy buffer as an alternative + sinlen = sizeof(sin); + memset(&sin, 0, sinlen); + received = recvfrom(pdpsocket.id, dummyPeekBuf64k, dummyPeekBuf64kSize, MSG_PEEK | MSG_NOSIGNAL, (struct sockaddr*)&sin, &sinlen); + error = errno; + // Discard packets from IP that can't be translated into MAC address to prevent confusing the game, since the sender MAC won't be updated and may contains invalid/undefined value. + // TODO: In order to discard packets from unresolvable IP (can't be translated into player's MAC) properly, we'll need to manage the socket buffer ourself, + // by reading the whole available data, separates each datagram and discard unresolvable one, so we can calculate the correct number of available data to recv on GetPdpStat too. + // We may also need to implement encryption (or a simple checksum will do) in order to validate the packet to findout whether it came from PPSSPP or a different App that may be sending/broadcasting data to the same port being used by a game + // (in case the IP was resolvable but came from a different App, which will need to be discarded too) + // Note: Looping to check too many packets (ie. contiguous) to discard per one non-blocking PdpRecv syscall may cause a slow down + if (received != SOCKET_ERROR && !resolveIP(sin.sin_addr.s_addr, &mac)) { + // Remove the packet from socket buffer + sinlen = sizeof(sin); + memset(&sin, 0, sinlen); + recvfrom(pdpsocket.id, dummyPeekBuf64k, dummyPeekBuf64kSize, MSG_NOSIGNAL, (struct sockaddr*)&sin, &sinlen); + if (flag) { + VERBOSE_LOG(SCENET, "%08x=sceNetAdhocPdpRecv: would block (disc)", ERROR_NET_ADHOC_WOULD_BLOCK); // Temporary fix to avoid a crash on the Logs due to trying to Logs syscall's argument from another thread (ie. AdhocMatchingInput thread) + return ERROR_NET_ADHOC_WOULD_BLOCK; // hleLogSuccessVerboseX(SCENET, ERROR_NET_ADHOC_WOULD_BLOCK, "would block (disc)"); + } + else { + // Simulate blocking behaviour with non-blocking socket, and discard more unresolvable packets until timeout reached + u64 threadSocketId = ((u64)__KernelGetCurThread()) << 32 | pdpsocket.id; + return WaitBlockingAdhocSocket(threadSocketId, PDP_RECV, id, buf, len, timeout, saddr, sport, "pdp recv (disc)"); + } + } + else + break; + } + // At this point we assumed that the packet is a valid PPSSPP packet if (received != SOCKET_ERROR && *len < received) { INFO_LOG(SCENET, "sceNetAdhocPdpRecv[%i:%u]: Peeked %u/%u bytes from %s:%u\n", id, getLocalPort(pdpsocket.id), received, *len, ip2str(sin.sin_addr).c_str(), ntohs(sin.sin_port)); + + if (received > 0 && *len > 0) + memcpy(buf, dummyPeekBuf64k, std::min(received, *len)); + + // Return the actual available data size *len = received; - // Peer MAC - SceNetEtherAddr mac; + // Provide Sender Information + *saddr = mac; + *sport = ntohs(sin.sin_port) - portOffset; - // Find Peer MAC - if (resolveIP(sin.sin_addr.s_addr, &mac)) { - // Provide Sender Information - *saddr = mac; - *sport = ntohs(sin.sin_port) - portOffset; + // Update last recv timestamp, may cause disconnection not detected properly tho + peerlock.lock(); + auto peer = findFriend(&mac); + if (peer != NULL) peer->last_recv = CoreTiming::GetGlobalTimeUsScaled(); + peerlock.unlock(); - // Update last recv timestamp, may cause disconnection not detected properly tho - peerlock.lock(); - auto peer = findFriend(&mac); - if (peer != NULL) peer->last_recv = CoreTiming::GetGlobalTimeUsScaled(); - peerlock.unlock(); - } - - // Free Network Lock - //_freeNetworkLock(); - - return hleLogSuccessVerboseX(SCENET, ERROR_NET_ADHOC_NOT_ENOUGH_SPACE, "not enough space"); //received; + return hleLogSuccessVerboseX(SCENET, ERROR_NET_ADHOC_NOT_ENOUGH_SPACE, "not enough space"); } + sinlen = sizeof(sin); memset(&sin, 0, sinlen); // On Windows: Socket Error 10014 may happen when buffer size is less than the minimum allowed/required (ie. negative number on Vulcanus Seek and Destroy), the address is not a valid part of the user address space (ie. on the stack or when buffer overflow occurred), or the address is not properly aligned (ie. multiple of 4 on 32bit and multiple of 8 on 64bit) https://stackoverflow.com/questions/861154/winsock-error-code-10014 @@ -1828,9 +1872,6 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * if (received >= 0) { DEBUG_LOG(SCENET, "sceNetAdhocPdpRecv[%i:%u]: Received %u bytes from %s:%u\n", id, getLocalPort(pdpsocket.id), received, ip2str(sin.sin_addr).c_str(), ntohs(sin.sin_port)); - // Peer MAC - SceNetEtherAddr mac; - // Find Peer MAC if (resolveIP(sin.sin_addr.s_addr, &mac)) { // Provide Sender Information @@ -1852,18 +1893,18 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * // Return Success. According to pspsdk-1.0+beta2 returned value is Number of bytes received, but JPCSP returning 0? return 0; //received; // Returning number of bytes received will cause KH BBS unable to see the game event/room } - // Unknown Peer, let's not give any data - else { - //*len = 0; // received; // Is this going to be okay since saddr may not be valid? - WARN_LOG(SCENET, "sceNetAdhocPdpRecv[%i:%u]: Received %i bytes from Unknown Peer %s:%u", id, getLocalPort(pdpsocket.id), received, ip2str(sin.sin_addr).c_str(), ntohs(sin.sin_port)); - } + // Free Network Lock //_freeNetworkLock(); //free(tmpbuf); - //Receiving data from unknown peer, ignore it ? - //return ERROR_NET_ADHOC_WOULD_BLOCK; //ERROR_NET_ADHOC_NO_DATA_AVAILABLE + // Receiving data from unknown peer? Should never reached here! Unless the Peeked's packet was different than the Recved one (which mean there is a problem) + WARN_LOG(SCENET, "sceNetAdhocPdpRecv[%i:%u]: Received %i bytes from Unknown Peer %s:%u", id, getLocalPort(pdpsocket.id), received, ip2str(sin.sin_addr).c_str(), ntohs(sin.sin_port)); + if (flag) { + VERBOSE_LOG(SCENET, "%08x=sceNetAdhocPdpRecv: would block (problem)", ERROR_NET_ADHOC_WOULD_BLOCK); // Temporary fix to avoid a crash on the Logs due to trying to Logs syscall's argument from another thread (ie. AdhocMatchingInput thread) + return ERROR_NET_ADHOC_WOULD_BLOCK; // hleLogSuccessVerboseX(SCENET, ERROR_NET_ADHOC_WOULD_BLOCK, "would block (problem)"); + } } // Free Network Lock @@ -1876,8 +1917,8 @@ static int sceNetAdhocPdpRecv(int id, void *addr, void * port, void *buf, void * DEBUG_LOG(SCENET, "sceNetAdhocPdpRecv[%i:%u]: Result:%i (Error:%i)", id, pdpsocket.lport, received, error); - // Timeout? - return hleLogError(SCENET, ERROR_NET_ADHOC_TIMEOUT, "timeout"); + // Unexpected error (other than EAGAIN/EWOULDBLOCK/ECONNRESET) or in case the Peeked's packet was different than Recved one, treated as Timeout? + return hleLogError(SCENET, ERROR_NET_ADHOC_TIMEOUT, "timeout?"); } // Invalid Argument From 3b8eb6b04e210bf122618f3c177b345f01696127 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Wed, 8 Dec 2021 08:36:46 +0700 Subject: [PATCH 4/6] Added a note regarding FIONREAD behavior on different platforms. --- Core/HLE/proAdhoc.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Core/HLE/proAdhoc.cpp b/Core/HLE/proAdhoc.cpp index ba92142d7a..94b5fe2058 100644 --- a/Core/HLE/proAdhoc.cpp +++ b/Core/HLE/proAdhoc.cpp @@ -1941,7 +1941,8 @@ uint16_t getLocalPort(int sock) { u_long getAvailToRecv(int sock, int udpBufferSize) { u_long n = 0; // Typical MTU size is 1500 int err = -1; -#if defined(_WIN32) // May not be available on all platform + // Note: FIONREAD may have different behavior depends on the platform, according to https://stackoverflow.com/questions/9278189/how-do-i-get-amount-of-queued-data-for-udp-socket/9296481#9296481 +#if defined(_WIN32) err = ioctlsocket(sock, FIONREAD, &n); #else err = ioctl(sock, FIONREAD, &n); @@ -1950,6 +1951,7 @@ u_long getAvailToRecv(int sock, int udpBufferSize) { return 0; if (udpBufferSize > 0 && n > 0) { + // TODO: May need to filter out packets from an IP that can't be translated to MAC address // TODO: Cap number of bytes of full DGRAM message(s) up to buffer size, but may cause Warriors Orochi 2 to get FPS drops } return n; From 004ecc008e00af40c4c87cc807cb58f4b221348c Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Wed, 24 Nov 2021 23:44:52 +0700 Subject: [PATCH 5/6] Updated GetPdpStat --- Core/HLE/sceNetAdhoc.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index dd2800a935..bf45b982b7 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -3058,6 +3058,18 @@ static int sceNetAdhocGetPdpStat(u32 structSize, u32 structAddr) { // It seems real PSP respecting the socket buffer size arg, so we may need to cap the value up to the buffer size arg since we use larger buffer, for PDP/UDP the total size must not contains partial/truncated message to avoid data loss. // TODO: We may need to manage PDP messages ourself by reading each msg 1-by-1 and moving it to our internal buffer(msg array) in order to calculate the correct messages size that can fit into buffer size when there are more than 1 messages in the recv buffer (simulate FIONREAD) sock->data.pdp.rcv_sb_cc = getAvailToRecv(sock->data.pdp.id, sock->buffer_size); + // There might be a possibility for the data to be taken by the OS, thus FIONREAD returns 0, but can be Received + if (sock->data.pdp.rcv_sb_cc == 0) { + // Let's try to peek the data size + // TODO: May need to filter out packets from an IP that can't be translated to MAC address + struct sockaddr_in sin; + socklen_t sinlen; + sinlen = sizeof(sin); + memset(&sin, 0, sinlen); + int received = recvfrom(sock->data.pdp.id, dummyPeekBuf64k, std::min((u32)dummyPeekBuf64kSize, sock->buffer_size), MSG_PEEK | MSG_NOSIGNAL, (struct sockaddr*)&sin, &sinlen); + if (received > 0) + sock->data.pdp.rcv_sb_cc = received; + } // Copy Socket Data from Internal Memory memcpy(&buf[i], &sock->data.pdp, sizeof(SceNetAdhocPdpStat)); @@ -3082,16 +3094,17 @@ static int sceNetAdhocGetPdpStat(u32 structSize, u32 structAddr) { // Update Buffer Length *buflen = i * sizeof(SceNetAdhocPdpStat); + hleEatMicro(50); // Not sure how long it supposed to take // Success return 0; } // Invalid Arguments - return ERROR_NET_ADHOC_INVALID_ARG; + return hleLogSuccessVerboseX(SCENET, ERROR_NET_ADHOC_INVALID_ARG, "invalid arg, at %08x", currentMIPS->pc); } // Library is uninitialized - return ERROR_NET_ADHOC_NOT_INITIALIZED; + return hleLogSuccessVerboseX(SCENET, ERROR_NET_ADHOC_NOT_INITIALIZED, "not initialized, at %08x", currentMIPS->pc); } From 26fd74edd49553356a7d6a3793ac28e0f34aca39 Mon Sep 17 00:00:00 2001 From: ANR2ME Date: Wed, 8 Dec 2021 08:44:54 +0700 Subject: [PATCH 6/6] Updated GetPtpStat --- Core/HLE/sceNetAdhoc.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Core/HLE/sceNetAdhoc.cpp b/Core/HLE/sceNetAdhoc.cpp index bf45b982b7..25c18e7cdf 100644 --- a/Core/HLE/sceNetAdhoc.cpp +++ b/Core/HLE/sceNetAdhoc.cpp @@ -3165,6 +3165,13 @@ static int sceNetAdhocGetPtpStat(u32 structSize, u32 structAddr) { sock->data.ptp.rcv_sb_cc = getAvailToRecv(sock->data.ptp.id); // It seems real PSP respecting the socket buffer size arg, so we may need to cap the value to the buffer size arg since we use larger buffer sock->data.ptp.rcv_sb_cc = std::min(sock->data.ptp.rcv_sb_cc, (u32_le)sock->buffer_size); + // There might be a possibility for the data to be taken by the OS, thus FIONREAD returns 0, but can be Received + if (sock->data.ptp.rcv_sb_cc == 0) { + // Let's try to peek the data size + int received = recv(sock->data.ptp.id, dummyPeekBuf64k, std::min((u32)dummyPeekBuf64kSize, sock->buffer_size), MSG_PEEK | MSG_NOSIGNAL); + if (received > 0) + sock->data.ptp.rcv_sb_cc = received; + } // Copy Socket Data from internal Memory memcpy(&buf[i], &sock->data.ptp, sizeof(SceNetAdhocPtpStat)); @@ -3195,11 +3202,11 @@ static int sceNetAdhocGetPtpStat(u32 structSize, u32 structAddr) { } // Invalid Arguments - return ERROR_NET_ADHOC_INVALID_ARG; + return hleLogSuccessVerboseX(SCENET, ERROR_NET_ADHOC_INVALID_ARG, "invalid arg, at %08x", currentMIPS->pc); } // Library is uninitialized - return ERROR_NET_ADHOC_NOT_INITIALIZED; + return hleLogSuccessVerboseX(SCENET, ERROR_NET_ADHOC_NOT_INITIALIZED, "not initialized, at %08x", currentMIPS->pc); }