1#![allow(clippy::module_name_repetitions)]
2
3use alloc::vec::Vec;
4use embedded_io::{ErrorType, Read, Write};
5
6use core::net::SocketAddr;
7use psp::sys;
8
9use core::ffi::c_void;
10
11use crate::traits::io::{EasySocket, Open, OptionType};
12use crate::traits::SocketBuffer;
13use crate::types::{SocketOptions, SocketRecvFlags, SocketSendFlags};
14
15use super::super::netc;
16
17use super::error::SocketError;
18use super::sce::SocketFileDescriptor;
19use super::state::{Connected, SocketState, Unbound};
20use super::ToSockaddr;
21
22#[repr(C)]
47#[derive(Debug, Clone, PartialEq, Eq, Hash)]
48pub struct TcpSocket<S: SocketState = Unbound, B: SocketBuffer = Vec<u8>> {
49 pub(super) fd: SocketFileDescriptor,
51 buffer: B,
53 send_flags: SocketSendFlags,
55 recv_flags: SocketRecvFlags,
57 _marker: core::marker::PhantomData<S>,
59}
60
61impl TcpSocket {
62 pub fn new() -> Result<TcpSocket<Unbound>, SocketError> {
70 let fd = unsafe { sys::sceNetInetSocket(i32::from(netc::AF_INET), netc::SOCK_STREAM, 0) };
71 if fd < 0 {
72 Err(SocketError::new_errno_with_description(
73 unsafe { sys::sceNetInetGetErrno() },
74 "failed to create socket",
75 ))
76 } else {
77 let fd = SocketFileDescriptor::new(fd);
78 Ok(TcpSocket {
79 fd,
80 buffer: Vec::with_capacity(0),
81 send_flags: SocketSendFlags::empty(),
82 recv_flags: SocketRecvFlags::empty(),
83 _marker: core::marker::PhantomData,
84 })
85 }
86 }
87}
88
89impl<S: SocketState> TcpSocket<S> {
90 #[must_use]
92 pub fn fd(&self) -> i32 {
93 *self.fd
94 }
95
96 #[must_use]
98 pub fn send_flags(&self) -> SocketSendFlags {
99 self.send_flags
100 }
101
102 pub fn set_send_flags(&mut self, send_flags: SocketSendFlags) {
104 self.send_flags = send_flags;
105 }
106
107 #[must_use]
109 pub fn recv_flags(&self) -> SocketRecvFlags {
110 self.recv_flags
111 }
112
113 pub fn set_recv_flags(&mut self, recv_flags: SocketRecvFlags) {
115 self.recv_flags = recv_flags;
116 }
117}
118
119impl TcpSocket<Unbound> {
120 #[must_use]
121 fn transition(self) -> TcpSocket<Connected> {
122 TcpSocket {
123 fd: self.fd,
124 buffer: Vec::default(),
125 send_flags: self.send_flags,
126 recv_flags: self.recv_flags,
127 _marker: core::marker::PhantomData,
128 }
129 }
130
131 pub fn connect(self, remote: SocketAddr) -> Result<TcpSocket<Connected>, SocketError> {
144 match remote {
145 SocketAddr::V4(v4) => {
146 let sockaddr = v4.to_sockaddr();
147
148 if unsafe {
149 sys::sceNetInetConnect(
150 *self.fd,
151 &sockaddr,
152 core::mem::size_of::<netc::sockaddr_in>() as u32,
153 )
154 } < 0
155 {
156 let errno = unsafe { sys::sceNetInetGetErrno() };
157 Err(SocketError::Errno(errno))
158 } else {
159 Ok(self.transition())
160 }
161 }
162 SocketAddr::V6(_) => Err(SocketError::UnsupportedAddressFamily),
163 }
164 }
165}
166
167impl TcpSocket<Connected> {
168 pub fn internal_read(&self, buf: &mut [u8]) -> Result<usize, SocketError> {
182 let result = unsafe {
183 sys::sceNetInetRecv(
184 *self.fd,
185 buf.as_mut_ptr().cast::<c_void>(),
186 buf.len(),
187 self.recv_flags.as_i32(),
188 )
189 };
190 if result < 0 {
191 Err(SocketError::Errno(unsafe { sys::sceNetInetGetErrno() }))
192 } else {
193 Ok(result as usize)
194 }
195 }
196
197 pub fn internal_write(&mut self, buf: &[u8]) -> Result<usize, SocketError> {
202 self.buffer.append_buffer(buf);
203 self.send()
204 }
205
206 fn internal_flush(&mut self) -> Result<(), SocketError> {
207 while !self.buffer.is_empty() {
208 self.send()?;
209 }
210 Ok(())
211 }
212
213 fn send(&mut self) -> Result<usize, SocketError> {
214 let result = unsafe {
215 sys::sceNetInetSend(
216 *self.fd,
217 self.buffer.as_slice().as_ptr().cast::<c_void>(),
218 self.buffer.len(),
219 self.send_flags.as_i32(),
220 )
221 };
222 if result < 0 {
223 Err(SocketError::Errno(unsafe { sys::sceNetInetGetErrno() }))
224 } else {
225 self.buffer.shift_left_buffer(result as usize);
226 Ok(result as usize)
227 }
228 }
229}
230
231impl<S: SocketState> ErrorType for TcpSocket<S> {
232 type Error = SocketError;
233}
234
235impl<S: SocketState> OptionType for TcpSocket<S> {
236 type Options<'a> = SocketOptions;
237}
238
239impl Open<'_, '_> for TcpSocket<Unbound> {
240 type Return = TcpSocket<Connected>;
241 fn open(self, options: &'_ Self::Options<'_>) -> Result<Self::Return, Self::Error>
243 where
244 Self: Sized,
245 {
246 let socket = self.connect(options.remote())?;
247 Ok(socket)
248 }
249}
250
251impl Read for TcpSocket<Connected> {
252 fn read<'m>(&'m mut self, buf: &'m mut [u8]) -> Result<usize, Self::Error> {
265 self.internal_read(buf)
266 }
267}
268
269impl Write for TcpSocket<Connected> {
270 fn write<'m>(&'m mut self, buf: &'m [u8]) -> Result<usize, Self::Error> {
276 self.internal_write(buf)
277 }
278
279 fn flush(&mut self) -> Result<(), SocketError> {
284 self.internal_flush()
285 }
286}
287
288impl EasySocket for TcpSocket<Connected> {}