#include "prx/libc/include/general/VabiMacros.hpp" #include "SceTypes.hpp" #include #include #include #include extern "C" { int APS5_VABI sceNpGetNpId(int user_id, NpId* np_id); } extern "C" { int APS5_VABI sceNpCreateRequest(void); int APS5_VABI sceNpCreateAsyncRequest(const NpCreateAsyncRequestParameter* param); int APS5_VABI sceNpDeleteRequest(int reqId); int APS5_VABI sceNpSetTimeout(int reqId, std::int32_t resolveRetry, std::uint32_t resolveTimeout, std::uint32_t connTimeout, std::uint32_t sendTimeout, std::uint32_t recvTimeout); } namespace { constexpr int InvalidArgument = static_cast(0x80550003u); constexpr int SignedOut = static_cast(0x80550006u); constexpr int RequestNotFound = static_cast(0x80550014u); void Require(bool condition, const char* message) { if (!condition) { std::fprintf(stderr, "NpManager: %s\n", message); std::abort(); } } void CheckRequestTimeouts() { Require(sceNpSetTimeout(0x7fffffff, 2, 0, 0, 0, 0) == RequestNotFound, "never created request"); Require(sceNpSetTimeout(0x7fffffff, 0, 0, 0, 0, 0) == InvalidArgument, "arguments checked before the request"); const int requestId = sceNpCreateRequest(); Require(requestId > 0, "sceNpCreateRequest must return a positive request id"); Require(sceNpSetTimeout(requestId, 2, 1000000, 10000000, 10000000, 10000000) == 0, "minimum timeouts"); Require(sceNpSetTimeout(requestId, 0, 0, 0, 0, 30000000) == 0, "only the receive timeout"); Require(sceNpSetTimeout(requestId, 3, 0, 0, 0, 0) == 0, "only the resolve retries"); Require(sceNpSetTimeout(requestId, 0, 0, 0, 0, 0) == InvalidArgument, "every value left at its default"); Require(sceNpSetTimeout(0, 2, 0, 0, 0, 0) == InvalidArgument, "request id 0"); Require(sceNpSetTimeout(-1, 2, 0, 0, 0, 0) == InvalidArgument, "negative request id"); Require(sceNpSetTimeout(requestId, -1, 0, 0, 0, 30000000) == InvalidArgument, "negative resolve retries"); Require(sceNpSetTimeout(requestId, 0, 999999, 0, 0, 0) == InvalidArgument, "resolve timeout below 1 s"); Require(sceNpSetTimeout(requestId, 0, 0, 9999999, 0, 0) == InvalidArgument, "connect timeout below 10 s"); Require(sceNpSetTimeout(requestId, 0, 0, 0, 9999999, 0) == InvalidArgument, "send timeout below 10 s"); Require(sceNpSetTimeout(requestId, 0, 0, 0, 0, 1) == InvalidArgument, "receive timeout below 10 s"); Require(sceNpDeleteRequest(requestId) == 0, "sceNpDeleteRequest failed"); Require(sceNpSetTimeout(requestId, 2, 0, 0, 0, 0) == RequestNotFound, "deleted request"); NpCreateAsyncRequestParameter param{}; const int asyncId = sceNpCreateAsyncRequest(¶m); Require(asyncId > 0, "sceNpCreateAsyncRequest must return a positive request id"); Require(sceNpSetTimeout(asyncId, 2, 0, 0, 0, 0) == 0, "async request"); Require(sceNpDeleteRequest(asyncId) == 0, "sceNpDeleteRequest failed on the async request"); Require(sceNpSetTimeout(asyncId, 2, 0, 0, 0, 0) == RequestNotFound, "deleted async request"); } } int main() { CheckRequestTimeouts(); NpId npId{}; std::memset(&npId, 0x5a, sizeof(npId)); NpId untouched{}; std::memset(&untouched, 0x5a, sizeof(untouched)); Require(sceNpGetNpId(0x10000, &npId) == SignedOut, "sceNpGetNpId must report the user as signed out"); Require(std::memcmp(&npId, &untouched, sizeof(npId)) == 0, "sceNpGetNpId must leave the NpId untouched"); Require(sceNpGetNpId(0x10000, nullptr) == InvalidArgument, "sceNpGetNpId must reject a null NpId"); return 0; }