55
66use crate :: error:: { to_result_errno, Result } ;
77use crate :: net:: ipaddr:: { try_sockaddr_from_c, try_sockaddr_to_c} ;
8- use crate :: raw:: {
9- sockaddr, socklen_t, zsock_bind, zsock_close, zsock_recvfrom, zsock_sendto, zsock_socket,
10- } ;
8+ use crate :: raw:: { self , sockaddr, socklen_t} ;
119use core:: ffi:: { c_int, c_void} ;
1210use core:: mem:: MaybeUninit ;
1311use core:: net:: SocketAddr ;
@@ -18,16 +16,31 @@ pub(crate) enum Domain {
1816 AfInet6 = crate :: raw:: AF_INET6 as isize ,
1917}
2018
19+ impl Domain {
20+ /// Get the Domain associated with a SocketAddr
21+ pub ( crate ) fn from_socket_addr ( addr : & SocketAddr ) -> Self {
22+ match addr {
23+ SocketAddr :: V4 ( _) => Self :: AfInet ,
24+ SocketAddr :: V6 ( _) => Self :: AfInet6 ,
25+ }
26+ }
27+ }
28+
2129#[ derive( Debug , Copy , Clone ) ]
2230pub ( crate ) enum SockType {
2331 Dgram = crate :: raw:: net_sock_type_SOCK_DGRAM as isize ,
32+ Stream = crate :: raw:: net_sock_type_SOCK_STREAM as isize ,
2433}
2534
2635#[ derive( Debug , Copy , Clone ) ]
2736pub ( crate ) enum Protocol {
28- IpprotoUdp = crate :: raw:: net_ip_protocol_IPPROTO_UDP as isize ,
37+ IpProtoUdp = crate :: raw:: net_ip_protocol_IPPROTO_UDP as isize ,
38+ IpProtoTcp = crate :: raw:: net_ip_protocol_IPPROTO_TCP as isize ,
2939}
3040
41+ // We could make the backlog configurable, but for now just pick a sensible default value
42+ const LISTEN_BACKLOG : c_int = 10 ;
43+
3144/// Socket type implementing minimal safe wrappers around Zephyr's C socket API
3245pub ( crate ) struct Socket {
3346 fd : c_int ,
@@ -38,7 +51,8 @@ impl Socket {
3851 ///
3952 /// This is a minimal wrapper around zsock_socket
4053 pub ( crate ) fn new ( domain : Domain , sock_type : SockType , protocol : Protocol ) -> Result < Socket > {
41- let res = unsafe { zsock_socket ( domain as c_int , sock_type as c_int , protocol as c_int ) } ;
54+ let res =
55+ unsafe { raw:: zsock_socket ( domain as c_int , sock_type as c_int , protocol as c_int ) } ;
4256
4357 let fd = to_result_errno ( res) ?;
4458
@@ -51,12 +65,52 @@ impl Socket {
5165 pub ( crate ) fn bind ( & mut self , addr : & SocketAddr ) -> Result < ( ) > {
5266 let ( sockaddr, socklen) = try_sockaddr_to_c ( addr) ?;
5367
54- let res = unsafe { zsock_bind ( self . fd , & sockaddr as * const sockaddr , socklen) } ;
68+ let res = unsafe { raw :: zsock_bind ( self . fd , & sockaddr as * const sockaddr , socklen) } ;
5569
5670 let _ = to_result_errno ( res) ?;
5771 Ok ( ( ) )
5872 }
5973
74+ /// Connect a socket to a peer socket address
75+ ///
76+ /// This is a minimal wrapper around zsock_connect
77+ pub ( crate ) fn connect ( & mut self , peer : & SocketAddr ) -> Result < ( ) > {
78+ let ( sa, socklen) = try_sockaddr_to_c ( peer) ?;
79+
80+ let res = unsafe { raw:: zsock_connect ( self . fd , & sa as * const sockaddr , socklen) } ;
81+ let _ = to_result_errno ( res) ?;
82+ Ok ( ( ) )
83+ }
84+
85+ /// Listen for incoming connections on a socket
86+ ///
87+ /// This is a minimal wrapper around zsock_listen
88+ pub ( crate ) fn listen ( & mut self ) -> Result < ( ) > {
89+ let res = unsafe { raw:: zsock_listen ( self . fd , LISTEN_BACKLOG ) } ;
90+ let _ = to_result_errno ( res) ?;
91+ Ok ( ( ) )
92+ }
93+
94+ /// Accept a connection on a listening socket
95+ ///
96+ /// This is a minimal wrapper around zsock_accept
97+ pub ( crate ) fn accept ( & mut self ) -> Result < ( Socket , SocketAddr ) > {
98+ let mut sa = MaybeUninit :: < sockaddr > :: uninit ( ) ;
99+ let mut socklen: socklen_t = core:: mem:: size_of :: < sockaddr > ( ) ;
100+
101+ let res =
102+ unsafe { raw:: zsock_accept ( self . fd , sa. as_mut_ptr ( ) , & mut socklen as * mut socklen_t ) } ;
103+
104+ let new_fd = to_result_errno ( res) ?;
105+ let new_sock = Socket { fd : new_fd } ;
106+
107+ // SAFETY: `zsock_accept` returned a success code, so it has populated the sockaddr.
108+ let sa = unsafe { sa. assume_init ( ) } ;
109+
110+ let peer_sa = try_sockaddr_from_c ( & sa, socklen) ?;
111+ Ok ( ( new_sock, peer_sa) )
112+ }
113+
60114 /// Receive from the socket, returning the data length and peer address it was received from
61115 ///
62116 /// This is a minimal wrapper around zsock_recvfrom
@@ -65,7 +119,7 @@ impl Socket {
65119 let mut socklen: socklen_t = core:: mem:: size_of :: < sockaddr > ( ) ;
66120
67121 let res = unsafe {
68- zsock_recvfrom (
122+ raw :: zsock_recvfrom (
69123 self . fd ,
70124 buf. as_mut_ptr ( ) as * mut c_void ,
71125 buf. len ( ) ,
@@ -87,11 +141,11 @@ impl Socket {
87141 /// Send data to the specified socket address.
88142 ///
89143 /// This is a minimal wrapper around zsock_sendto
90- pub fn send_to ( & self , buf : & [ u8 ] , addr : & SocketAddr ) -> Result < usize > {
91- let ( sa, socklen) = try_sockaddr_to_c ( addr ) ?;
144+ pub fn send_to ( & self , buf : & [ u8 ] , peer : & SocketAddr ) -> Result < usize > {
145+ let ( sa, socklen) = try_sockaddr_to_c ( peer ) ?;
92146
93147 let res = unsafe {
94- zsock_sendto (
148+ raw :: zsock_sendto (
95149 self . fd ,
96150 buf. as_ptr ( ) as * const c_void ,
97151 buf. len ( ) ,
@@ -104,12 +158,27 @@ impl Socket {
104158 let sent = to_result_errno ( res) ?;
105159 Ok ( sent as usize )
106160 }
161+
162+ /// Send data on a socket
163+ pub fn send ( & mut self , buf : & [ u8 ] ) -> Result < usize > {
164+ let res = unsafe { raw:: zsock_send ( self . fd , buf. as_ptr ( ) as * const c_void , buf. len ( ) , 0 ) } ;
165+ let sent = to_result_errno ( res) ?;
166+ Ok ( sent as usize )
167+ }
168+
169+ /// Receive data from a socket
170+ pub fn recv ( & mut self , buf : & mut [ u8 ] ) -> Result < usize > {
171+ let res =
172+ unsafe { raw:: zsock_recv ( self . fd , buf. as_mut_ptr ( ) as * mut c_void , buf. len ( ) , 0 ) } ;
173+ let recvd = to_result_errno ( res) ?;
174+ Ok ( recvd as usize )
175+ }
107176}
108177
109178impl Drop for Socket {
110179 fn drop ( & mut self ) {
111180 unsafe {
112- let _ = zsock_close ( self . fd ) ;
181+ let _ = raw :: zsock_close ( self . fd ) ;
113182 }
114183 }
115184}
0 commit comments