Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions core/libs/prx/libSceRudp/Export.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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*);

Expand Down Expand Up @@ -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;
}

Expand Down
31 changes: 22 additions & 9 deletions core/libs/tests/GuestRudpPump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

Expand All @@ -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;
}
1 change: 1 addition & 0 deletions docs/dev/TechnicalDebt.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading