use alloc::{borrow::ToOwned, string::String};
use thiserror::Error;
#[derive(Debug, Clone, PartialEq, Eq, Error)]
#[must_use]
pub enum NetError {
#[error("Failed to load module {}: {}", 0, 1)]
LoadModuleFailed(String, i32),
#[error("Failed to initialize {}: {}", 0, 1)]
InitFailed(String, i32),
#[error("{}: {}", 0, 1)]
Error(String, i32),
#[error("Net config does not exist")]
NetConfigNotExist,
#[error("Timeout")]
Timeout,
}
impl NetError {
pub fn load_module_failed(module: &str, error: i32) -> Self {
NetError::LoadModuleFailed(module.to_owned(), error)
}
pub fn init_failed(fn_name: &str, error: i32) -> Self {
NetError::InitFailed(fn_name.to_owned(), error)
}
pub fn error(fn_name: &str, error: i32) -> Self {
NetError::Error(fn_name.to_owned(), error)
}
}
#[allow(unused)]
#[inline]
pub fn load_net_modules() -> Result<(), NetError> {
unsafe {
let res = psp::sys::sceUtilityLoadNetModule(psp::sys::NetModule::NetCommon);
if res != 0 {
return Err(NetError::load_module_failed("", res));
}
let res = psp::sys::sceUtilityLoadNetModule(psp::sys::NetModule::NetInet);
if res != 0 {
return Err(NetError::load_module_failed("", res));
}
let res = psp::sys::sceUtilityLoadNetModule(psp::sys::NetModule::NetParseUri);
if res != 0 {
return Err(NetError::load_module_failed("", res));
}
let res = psp::sys::sceUtilityLoadNetModule(psp::sys::NetModule::NetHttp);
if res != 0 {
return Err(NetError::load_module_failed("", res));
}
Ok(())
}
}
#[allow(unused)]
#[inline]
pub fn net_init() -> Result<(), NetError> {
unsafe {
let res = psp::sys::sceNetInit(0x20000, 0x20, 0x1000, 0x20, 0x1000);
if res != 0 {
return Err(NetError::init_failed("sceNetInit", res));
}
let res = psp::sys::sceNetInetInit();
if res != 0 {
return Err(NetError::init_failed("sceNetInetInit", res));
}
let res = psp::sys::sceNetResolverInit();
if res != 0 {
return Err(NetError::init_failed("sceNetResolverInit", res));
}
let res = psp::sys::sceNetApctlInit(0x1600, 42);
if res != 0 {
return Err(NetError::init_failed("sceNetApctlInit", res));
}
}
Ok(())
}
#[allow(unused)]
#[inline]
pub fn check_netconfig_existence(id: i32) -> Result<(), NetError> {
unsafe {
let res = psp::sys::sceUtilityCheckNetParam(id);
if res != 0 {
return Err(NetError::NetConfigNotExist);
}
}
Ok(())
}
#[allow(unused)]
#[inline]
pub fn check_first_netconfig_existence() -> Result<(), NetError> {
check_netconfig_existence(1)
}
pub fn init_connection_to_access_point(connection_id: i32) -> Result<(), NetError> {
unsafe {
let res = psp::sys::sceNetApctlConnect(connection_id);
if res != 0 {
return Err(NetError::error("sceNetApctlConnect", res));
}
}
Ok(())
}
#[inline]
pub fn block_until_connected(desist_after: usize) -> Result<(), NetError> {
let mut state: psp::sys::ApctlState = unsafe { core::mem::zeroed() };
for _ in 0..desist_after {
unsafe {
let err = psp::sys::sceNetApctlGetState(&mut state);
if err != 0 {
return Err(NetError::error("sceNetApctlGetState", err));
}
}
if let psp::sys::ApctlState::GotIp = state {
return Ok(());
}
unsafe { psp::sys::sceKernelDelayThread(50_000) };
}
Err(NetError::Timeout)
}