5
5
6
6
use crate :: error:: { to_result_errno, Result } ;
7
7
use 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} ;
11
9
use core:: ffi:: { c_int, c_void} ;
12
10
use core:: mem:: MaybeUninit ;
13
11
use core:: net:: SocketAddr ;
@@ -18,16 +16,31 @@ pub(crate) enum Domain {
18
16
AfInet6 = crate :: raw:: AF_INET6 as isize ,
19
17
}
20
18
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
+
21
29
#[ derive( Debug , Copy , Clone ) ]
22
30
pub ( crate ) enum SockType {
23
31
Dgram = crate :: raw:: net_sock_type_SOCK_DGRAM as isize ,
32
+ Stream = crate :: raw:: net_sock_type_SOCK_STREAM as isize ,
24
33
}
25
34
26
35
#[ derive( Debug , Copy , Clone ) ]
27
36
pub ( 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 ,
29
39
}
30
40
41
+ // We could make the backlog configurable, but for now just pick a sensible default value
42
+ const LISTEN_BACKLOG : c_int = 10 ;
43
+
31
44
/// Socket type implementing minimal safe wrappers around Zephyr's C socket API
32
45
pub ( crate ) struct Socket {
33
46
fd : c_int ,
@@ -38,7 +51,8 @@ impl Socket {
38
51
///
39
52
/// This is a minimal wrapper around zsock_socket
40
53
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 ) } ;
42
56
43
57
let fd = to_result_errno ( res) ?;
44
58
@@ -51,12 +65,52 @@ impl Socket {
51
65
pub ( crate ) fn bind ( & mut self , addr : & SocketAddr ) -> Result < ( ) > {
52
66
let ( sockaddr, socklen) = try_sockaddr_to_c ( addr) ?;
53
67
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) } ;
55
69
56
70
let _ = to_result_errno ( res) ?;
57
71
Ok ( ( ) )
58
72
}
59
73
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
+
60
114
/// Receive from the socket, returning the data length and peer address it was received from
61
115
///
62
116
/// This is a minimal wrapper around zsock_recvfrom
@@ -65,7 +119,7 @@ impl Socket {
65
119
let mut socklen: socklen_t = core:: mem:: size_of :: < sockaddr > ( ) ;
66
120
67
121
let res = unsafe {
68
- zsock_recvfrom (
122
+ raw :: zsock_recvfrom (
69
123
self . fd ,
70
124
buf. as_mut_ptr ( ) as * mut c_void ,
71
125
buf. len ( ) ,
@@ -87,11 +141,11 @@ impl Socket {
87
141
/// Send data to the specified socket address.
88
142
///
89
143
/// 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 ) ?;
92
146
93
147
let res = unsafe {
94
- zsock_sendto (
148
+ raw :: zsock_sendto (
95
149
self . fd ,
96
150
buf. as_ptr ( ) as * const c_void ,
97
151
buf. len ( ) ,
@@ -104,12 +158,27 @@ impl Socket {
104
158
let sent = to_result_errno ( res) ?;
105
159
Ok ( sent as usize )
106
160
}
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
+ }
107
176
}
108
177
109
178
impl Drop for Socket {
110
179
fn drop ( & mut self ) {
111
180
unsafe {
112
- let _ = zsock_close ( self . fd ) ;
181
+ let _ = raw :: zsock_close ( self . fd ) ;
113
182
}
114
183
}
115
184
}
0 commit comments