From 82fcc0e3f7ea63281c34973a5b853ea0092ce2ed Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Sat, 26 Apr 2025 00:08:59 +0300 Subject: [PATCH] sceNetRecv,sceNetRecvFrom,sceNetRecvMsg RE --- src/core/libraries/network/net.cpp | 131 +++++++++++++++++++++++-- src/core/libraries/network/net.h | 8 +- src/core/libraries/network/sys_net.cpp | 7 ++ src/core/libraries/network/sys_net.h | 4 +- 4 files changed, 135 insertions(+), 15 deletions(-) diff --git a/src/core/libraries/network/net.cpp b/src/core/libraries/network/net.cpp index 6b3168206..1f024277f 100644 --- a/src/core/libraries/network/net.cpp +++ b/src/core/libraries/network/net.cpp @@ -1103,20 +1103,131 @@ int PS4_SYSV_ABI sceNetPppoeStop() { return ORBIS_OK; } -int PS4_SYSV_ABI sceNetRecv() { - LOG_ERROR(Lib_Net, "(STUBBED) called"); - return ORBIS_OK; +int PS4_SYSV_ABI sceNetRecv(OrbisNetId s, void* buf, u64 len, int flags) { + if (!g_isNetInitialized) { + return ORBIS_NET_ERROR_ENOTINIT; + } + int result; + int err; + int positiveErr; + + do { + result = sys_recvfrom(s, buf, len, flags | 0x40000000, nullptr, 0); + + if (result >= 0) { + return result; // Success + } + + err = *Libraries::Kernel::__Error(); // Standard errno + + // Convert to positive error for comparison + int positiveErr = (err < 0) ? -err : err; + + if ((positiveErr & 0xfff0000) != 0) { + // Unknown/fatal error range + *sceNetErrnoLoc() = ORBIS_NET_ERETURN; + return -positiveErr; + } + + // Retry if interrupted + } while (positiveErr == ORBIS_NET_EINTR); + + if (positiveErr == ORBIS_NET_EADDRINUSE) { + result = -ORBIS_NET_EBADF; + } else if (positiveErr == ORBIS_NET_EALREADY) { + result = -ORBIS_NET_EINTR; + } else { + result = -positiveErr; + } + + *sceNetErrnoLoc() = -result; + + return (-result) | ORBIS_NET_ERROR_BASE; // Convert to official ORBIS_NET_ERROR code } -int PS4_SYSV_ABI sceNetRecvfrom(OrbisNetId s, void* buf, size_t len, int flags, - OrbisNetSockaddr* addr, u32* paddrlen) { - LOG_ERROR(Lib_Net, "(STUBBED) called"); - return ORBIS_OK; +int PS4_SYSV_ABI sceNetRecvfrom(OrbisNetId s, void* buf, u64 len, int flags, OrbisNetSockaddr* addr, + u32* paddrlen) { + if (!g_isNetInitialized) { + return ORBIS_NET_ERROR_ENOTINIT; + } + int result; + int err; + int positiveErr; + + do { + result = sys_recvfrom(s, buf, len, flags | 0x40000000, addr, paddrlen); + + if (result >= 0) { + return result; // Success + } + + err = *Libraries::Kernel::__Error(); // Standard errno + + // Convert to positive error for comparison + int positiveErr = (err < 0) ? -err : err; + + if ((positiveErr & 0xfff0000) != 0) { + // Unknown/fatal error range + *sceNetErrnoLoc() = ORBIS_NET_ERETURN; + return -positiveErr; + } + + // Retry if interrupted + } while (positiveErr == ORBIS_NET_EINTR); + + if (positiveErr == ORBIS_NET_EADDRINUSE) { + result = -ORBIS_NET_EBADF; + } else if (positiveErr == ORBIS_NET_EALREADY) { + result = -ORBIS_NET_EINTR; + } else { + result = -positiveErr; + } + + *sceNetErrnoLoc() = -result; + + return (-result) | ORBIS_NET_ERROR_BASE; // Convert to official ORBIS_NET_ERROR code } -int PS4_SYSV_ABI sceNetRecvmsg() { - LOG_ERROR(Lib_Net, "(STUBBED) called"); - return ORBIS_OK; +int PS4_SYSV_ABI sceNetRecvmsg(OrbisNetId s, OrbisNetMsghdr* msg, int flags) { + if (!g_isNetInitialized) { + return ORBIS_NET_ERROR_ENOTINIT; + } + int result; + int err; + int positiveErr; + + do { + result = sys_recvmsg(s, msg, flags | 0x40000000); + + if (result >= 0) { + return result; // Success + } + + err = *Libraries::Kernel::__Error(); // Standard errno + + // Convert to positive error for comparison + int positiveErr = (err < 0) ? -err : err; + + if ((positiveErr & 0xfff0000) != 0) { + // Unknown/fatal error range + *sceNetErrnoLoc() = ORBIS_NET_ERETURN; + return -positiveErr; + } + + // Retry if interrupted + } while (positiveErr == ORBIS_NET_EINTR); + + if (positiveErr == ORBIS_NET_EADDRINUSE) { + result = -ORBIS_NET_EBADF; + } else if (positiveErr == ORBIS_NET_EALREADY) { + result = -ORBIS_NET_EINTR; + } else { + result = -positiveErr; + } + + *sceNetErrnoLoc() = -result; + + return (-result) | ORBIS_NET_ERROR_BASE; // Convert to official ORBIS_NET_ERROR code } int PS4_SYSV_ABI sceNetResolverAbort() { diff --git a/src/core/libraries/network/net.h b/src/core/libraries/network/net.h index ed5721f57..06ccb27d1 100644 --- a/src/core/libraries/network/net.h +++ b/src/core/libraries/network/net.h @@ -203,10 +203,10 @@ int PS4_SYSV_ABI sceNetPoolCreate(const char* name, int size, int flags); int PS4_SYSV_ABI sceNetPoolDestroy(); int PS4_SYSV_ABI sceNetPppoeStart(); int PS4_SYSV_ABI sceNetPppoeStop(); -int PS4_SYSV_ABI sceNetRecv(); -int PS4_SYSV_ABI sceNetRecvfrom(OrbisNetId s, void* buf, size_t len, int flags, - OrbisNetSockaddr* addr, u32* paddrlen); -int PS4_SYSV_ABI sceNetRecvmsg(); +int PS4_SYSV_ABI sceNetRecv(OrbisNetId s, void* buf, u64 len, int flags); +int PS4_SYSV_ABI sceNetRecvfrom(OrbisNetId s, void* buf, u64 len, int flags, OrbisNetSockaddr* addr, + u32* paddrlen); +int PS4_SYSV_ABI sceNetRecvmsg(OrbisNetId s, OrbisNetMsghdr* msg, int flags); int PS4_SYSV_ABI sceNetResolverAbort(); int PS4_SYSV_ABI sceNetResolverConnect(); int PS4_SYSV_ABI sceNetResolverConnectAbort(); diff --git a/src/core/libraries/network/sys_net.cpp b/src/core/libraries/network/sys_net.cpp index f6073c578..9a91a3325 100644 --- a/src/core/libraries/network/sys_net.cpp +++ b/src/core/libraries/network/sys_net.cpp @@ -48,4 +48,11 @@ int sys_sendto(OrbisNetId s, const void* buf, u64 len, int flags, const OrbisNet int sys_sendmsg(OrbisNetId s, const OrbisNetMsghdr* msg, int flags) { return -1; } +int sys_recvfrom(OrbisNetId s, void* buf, u64 len, int flags, OrbisNetSockaddr* addr, + u32* paddrlen) { + return -1; +} +int sys_recvmsg(OrbisNetId s, OrbisNetMsghdr* msg, int flags) { + return -1; +} } // namespace Libraries::Net \ No newline at end of file diff --git a/src/core/libraries/network/sys_net.h b/src/core/libraries/network/sys_net.h index be8286705..012f4c315 100644 --- a/src/core/libraries/network/sys_net.h +++ b/src/core/libraries/network/sys_net.h @@ -23,5 +23,7 @@ int sys_socketclose(OrbisNetId s); int sys_sendto(OrbisNetId s, const void* buf, u64 len, int flags, const OrbisNetSockaddr* addr, u32 addrlen); int sys_sendmsg(OrbisNetId s, const OrbisNetMsghdr* msg, int flags); - +int sys_recvfrom(OrbisNetId s, void* buf, u64 len, int flags, OrbisNetSockaddr* addr, + u32* paddrlen); +int sys_recvmsg(OrbisNetId s, OrbisNetMsghdr* msg, int flags); } // namespace Libraries::Net \ No newline at end of file