AnyPS5/core/libs/tests/GuestUsbd.cpp

65 lines
2.0 KiB
C++

#include "prx/libc/include/general/VabiMacros.hpp"
#include <chrono>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <stdexcept>
namespace {
struct UsbdTimeval {
std::int64_t seconds;
std::int64_t microseconds;
};
}
extern "C" {
std::int32_t APS5_VABI sceUsbdInit();
void APS5_VABI sceUsbdExit();
std::int64_t APS5_VABI sceUsbdGetDeviceList(void*** list);
void APS5_VABI sceUsbdFreeDeviceList(void** list, std::int32_t unrefDevices);
std::int32_t APS5_VABI sceUsbdHandleEventsTimeout(const UsbdTimeval* timeout);
int APS5_VABI sceUsbdOpen();
}
namespace {
constexpr std::int32_t invalidArgument = static_cast<std::int32_t>(0x80240002);
void Require(bool condition, const char* message) {
if (!condition) {
std::fprintf(stderr, "USBD: %s\n", message);
std::abort();
}
}
}
int main() {
Require(sceUsbdInit() == 0, "initialization failed");
void** list = nullptr;
Require(sceUsbdGetDeviceList(&list) == 0, "a device was listed");
Require(list != nullptr && list[0] == nullptr, "device list is not an empty null-terminated array");
sceUsbdFreeDeviceList(list, 1);
Require(sceUsbdGetDeviceList(nullptr) == invalidArgument, "null list accepted");
Require(sceUsbdHandleEventsTimeout(nullptr) == invalidArgument, "null timeout accepted");
const UsbdTimeval invalid{0, 1000000};
Require(sceUsbdHandleEventsTimeout(&invalid) == invalidArgument, "out-of-range microseconds accepted");
const UsbdTimeval timeout{0, 50000};
const auto start = std::chrono::steady_clock::now();
Require(sceUsbdHandleEventsTimeout(&timeout) == 0, "event handling failed");
Require(std::chrono::steady_clock::now() - start >= std::chrono::milliseconds(45), "event handling returned before the timeout");
bool threw = false;
try {
sceUsbdOpen();
} catch (const std::runtime_error&) {
threw = true;
}
Require(threw, "opening a device did not throw");
sceUsbdExit();
std::puts("USBD tests passed");
return 0;
}