1use alloc::{borrow::ToOwned, string::String};
2use thiserror::Error;
3
4#[derive(Debug, Clone, PartialEq, Eq, Error)]
6#[must_use]
7pub enum NetError {
8 #[error("Failed to load module {}: {}", 0, 1)]
10 LoadModuleFailed(String, i32),
11 #[error("Failed to initialize {}: {}", 0, 1)]
13 InitFailed(String, i32),
14 #[error("{}: {}", 0, 1)]
16 Error(String, i32),
17 #[error("Net config does not exist")]
19 NetConfigNotExist,
20 #[error("Timeout")]
22 Timeout,
23}
24
25impl NetError {
26 pub fn load_module_failed(module: &str, error: i32) -> Self {
27 NetError::LoadModuleFailed(module.to_owned(), error)
28 }
29
30 pub fn init_failed(fn_name: &str, error: i32) -> Self {
31 NetError::InitFailed(fn_name.to_owned(), error)
32 }
33
34 pub fn error(fn_name: &str, error: i32) -> Self {
35 NetError::Error(fn_name.to_owned(), error)
36 }
37}
38
39#[allow(unused)]
44#[inline]
45pub fn load_net_modules() -> Result<(), NetError> {
46 unsafe {
47 let res = psp::sys::sceUtilityLoadNetModule(psp::sys::NetModule::NetCommon);
48 if res != 0 {
49 return Err(NetError::load_module_failed("", res));
50 }
51
52 let res = psp::sys::sceUtilityLoadNetModule(psp::sys::NetModule::NetInet);
53 if res != 0 {
54 return Err(NetError::load_module_failed("", res));
55 }
56
57 let res = psp::sys::sceUtilityLoadNetModule(psp::sys::NetModule::NetParseUri);
58 if res != 0 {
59 return Err(NetError::load_module_failed("", res));
60 }
61
62 let res = psp::sys::sceUtilityLoadNetModule(psp::sys::NetModule::NetHttp);
63 if res != 0 {
64 return Err(NetError::load_module_failed("", res));
65 }
66
67 Ok(())
68 }
69}
70
71#[allow(unused)]
76#[inline]
77pub fn net_init() -> Result<(), NetError> {
78 unsafe {
79 let res = psp::sys::sceNetInit(0x20000, 0x20, 0x1000, 0x20, 0x1000);
80 if res != 0 {
81 return Err(NetError::init_failed("sceNetInit", res));
82 }
83
84 let res = psp::sys::sceNetInetInit();
85 if res != 0 {
86 return Err(NetError::init_failed("sceNetInetInit", res));
87 }
88
89 let res = psp::sys::sceNetResolverInit();
90 if res != 0 {
91 return Err(NetError::init_failed("sceNetResolverInit", res));
92 }
93
94 let res = psp::sys::sceNetApctlInit(0x1600, 42);
95 if res != 0 {
96 return Err(NetError::init_failed("sceNetApctlInit", res));
97 }
98 }
99
100 Ok(())
101}
102
103#[allow(unused)]
114#[inline]
115pub fn check_netconfig_existence(id: i32) -> Result<(), NetError> {
116 unsafe {
117 let res = psp::sys::sceUtilityCheckNetParam(id);
118 if res != 0 {
119 return Err(NetError::NetConfigNotExist);
120 }
121 }
122
123 Ok(())
124}
125
126#[allow(unused)]
131#[inline]
132pub fn check_first_netconfig_existence() -> Result<(), NetError> {
133 check_netconfig_existence(1)
134}
135
136pub fn init_connection_to_access_point(connection_id: i32) -> Result<(), NetError> {
152 unsafe {
153 let res = psp::sys::sceNetApctlConnect(connection_id);
154 if res != 0 {
155 return Err(NetError::error("sceNetApctlConnect", res));
156 }
157 }
158
159 Ok(())
160}
161
162#[inline]
174pub fn block_until_connected(desist_after: usize) -> Result<(), NetError> {
175 let mut state: psp::sys::ApctlState = unsafe { core::mem::zeroed() };
176 for _ in 0..desist_after {
177 unsafe {
178 let err = psp::sys::sceNetApctlGetState(&mut state);
179 if err != 0 {
180 return Err(NetError::error("sceNetApctlGetState", err));
181 }
182 }
183 if let psp::sys::ApctlState::GotIp = state {
184 return Ok(());
185 }
186 unsafe { psp::sys::sceKernelDelayThread(50_000) };
187 }
188
189 Err(NetError::Timeout)
190}