1#![allow(clippy::module_name_repetitions)]
2
3use alloc::{borrow::ToOwned, vec::Vec};
4use core::net::{IpAddr, Ipv4Addr, SocketAddr};
5use embedded_io::{ErrorType, Read, Write};
6use psp::sys::{self, sockaddr, socklen_t};
7
8use core::ffi::c_void;
9
10use crate::{
11 traits::{
12 io::{EasySocket, Open, OptionType},
13 SocketBuffer,
14 },
15 types::{SocketOptions, SocketRecvFlags, SocketSendFlags},
16};
17
18use super::{
19 super::netc,
20 error::SocketError,
21 sce::SocketFileDescriptor,
22 state::{Bound, Connected, SocketState, Unbound},
23 ToSockaddr, ToSocketAddr,
24};
25
26#[repr(C)]
37#[derive(Clone)]
38pub struct UdpSocket<S: SocketState = Unbound, B: SocketBuffer = Vec<u8>> {
39 fd: SocketFileDescriptor,
41 remote: Option<sockaddr>,
43 buffer: B,
45 send_flags: SocketSendFlags,
47 recv_flags: SocketRecvFlags,
49 _marker: core::marker::PhantomData<S>,
51}
52
53impl UdpSocket {
54 #[allow(dead_code)]
64 pub fn new() -> Result<UdpSocket<Unbound>, SocketError> {
65 let fd = unsafe { sys::sceNetInetSocket(i32::from(netc::AF_INET), netc::SOCK_DGRAM, 0) };
66 if fd < 0 {
67 Err(SocketError::Errno(unsafe { sys::sceNetInetGetErrno() }))
68 } else {
69 let fd = SocketFileDescriptor::new(fd);
70 Ok(UdpSocket {
71 fd,
72 remote: None,
73 buffer: Vec::with_capacity(0),
74 send_flags: SocketSendFlags::empty(),
75 recv_flags: SocketRecvFlags::empty(),
76 _marker: core::marker::PhantomData,
77 })
78 }
79 }
80}
81
82impl<S: SocketState> UdpSocket<S> {
83 fn socket_len() -> socklen_t {
84 core::mem::size_of::<netc::sockaddr>() as u32
85 }
86
87 #[must_use]
89 pub fn fd(&self) -> i32 {
90 *self.fd
91 }
92
93 #[must_use]
95 pub fn remote(&self) -> Option<SocketAddr> {
96 self.remote.map(|sockaddr| sockaddr.to_socket_addr())
97 }
98
99 #[must_use]
101 pub fn send_flags(&self) -> SocketSendFlags {
102 self.send_flags
103 }
104
105 pub fn set_send_flags(&mut self, send_flags: SocketSendFlags) {
107 self.send_flags = send_flags;
108 }
109
110 #[must_use]
112 pub fn recv_flags(&self) -> SocketRecvFlags {
113 self.recv_flags
114 }
115
116 pub fn set_recv_flags(&mut self, recv_flags: SocketRecvFlags) {
118 self.recv_flags = recv_flags;
119 }
120}
121
122impl UdpSocket<Unbound> {
123 fn transition(self, remote: Option<sockaddr>) -> UdpSocket<Bound> {
125 UdpSocket {
126 fd: self.fd,
127 remote,
128 buffer: Vec::with_capacity(0),
129 send_flags: self.send_flags,
130 recv_flags: self.recv_flags,
131 _marker: core::marker::PhantomData,
132 }
133 }
134
135 #[allow(unused)]
147 pub fn bind(mut self, addr: Option<SocketAddr>) -> Result<UdpSocket<Bound>, SocketError> {
148 let default_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0);
149 let addr = addr.unwrap_or(default_addr);
150 match addr {
151 SocketAddr::V4(v4) => {
152 let sockaddr = v4.to_sockaddr();
153
154 if unsafe {
155 sys::sceNetInetBind(
156 *self.fd,
157 &sockaddr,
158 core::mem::size_of::<netc::sockaddr>() as u32,
159 )
160 } != 0
161 {
162 let errno = unsafe { sys::sceNetInetGetErrno() };
163 Err(SocketError::Errno(errno))
164 } else {
165 Ok(self.transition(Some(sockaddr)))
166 }
167 }
168 SocketAddr::V6(_) => Err(SocketError::UnsupportedAddressFamily),
169 }
170 }
171}
172
173impl UdpSocket<Bound> {
174 fn transition(self, remote: sockaddr, buf: Option<Vec<u8>>) -> UdpSocket<Connected> {
176 UdpSocket {
177 fd: self.fd,
178 remote: Some(remote),
179 buffer: buf.unwrap_or_default(),
180 send_flags: self.send_flags,
181 recv_flags: self.recv_flags,
182 _marker: core::marker::PhantomData,
183 }
184 }
185
186 #[allow(unused)]
199 pub fn connect(mut self, addr: SocketAddr) -> Result<UdpSocket<Connected>, SocketError> {
200 match addr {
201 SocketAddr::V4(v4) => {
202 let sockaddr = v4.to_sockaddr();
203
204 if unsafe { sys::sceNetInetConnect(*self.fd, &sockaddr, Self::socket_len()) } != 0 {
205 let errno = unsafe { sys::sceNetInetGetErrno() };
206 Err(SocketError::Errno(errno))
207 } else {
208 Ok(self.transition(sockaddr, None))
209 }
210 }
211 SocketAddr::V6(_) => Err(SocketError::UnsupportedAddressFamily),
212 }
213 }
214
215 #[allow(unused)]
227 pub fn _read_from(
228 mut self,
229 buf: &mut [u8],
230 ) -> Result<(usize, UdpSocket<Connected>), SocketError> {
231 let mut sockaddr = self
232 .remote
233 .ok_or(SocketError::Other("Remote not set".to_owned()))?;
234 let result = unsafe {
235 sys::sceNetInetRecvfrom(
236 *self.fd,
237 buf.as_mut_ptr().cast::<c_void>(),
238 buf.len(),
239 self.recv_flags.as_i32(),
240 &mut sockaddr,
241 &mut Self::socket_len(),
242 )
243 };
244 if result < 0 {
245 Err(SocketError::Errno(unsafe { sys::sceNetInetGetErrno() }))
246 } else {
247 Ok((result as usize, self.transition(sockaddr, None)))
248 }
249 }
250
251 #[allow(unused)]
264 pub fn _write_to(
265 self,
266 buf: &[u8],
267 len: usize,
268 to: SocketAddr,
269 ) -> Result<(usize, UdpSocket<Connected>), SocketError> {
270 let sockaddr = match to {
271 SocketAddr::V4(v4) => Ok(super::socket_addr_v4_to_sockaddr(v4)),
272 SocketAddr::V6(_) => Err(SocketError::UnsupportedAddressFamily),
273 }?;
274 let socklen = core::mem::size_of::<netc::sockaddr>() as u32;
275
276 let mut buffer = Vec::with_capacity(buf.len());
277 buffer.append_buffer(buf);
278
279 let result = unsafe {
280 sys::sceNetInetSendto(
281 *self.fd,
282 buf.as_ptr().cast::<c_void>(),
283 len,
284 self.send_flags.as_i32(),
285 &sockaddr,
286 socklen,
287 )
288 };
289 if result < 0 {
290 Err(SocketError::Errno(unsafe { sys::sceNetInetGetErrno() }))
291 } else {
292 buffer.shift_left_buffer(result as usize);
293 Ok((result as usize, self.transition(sockaddr, Some(buffer))))
294 }
295 }
296}
297
298impl UdpSocket<Connected> {
299 #[allow(unused)]
311 pub fn internal_read(&mut self, buf: &mut [u8]) -> Result<usize, SocketError> {
312 let result = unsafe {
313 sys::sceNetInetRecv(
314 *self.fd,
315 buf.as_mut_ptr().cast::<c_void>(),
316 buf.len(),
317 self.recv_flags.as_i32(),
318 )
319 };
320 if result < 0 {
321 Err(SocketError::Errno(unsafe { sys::sceNetInetGetErrno() }))
322 } else {
323 Ok(result as usize)
324 }
325 }
326
327 #[allow(unused)]
336 pub fn internal_write(&mut self, buf: &[u8]) -> Result<usize, SocketError> {
337 self.buffer.append_buffer(buf);
338 self.send()
339 }
340
341 pub fn internal_flush(&mut self) -> Result<(), SocketError> {
346 while !self.buffer.is_empty() {
347 self.send()?;
348 }
349 Ok(())
350 }
351
352 fn send(&mut self) -> Result<usize, SocketError> {
353 let result = unsafe {
354 sys::sceNetInetSend(
355 *self.fd,
356 self.buffer.as_slice().as_ptr().cast::<c_void>(),
357 self.buffer.len(),
358 self.send_flags.as_i32(),
359 )
360 };
361 if result < 0 {
362 Err(SocketError::Errno(unsafe { sys::sceNetInetGetErrno() }))
363 } else {
364 self.buffer.shift_left_buffer(result as usize);
365 Ok(result as usize)
366 }
367 }
368}
369
370impl<S: SocketState> OptionType for UdpSocket<S> {
371 type Options<'a> = SocketOptions;
372}
373
374impl<S: SocketState> ErrorType for UdpSocket<S> {
375 type Error = SocketError;
376}
377
378impl Open<'_, '_> for UdpSocket<Unbound> {
379 type Return = UdpSocket<Connected>;
380 fn open(self, options: &'_ Self::Options<'_>) -> Result<Self::Return, Self::Error> {
395 let sock = self.bind(None)?;
396 let sock = sock.connect(options.remote())?;
397 Ok(sock)
398 }
399}
400
401impl Read for UdpSocket<Connected> {
402 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
411 self.internal_read(buf)
412 }
413}
414
415impl Write for UdpSocket<Connected> {
416 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
425 self.internal_write(buf)
426 }
427
428 fn flush(&mut self) -> Result<(), Self::Error> {
433 self.internal_flush()
434 }
435}
436
437impl EasySocket for UdpSocket<Connected> {}