@@ -59,11 +59,13 @@ fn result_from<T, F>(err: lwip_sys::err, f: F) -> Result<T>
59
59
#[ derive( Debug , Clone , Copy , PartialEq , Eq , PartialOrd , Ord ) ]
60
60
pub enum IpAddr {
61
61
Ip4 ( [ u8 ; 4 ] ) ,
62
- Ip6 ( [ u16 ; 8 ] )
62
+ Ip6 ( [ u16 ; 8 ] ) ,
63
+ IpAny
63
64
}
64
65
65
66
pub const IP4_ANY : IpAddr = IpAddr :: Ip4 ( [ 0 , 0 , 0 , 0 ] ) ;
66
67
pub const IP6_ANY : IpAddr = IpAddr :: Ip6 ( [ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ] ) ;
68
+ pub const IP_ANY : IpAddr = IpAddr :: IpAny ;
67
69
68
70
impl IpAddr {
69
71
fn into_raw ( self ) -> lwip_sys:: ip_addr {
@@ -84,6 +86,11 @@ impl IpAddr {
84
86
( segments[ 4 ] as u32 ) << 16 | ( segments[ 5 ] as u32 ) ,
85
87
( segments[ 6 ] as u32 ) << 16 | ( segments[ 7 ] as u32 ) ] ,
86
88
type_ : lwip_sys:: IPADDR_TYPE_V6
89
+ } ,
90
+ IpAddr :: IpAny =>
91
+ lwip_sys:: ip_addr {
92
+ data : [ 0 ; 4 ] ,
93
+ type_ : lwip_sys:: IPADDR_TYPE_ANY
87
94
}
88
95
}
89
96
}
@@ -100,7 +107,8 @@ impl IpAddr {
100
107
( data[ 1 ] >> 16 ) as u16 , data[ 1 ] as u16 ,
101
108
( data[ 2 ] >> 16 ) as u16 , data[ 2 ] as u16 ,
102
109
( data[ 3 ] >> 16 ) as u16 , data[ 3 ] as u16 ] ) ,
103
- _ => panic ! ( "unknown IP address type" )
110
+ lwip_sys:: ip_addr { type_ : lwip_sys:: IPADDR_TYPE_ANY , .. } =>
111
+ IpAddr :: IpAny
104
112
}
105
113
}
106
114
}
@@ -186,10 +194,21 @@ impl<'a> Drop for Pbuf<'a> {
186
194
}
187
195
}
188
196
197
+ #[ derive( Debug ) ]
198
+ pub struct UdpSocketState {
199
+ recv_buffer : LinkedList < ( SocketAddr , Pbuf < ' static > ) >
200
+ }
201
+
202
+ impl UdpSocketState {
203
+ pub fn readable ( & self ) -> bool {
204
+ !self . recv_buffer . is_empty ( )
205
+ }
206
+ }
207
+
189
208
#[ derive( Debug ) ]
190
209
pub struct UdpSocket {
191
- raw : * mut lwip_sys:: udp_pcb ,
192
- buffer : Box < LinkedList < ( SocketAddr , Pbuf < ' static > ) > >
210
+ raw : * mut lwip_sys:: udp_pcb ,
211
+ state : Box < UdpSocketState >
193
212
}
194
213
195
214
impl UdpSocket {
@@ -198,23 +217,27 @@ impl UdpSocket {
198
217
pbuf : * mut lwip_sys:: pbuf ,
199
218
addr : * mut lwip_sys:: ip_addr , port : u16 ) {
200
219
unsafe {
201
- let buffer = arg as * mut LinkedList < ( SocketAddr , Pbuf ) > ;
220
+ let state = arg as * mut UdpSocketState ;
202
221
let socket_addr = SocketAddr { ip : IpAddr :: from_raw ( addr) , port : port } ;
203
- ( * buffer ) . push_back ( ( socket_addr, Pbuf :: from_raw ( pbuf) ) ) ;
222
+ ( * state ) . recv_buffer . push_back ( ( socket_addr, Pbuf :: from_raw ( pbuf) ) ) ;
204
223
}
205
224
}
206
225
207
226
unsafe {
208
227
let raw = lwip_sys:: udp_new ( ) ;
209
228
if raw. is_null ( ) { return Err ( Error :: OutOfMemory ) }
210
229
211
- let mut buffer = Box :: new ( LinkedList :: new ( ) ) ;
212
- let arg = & mut * buffer as * mut LinkedList < ( SocketAddr , Pbuf ) > as * mut _ ;
230
+ let mut state = Box :: new ( UdpSocketState { recv_buffer : LinkedList :: new ( ) } ) ;
231
+ let arg = & mut * state as * mut UdpSocketState as * mut _ ;
213
232
lwip_sys:: udp_recv ( raw, recv, arg) ;
214
- Ok ( UdpSocket { raw : raw, buffer : buffer } )
233
+ Ok ( UdpSocket { raw : raw, state : state } )
215
234
}
216
235
}
217
236
237
+ pub fn state ( & self ) -> * const UdpSocketState {
238
+ & * self . state
239
+ }
240
+
218
241
pub fn bind ( & mut self , addr : SocketAddr ) -> Result < ( ) > {
219
242
result_from ( unsafe {
220
243
lwip_sys:: udp_bind ( self . raw , & mut addr. ip . into_raw ( ) , addr. port )
@@ -247,7 +270,11 @@ impl UdpSocket {
247
270
}
248
271
249
272
pub fn try_recv ( & mut self ) -> Option < ( SocketAddr , Pbuf < ' static > ) > {
250
- self . buffer . pop_front ( )
273
+ self . state . recv_buffer . pop_front ( )
274
+ }
275
+
276
+ pub fn close ( self ) {
277
+ // just drop
251
278
}
252
279
}
253
280
@@ -257,10 +284,21 @@ impl Drop for UdpSocket {
257
284
}
258
285
}
259
286
287
+ #[ derive( Debug ) ]
288
+ pub struct TcpListenerState {
289
+ backlog : LinkedList < TcpStream >
290
+ }
291
+
292
+ impl TcpListenerState {
293
+ pub fn acceptable ( & self ) -> bool {
294
+ !self . backlog . is_empty ( )
295
+ }
296
+ }
297
+
260
298
#[ derive( Debug ) ]
261
299
pub struct TcpListener {
262
- raw : * mut lwip_sys:: tcp_pcb ,
263
- backlog : Box < LinkedList < TcpStream > >
300
+ raw : * mut lwip_sys:: tcp_pcb ,
301
+ state : Box < TcpListenerState >
264
302
}
265
303
266
304
impl TcpListener {
@@ -269,19 +307,15 @@ impl TcpListener {
269
307
err : lwip_sys:: err ) -> lwip_sys:: err {
270
308
if err != lwip_sys:: ERR_OK { return err }
271
309
unsafe {
272
- let backlog = arg as * mut LinkedList < TcpStream > ;
273
- ( * backlog ) . push_back ( TcpStream :: from_raw ( newpcb) ) ;
310
+ let state = arg as * mut TcpListenerState ;
311
+ ( * state ) . backlog . push_back ( TcpStream :: from_raw ( newpcb) ) ;
274
312
}
275
313
lwip_sys:: ERR_OK
276
314
}
277
315
278
316
unsafe {
279
317
let raw = lwip_sys:: tcp_new ( ) ;
280
318
if raw. is_null ( ) { return Err ( Error :: OutOfMemory ) }
281
-
282
- let mut backlog = Box :: new ( LinkedList :: new ( ) ) ;
283
- let arg = & mut * backlog as * mut LinkedList < TcpStream > as * mut _ ;
284
- lwip_sys:: tcp_arg ( raw, arg) ;
285
319
try!( result_from ( lwip_sys:: tcp_bind ( raw, & mut addr. ip . into_raw ( ) , addr. port ) ,
286
320
|| ( ) ) ) ;
287
321
@@ -290,13 +324,23 @@ impl TcpListener {
290
324
lwip_sys:: tcp_abort ( raw) ;
291
325
return Err ( Error :: OutOfMemory )
292
326
}
327
+
328
+ let mut state = Box :: new ( TcpListenerState {
329
+ backlog : LinkedList :: new ( )
330
+ } ) ;
331
+ let arg = & mut * state as * mut TcpListenerState as * mut _ ;
332
+ lwip_sys:: tcp_arg ( raw, arg) ;
293
333
lwip_sys:: tcp_accept ( raw2, accept) ;
294
- Ok ( TcpListener { raw : raw2, backlog : backlog } )
334
+ Ok ( TcpListener { raw : raw2, state : state } )
295
335
}
296
336
}
297
337
338
+ pub fn state ( & self ) -> * const TcpListenerState {
339
+ & * self . state
340
+ }
341
+
298
342
pub fn try_accept ( & mut self ) -> Option < TcpStream > {
299
- self . backlog . pop_front ( )
343
+ self . state . backlog . pop_front ( )
300
344
}
301
345
302
346
pub fn close ( self ) {
@@ -320,61 +364,96 @@ pub enum Shutdown {
320
364
Both ,
321
365
}
322
366
367
+ #[ derive( Debug ) ]
368
+ pub struct TcpStreamState {
369
+ recv_buffer : LinkedList < Result < Pbuf < ' static > > > ,
370
+ send_avail : usize
371
+ }
372
+
373
+ impl TcpStreamState {
374
+ pub fn readable ( & self ) -> bool {
375
+ !self . recv_buffer . is_empty ( )
376
+ }
377
+
378
+ pub fn writeable ( & self ) -> bool {
379
+ !( self . send_avail == 0 )
380
+ }
381
+ }
382
+
323
383
#[ derive( Debug ) ]
324
384
pub struct TcpStream {
325
- raw : * mut lwip_sys:: tcp_pcb ,
326
- buffer : Box < LinkedList < Result < Pbuf < ' static > > > >
385
+ raw : * mut lwip_sys:: tcp_pcb ,
386
+ state : Box < TcpStreamState >
327
387
}
328
388
329
389
impl TcpStream {
330
390
fn from_raw ( raw : * mut lwip_sys:: tcp_pcb ) -> TcpStream {
331
- extern fn recv ( arg : * mut c_void , _tcb : * mut lwip_sys:: tcp_pcb ,
391
+ extern fn recv ( arg : * mut c_void , _raw : * mut lwip_sys:: tcp_pcb ,
332
392
pbuf : * mut lwip_sys:: pbuf , err : lwip_sys:: err ) -> lwip_sys:: err {
333
393
if err != lwip_sys:: ERR_OK { return err }
334
394
unsafe {
335
- let buffer = arg as * mut LinkedList < Result < Pbuf < ' static > > > ;
395
+ let state = arg as * mut TcpStreamState ;
336
396
if pbuf. is_null ( ) {
337
- ( * buffer ) . push_back ( Err ( Error :: ConnectionClosed ) )
397
+ ( * state ) . recv_buffer . push_back ( Err ( Error :: ConnectionClosed ) )
338
398
} else {
339
- ( * buffer ) . push_back ( Ok ( Pbuf :: from_raw ( pbuf) ) )
399
+ ( * state ) . recv_buffer . push_back ( Ok ( Pbuf :: from_raw ( pbuf) ) )
340
400
}
341
401
}
342
402
lwip_sys:: ERR_OK
343
403
}
344
404
405
+ extern fn sent ( arg : * mut c_void , raw : * mut lwip_sys:: tcp_pcb ,
406
+ _len : u16 ) -> lwip_sys:: err {
407
+ unsafe {
408
+ let state = arg as * mut TcpStreamState ;
409
+ ( * state) . send_avail = lwip_sys:: tcp_sndbuf_ ( raw) as usize ;
410
+ }
411
+ lwip_sys:: ERR_OK
412
+ }
413
+
345
414
extern fn err ( arg : * mut c_void , err : lwip_sys:: err ) {
346
415
unsafe {
347
- let buffer = arg as * mut LinkedList < Result < Pbuf < ' static > > > ;
348
- ( * buffer ) . push_back ( result_from ( err, || unreachable ! ( ) ) )
416
+ let state = arg as * mut TcpStreamState ;
417
+ ( * state ) . recv_buffer . push_back ( result_from ( err, || unreachable ! ( ) ) )
349
418
}
350
419
}
351
420
352
421
unsafe {
353
- let mut buffer = Box :: new ( LinkedList :: new ( ) ) ;
354
- let arg = & mut * buffer as * mut LinkedList < Result < Pbuf < ' static > > > as * mut _ ;
422
+ let mut state = Box :: new ( TcpStreamState {
423
+ recv_buffer : LinkedList :: new ( ) ,
424
+ send_avail : lwip_sys:: tcp_sndbuf_ ( raw) as usize
425
+ } ) ;
426
+ let arg = & mut * state as * mut TcpStreamState as * mut _ ;
355
427
lwip_sys:: tcp_arg ( raw, arg) ;
356
428
lwip_sys:: tcp_recv ( raw, recv) ;
429
+ lwip_sys:: tcp_sent ( raw, sent) ;
357
430
lwip_sys:: tcp_err ( raw, err) ;
358
- TcpStream { raw : raw, buffer : buffer }
431
+ TcpStream { raw : raw, state : state }
359
432
}
360
433
}
361
434
435
+ pub fn state ( & self ) -> * const TcpStreamState {
436
+ & * self . state
437
+ }
438
+
362
439
pub fn write ( & mut self , data : & [ u8 ] ) -> Result < usize > {
363
440
let sndbuf = unsafe { lwip_sys:: tcp_sndbuf_ ( self . raw ) } as usize ;
364
441
let len = if data. len ( ) < sndbuf { data. len ( ) } else { sndbuf } ;
365
- result_from ( unsafe {
442
+ let result = result_from ( unsafe {
366
443
lwip_sys:: tcp_write ( self . raw , data as * const [ u8 ] as * const _ , len as u16 ,
367
444
lwip_sys:: TCP_WRITE_FLAG_COPY )
368
- } , || len)
445
+ } , || len) ;
446
+ self . state . send_avail = unsafe { lwip_sys:: tcp_sndbuf_ ( self . raw ) } as usize ;
447
+ result
369
448
}
370
449
371
450
pub fn try_read ( & mut self ) -> Result < Option < Pbuf < ' static > > > {
372
- match self . buffer . front ( ) {
451
+ match self . state . recv_buffer . front ( ) {
373
452
None => return Ok ( None ) ,
374
453
Some ( & Err ( err) ) => return Err ( err) ,
375
454
Some ( _) => ( )
376
455
}
377
- match self . buffer . pop_front ( ) {
456
+ match self . state . recv_buffer . pop_front ( ) {
378
457
Some ( Ok ( pbuf) ) => return Ok ( Some ( pbuf) ) ,
379
458
_ => unreachable ! ( )
380
459
}
0 commit comments