feat(libSceRudp): implement sceRudpGetMaxSegmentSize

This commit is contained in:
overlordxrz-source 2026-10-12 02:39:50 +00:00
parent 6253883dee
commit 4b378a251f
3 changed files with 33 additions and 11 deletions

View File

@ -25,6 +25,7 @@ constexpr int RUDP_POOL_MIN_SIZE = 0xC58;
constexpr std::uintptr_t RUDP_POOL_ALIGNMENT = 8;
constexpr std::size_t RUDP_STATUS_SIZE = 0xF8;
constexpr std::size_t RUDP_STATUS_CURRENT_CONTEXTS = 0x64;
constexpr uint16_t RUDP_MAX_SEGMENT_SIZE = 1410;
using GuestRudpEventHandler = void(APS5_VABI*)(int, int, int, void*);
@ -273,8 +274,15 @@ int APS5_VABI sceRudpNetReceived(void) {
return 0;
}
int APS5_VABI sceRudpGetMaxSegmentSize(void) {
NotImplemented_nid_no_patch(__func__);
int APS5_VABI sceRudpGetMaxSegmentSize(uint16_t* size) {
std::lock_guard<std::mutex> lk(g_mutex);
if (!g_inited) {
return RUDP_ERROR_NOT_INITIALIZED;
}
if (size == nullptr) {
return RUDP_ERROR_INVALID_ARGUMENT;
}
*size = RUDP_MAX_SEGMENT_SIZE;
return 0;
}

View File

@ -11,7 +11,7 @@ int APS5_VABI sceRudpInit_nid_postfix(void*, int);
int APS5_VABI sceRudpTerminate();
int APS5_VABI sceRudpProcessEvents();
int APS5_VABI sceRudpNetFlush();
int APS5_VABI sceRudpGetMaxSegmentSize();
int APS5_VABI sceRudpGetMaxSegmentSize(std::uint16_t*);
int APS5_VABI sceRudpNetReceived();
}
@ -25,23 +25,36 @@ static void Require(bool value, int line) {
int main() {
constexpr int notInitialized = static_cast<int>(0x80770001);
constexpr int invalidArgument = static_cast<int>(0x80770004);
std::uint16_t segmentSize = 0x5a5a;
CHECK(sceRudpProcessEvents() == notInitialized);
CHECK(sceRudpNetFlush() == notInitialized);
CHECK(sceRudpGetMaxSegmentSize(&segmentSize) == notInitialized);
CHECK(segmentSize == 0x5a5a);
CHECK(sceRudpGetMaxSegmentSize(nullptr) == notInitialized);
alignas(8) static unsigned char pool[0xC58];
CHECK(sceRudpInit_nid_postfix(pool, sizeof(pool)) == 0);
CHECK(sceRudpProcessEvents() == 0);
CHECK(sceRudpNetFlush() == 0);
CHECK(sceRudpGetMaxSegmentSize(nullptr) == invalidArgument);
CHECK(sceRudpGetMaxSegmentSize(&segmentSize) == 0);
CHECK(segmentSize == 1410);
std::uint16_t segment[3] = {0, 0, 0x5a5a};
CHECK(sceRudpGetMaxSegmentSize(&segment[1]) == 0);
CHECK(segment[0] == 0 && segment[1] == 1410 && segment[2] == 0x5a5a);
CHECK(sceRudpTerminate() == 0);
for (const auto call : {&sceRudpNetReceived, &sceRudpGetMaxSegmentSize}) {
bool threw = false;
try {
call();
} catch (const std::runtime_error&) {
threw = true;
}
CHECK(threw);
segmentSize = 0x5a5a;
CHECK(sceRudpGetMaxSegmentSize(&segmentSize) == notInitialized);
CHECK(segmentSize == 0x5a5a);
bool threw = false;
try {
sceRudpNetReceived();
} catch (const std::runtime_error&) {
threw = true;
}
CHECK(threw);
return 0;
}

View File

@ -73,6 +73,7 @@ Throughout the project, every function at every stage either **does exactly what
- [sceNpEntitlementAccessGetEntitlementKey](../../core/libs/prx/libSceNpEntitlementAccess/Export.cpp) - the three-argument signature, 16-byte key and errors `0x817D0002`/`0x817D0007` follow [KytyPS5](https://github.com/KytyPS5/KytyPS5/blob/main/src/libs/libNet.cpp); PPSA01521 passes a service label, entitlement label and output pointer. Only the no-key path is implemented: local entitlement labels carry no keys, and the output is untouched on failure. Console error precedence and key provisioning are unverified
- [sceNpEntitlementAccess{Request,Poll}{Unified,Service}EntitlementInfo{,List}](../../core/libs/prx/libSceNpEntitlementAccess/Export.cpp) - signatures unknown; no reference implements them, so they are declared without parameters. The single-item variants copy the behaviour of the list ones, with no source of their own. Like the consume requests in the same library, they report the signed-out NP state with `SCE_NP_ERROR_SIGNED_OUT` (`0x80550006`) and write nothing. PPSA15657 calls the unified request during start-up and continues past the error. Whether the console fails at the request or at the poll when signed out is unverified
- [sceRudpGetStatus](../../core/libs/prx/libSceRudp/Export.cpp) - PPSA01521 passes an output pointer and byte count `0xF8`. Measured on a PS5 (firmware 13.60): the status is 0xF8 bytes; before `sceRudpInit` every call returns `RUDP_ERROR_NOT_INITIALIZED`, and after it a null pointer or a byte count of 0 or above 0xF8 returns `RUDP_ERROR_INVALID_ARGUMENT`. The layout matches `SceRudpStatus` in [Vita3K](https://github.com/AndnixSH/Vita3K-PS-Vita-OS-Fork/blob/master/vita3k/modules/SceRudp/SceLibRudp.cpp) with `currentContexts` at 0x64 and `allocs`, `frees`, `memCurrent` and `memPeak` at 0xC8 to 0xD4. Only `currentContexts` is reported: the traffic counters stay 0 because nothing is sent, and the allocator counters stay 0 because the library does not allocate from the title's pool (the console reports 6 allocations and 0x1260 bytes right after `sceRudpInit`, and 4 more allocations and 0x3F0 bytes per context). The console also writes `currentContexts` and the allocator counters when the byte count is smaller than their offset; only the requested bytes are written here.
- [sceRudpGetMaxSegmentSize](../../core/libs/prx/libSceRudp/Export.cpp) (libSceRudp) - measured on a PS5 (firmware 13.60) in #3073: before `sceRudpInit` it returns `RUDP_ERROR_NOT_INITIALIZED` and leaves the value untouched, also for a null pointer; after it a null pointer returns `RUDP_ERROR_INVALID_ARGUMENT` and a valid one gets 1410 with result 0. The library keeps no configurable segment size (there is no `sceRudpSetMaxSegmentSize`), so 1410 is always reported. The `uint16_t*` parameter is inferred: the measurement does not show how many bytes the console writes, PPSA03490 passes a pointer to a 16-bit value and [RPCS3](https://github.com/RPCS3/rpcs3/blob/master/rpcs3/Emu/Cell/Modules/cellRudp.cpp) declares the PS3 `cellRudpSetMaxSegmentSize(u16 mss)`, so only 16 bits are written
- [sceHttpSetCookieEnabled](../../core/libs/prx/libSceHttp/Export.cpp) - the two-argument signature and 0/1 enable values follow [VitaSDK](https://github.com/vitasdk/vita-headers/blob/master/include/psp2/net/http.h) and [shadPS4](https://github.com/shadps4-emu/shadPS4/blob/main/src/core/libraries/network/http.cpp); PPSA01521 passes 0 to disable cookies. Disabling succeeds because the offline HTTP backend has no cookie engine; enabling throws. Invalid enable values use the same error as `sceHttpSetInflateGZIPEnabled`. Like the existing offline HTTP setters, the handle is not validated; requests still fail with the network error. Console behavior is unverified
- [sceHmd2Initialize](../../core/libs/prx/libSceHmd2/Export.cpp) (libSceHmd2) - the error the console returns when the PS VR2 runtime is unavailable is unknown; it returns libSceHmd's `UNSUPPORTED_FEATURE` (0x81110016). PPSA01317 passes a pointer to 16 zeroed bytes and only tests the result for non-zero