@@ -3,6 +3,7 @@ use core::cmp::min;
3
3
use core:: task:: Waker ;
4
4
5
5
use crate :: iface:: Context ;
6
+ use crate :: phy:: PacketMeta ;
6
7
use crate :: socket:: PollAt ;
7
8
#[ cfg( feature = "async" ) ]
8
9
use crate :: socket:: WakerRegistration ;
@@ -50,11 +51,25 @@ impl core::fmt::Display for RecvError {
50
51
#[ cfg( feature = "std" ) ]
51
52
impl std:: error:: Error for RecvError { }
52
53
54
+ /// Metadata for a sent or received ETH packet.
55
+ #[ derive( Debug , PartialEq , Eq , Clone , Copy ) ]
56
+ #[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
57
+ pub struct EthMetadata {
58
+ pub meta : PacketMeta ,
59
+ }
60
+
61
+ impl core:: fmt:: Display for EthMetadata {
62
+ fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
63
+ #[ cfg( feature = "packetmeta-id" ) ]
64
+ return write ! ( f, "PacketID: {:?}" , self . meta) ;
65
+ }
66
+ }
67
+
53
68
/// A Eth packet metadata.
54
- pub type PacketMetadata = crate :: storage:: PacketMetadata < ( ) > ;
69
+ pub type PacketMetadata = crate :: storage:: PacketMetadata < EthMetadata > ;
55
70
56
71
/// A Eth packet ring buffer.
57
- pub type PacketBuffer < ' a > = crate :: storage:: PacketBuffer < ' a , ( ) > ;
72
+ pub type PacketBuffer < ' a > = crate :: storage:: PacketBuffer < ' a , EthMetadata > ;
58
73
59
74
pub type Ethertype = u16 ;
60
75
@@ -176,10 +191,15 @@ impl<'a> Socket<'a> {
176
191
///
177
192
/// If the buffer is filled in a way that does not match the socket's
178
193
/// ethertype, the packet will be silently dropped.
179
- pub fn send ( & mut self , size : usize ) -> Result < & mut [ u8 ] , SendError > {
194
+ pub fn send (
195
+ & mut self ,
196
+ size : usize ,
197
+ meta : impl Into < EthMetadata > ,
198
+ ) -> Result < & mut [ u8 ] , SendError > {
199
+ let meta = meta. into ( ) ;
180
200
let packet_buf = self
181
201
. tx_buffer
182
- . enqueue ( size, ( ) )
202
+ . enqueue ( size, meta )
183
203
. map_err ( |_| SendError :: BufferFull ) ?;
184
204
185
205
net_trace ! (
@@ -194,13 +214,19 @@ impl<'a> Socket<'a> {
194
214
/// The closure then returns the size of the data written into the buffer.
195
215
///
196
216
/// Also see [send](#method.send).
197
- pub fn send_with < F > ( & mut self , max_size : usize , f : F ) -> Result < usize , SendError >
217
+ pub fn send_with < F > (
218
+ & mut self ,
219
+ max_size : usize ,
220
+ meta : impl Into < EthMetadata > ,
221
+ f : F ,
222
+ ) -> Result < usize , SendError >
198
223
where
199
224
F : FnOnce ( & mut [ u8 ] ) -> usize ,
200
225
{
226
+ let meta = meta. into ( ) ;
201
227
let size = self
202
228
. tx_buffer
203
- . enqueue_with_infallible ( max_size, ( ) , f)
229
+ . enqueue_with_infallible ( max_size, meta , f)
204
230
. map_err ( |_| SendError :: BufferFull ) ?;
205
231
206
232
net_trace ! (
@@ -215,23 +241,27 @@ impl<'a> Socket<'a> {
215
241
/// Enqueue a packet to send, and fill it from a slice.
216
242
///
217
243
/// See also [send](#method.send).
218
- pub fn send_slice ( & mut self , data : & [ u8 ] ) -> Result < ( ) , SendError > {
219
- self . send ( data. len ( ) ) ?. copy_from_slice ( data) ;
244
+ pub fn send_slice (
245
+ & mut self ,
246
+ data : & [ u8 ] ,
247
+ meta : impl Into < EthMetadata > ,
248
+ ) -> Result < ( ) , SendError > {
249
+ self . send ( data. len ( ) , meta) ?. copy_from_slice ( data) ;
220
250
Ok ( ( ) )
221
251
}
222
252
223
253
/// Dequeue a packet, and return a pointer to the payload.
224
254
///
225
255
/// This function returns `Err(Error::Exhausted)` if the receive buffer is empty.
226
- pub fn recv ( & mut self ) -> Result < & [ u8 ] , RecvError > {
227
- let ( ( ) , packet_buf) = self . rx_buffer . dequeue ( ) . map_err ( |_| RecvError :: Exhausted ) ?;
256
+ pub fn recv ( & mut self ) -> Result < ( & [ u8 ] , EthMetadata ) , RecvError > {
257
+ let ( meta , packet_buf) = self . rx_buffer . dequeue ( ) . map_err ( |_| RecvError :: Exhausted ) ?;
228
258
229
259
net_trace ! (
230
260
"eth:{}: receive {} buffered octets" ,
231
261
self . ethertype. unwrap_or( 0 ) ,
232
262
packet_buf. len( )
233
263
) ;
234
- Ok ( packet_buf)
264
+ Ok ( ( packet_buf, meta ) )
235
265
}
236
266
237
267
/// Dequeue a packet, and copy the payload into the given slice.
@@ -240,32 +270,32 @@ impl<'a> Socket<'a> {
240
270
/// the packet is dropped and a `RecvError::Truncated` error is returned.
241
271
///
242
272
/// See also [recv](#method.recv).
243
- pub fn recv_slice ( & mut self , data : & mut [ u8 ] ) -> Result < usize , RecvError > {
244
- let buffer = self . recv ( ) ?;
273
+ pub fn recv_slice ( & mut self , data : & mut [ u8 ] ) -> Result < ( usize , EthMetadata ) , RecvError > {
274
+ let ( buffer, meta ) = self . recv ( ) ?;
245
275
if data. len ( ) < buffer. len ( ) {
246
276
return Err ( RecvError :: Truncated ) ;
247
277
}
248
278
249
279
let length = min ( data. len ( ) , buffer. len ( ) ) ;
250
280
data[ ..length] . copy_from_slice ( & buffer[ ..length] ) ;
251
- Ok ( length)
281
+ Ok ( ( length, meta ) )
252
282
}
253
283
254
284
/// Peek at a packet in the receive buffer and return a pointer to the
255
285
/// payload without removing the packet from the receive buffer.
256
286
/// This function otherwise behaves identically to [recv](#method.recv).
257
287
///
258
288
/// It returns `Err(Error::Exhausted)` if the receive buffer is empty.
259
- pub fn peek ( & mut self ) -> Result < & [ u8 ] , RecvError > {
260
- let ( ( ) , packet_buf) = self . rx_buffer . peek ( ) . map_err ( |_| RecvError :: Exhausted ) ?;
289
+ pub fn peek ( & mut self ) -> Result < ( & [ u8 ] , & EthMetadata ) , RecvError > {
290
+ let ( meta , packet_buf) = self . rx_buffer . peek ( ) . map_err ( |_| RecvError :: Exhausted ) ?;
261
291
262
292
net_trace ! (
263
293
"eth:{}: receive {} buffered octets" ,
264
294
self . ethertype. unwrap_or( 0 ) ,
265
295
packet_buf. len( )
266
296
) ;
267
297
268
- Ok ( packet_buf)
298
+ Ok ( ( packet_buf, meta ) )
269
299
}
270
300
271
301
/// Peek at a packet in the receive buffer, copy the payload into the given slice,
@@ -276,15 +306,15 @@ impl<'a> Socket<'a> {
276
306
/// no data is copied into the provided buffer and a `RecvError::Truncated` error is returned.
277
307
///
278
308
/// See also [peek](#method.peek).
279
- pub fn peek_slice ( & mut self , data : & mut [ u8 ] ) -> Result < usize , RecvError > {
280
- let buffer = self . peek ( ) ?;
309
+ pub fn peek_slice ( & mut self , data : & mut [ u8 ] ) -> Result < ( usize , & EthMetadata ) , RecvError > {
310
+ let ( buffer, meta ) = self . peek ( ) ?;
281
311
if data. len ( ) < buffer. len ( ) {
282
312
return Err ( RecvError :: Truncated ) ;
283
313
}
284
314
285
315
let length = min ( data. len ( ) , buffer. len ( ) ) ;
286
316
data[ ..length] . copy_from_slice ( & buffer[ ..length] ) ;
287
- Ok ( length)
317
+ Ok ( ( length, meta ) )
288
318
}
289
319
290
320
/// Return the amount of octets queued in the transmit buffer.
@@ -305,7 +335,13 @@ impl<'a> Socket<'a> {
305
335
}
306
336
}
307
337
308
- pub ( crate ) fn process ( & mut self , _cx : & mut Context , eth_repr : & EthernetRepr , payload : & [ u8 ] ) {
338
+ pub ( crate ) fn process (
339
+ & mut self ,
340
+ _cx : & mut Context ,
341
+ meta : PacketMeta ,
342
+ eth_repr : & EthernetRepr ,
343
+ payload : & [ u8 ] ,
344
+ ) {
309
345
debug_assert ! ( self . accepts( eth_repr) ) ;
310
346
311
347
let header_len = eth_repr. buffer_len ( ) ;
@@ -317,7 +353,9 @@ impl<'a> Socket<'a> {
317
353
total_len
318
354
) ;
319
355
320
- match self . rx_buffer . enqueue ( total_len, ( ) ) {
356
+ let metadata = EthMetadata { meta } ;
357
+
358
+ match self . rx_buffer . enqueue ( total_len, metadata) {
321
359
Ok ( buf) => {
322
360
let mut frame = EthernetFrame :: new_checked ( buf) . expect ( "internal ethernet error" ) ;
323
361
eth_repr. emit ( & mut frame) ;
@@ -335,10 +373,10 @@ impl<'a> Socket<'a> {
335
373
336
374
pub ( crate ) fn dispatch < F , E > ( & mut self , cx : & mut Context , emit : F ) -> Result < ( ) , E >
337
375
where
338
- F : FnOnce ( & mut Context , ( EthernetRepr , & [ u8 ] ) ) -> Result < ( ) , E > ,
376
+ F : FnOnce ( & mut Context , PacketMeta , ( EthernetRepr , & [ u8 ] ) ) -> Result < ( ) , E > ,
339
377
{
340
378
let ethertype = self . ethertype ;
341
- let res = self . tx_buffer . dequeue_with ( |& mut ( ) , buffer| {
379
+ let res = self . tx_buffer . dequeue_with ( |meta , buffer| {
342
380
#[ allow( clippy:: useless_asref) ]
343
381
let frame = match EthernetFrame :: new_checked ( buffer. as_ref ( ) ) {
344
382
Ok ( x) => x,
@@ -355,7 +393,7 @@ impl<'a> Socket<'a> {
355
393
}
356
394
} ;
357
395
net_trace ! ( "eth:{}: sending" , ethertype. unwrap_or( 0 ) ) ;
358
- emit ( cx, ( eth_repr, frame. payload ( ) ) )
396
+ emit ( cx, meta . meta , ( eth_repr, frame. payload ( ) ) )
359
397
} ) ;
360
398
match res {
361
399
Err ( Empty ) => Ok ( ( ) ) ,
@@ -415,12 +453,21 @@ mod test {
415
453
let ( mut iface, _, _) = setup ( Medium :: Ethernet ) ;
416
454
let cx = iface. context ( ) ;
417
455
let mut socket = socket ( buffer ( 1 ) , buffer ( 1 ) ) ;
456
+ let dummymeta = EthMetadata {
457
+ meta : PacketMeta {
458
+ #[ cfg( feature = "packetmeta-id" ) ]
459
+ id : 42 ,
460
+ } ,
461
+ } ;
418
462
assert ! ( socket. can_send( ) ) ;
419
- assert_eq ! ( socket. send_slice( & PACKET_BYTES [ ..] ) , Ok ( ( ) ) ) ;
420
- assert_eq ! ( socket. send_slice( b"" ) , Err ( SendError :: BufferFull ) ) ;
463
+ assert_eq ! ( socket. send_slice( & PACKET_BYTES [ ..] , dummymeta) , Ok ( ( ) ) ) ;
464
+ assert_eq ! (
465
+ socket. send_slice( b"" , dummymeta) ,
466
+ Err ( SendError :: BufferFull )
467
+ ) ;
421
468
assert ! ( !socket. can_send( ) ) ;
422
469
assert_eq ! (
423
- socket. dispatch( cx, |_, ( eth_repr, eth_payload) | {
470
+ socket. dispatch( cx, |_, _ , ( eth_repr, eth_payload) | {
424
471
assert_eq!( eth_repr. ethertype, EtherType :: from( ETHER_TYPE ) ) ;
425
472
assert_eq!( eth_payload, PACKET_PAYLOAD ) ;
426
473
Err ( ( ) )
@@ -429,7 +476,7 @@ mod test {
429
476
) ;
430
477
assert ! ( !socket. can_send( ) ) ;
431
478
assert_eq ! (
432
- socket. dispatch( cx, |_, ( eth_repr, eth_payload) | {
479
+ socket. dispatch( cx, |_, _ , ( eth_repr, eth_payload) | {
433
480
assert_eq!( eth_repr. ethertype, EtherType :: from( ETHER_TYPE ) ) ;
434
481
assert_eq!( eth_payload, PACKET_PAYLOAD ) ;
435
482
Ok :: <_, ( ) >( ( ) )
@@ -449,22 +496,29 @@ mod test {
449
496
assert_eq ! ( socket. recv( ) , Err ( RecvError :: Exhausted ) ) ;
450
497
assert_eq ! ( socket. peek( ) , Err ( RecvError :: Exhausted ) ) ;
451
498
499
+ let pktmeta = PacketMeta {
500
+ #[ cfg( feature = "packetmeta-id" ) ]
501
+ id : 43 ,
502
+ } ;
503
+
504
+ let ethmeta = EthMetadata { meta : pktmeta } ;
505
+
452
506
let frameinfo = EthernetRepr {
453
507
src_addr : EthernetAddress :: from_bytes ( & PACKET_SENDER ) ,
454
508
dst_addr : EthernetAddress :: from_bytes ( & PACKET_RECEIVER ) ,
455
509
ethertype : ETHER_TYPE . into ( ) ,
456
510
} ;
457
511
458
512
assert ! ( socket. accepts( & frameinfo) ) ;
459
- socket. process ( cx, & frameinfo, & PACKET_PAYLOAD ) ;
513
+ socket. process ( cx, pktmeta , & frameinfo, & PACKET_PAYLOAD ) ;
460
514
assert ! ( socket. can_recv( ) ) ;
461
515
462
516
assert ! ( socket. accepts( & frameinfo) ) ;
463
- socket. process ( cx, & frameinfo, & PACKET_PAYLOAD ) ;
517
+ socket. process ( cx, pktmeta , & frameinfo, & PACKET_PAYLOAD ) ;
464
518
465
- assert_eq ! ( socket. peek( ) , Ok ( & PACKET_BYTES [ ..] ) ) ;
466
- assert_eq ! ( socket. peek( ) , Ok ( & PACKET_BYTES [ ..] ) ) ;
467
- assert_eq ! ( socket. recv( ) , Ok ( & PACKET_BYTES [ ..] ) ) ;
519
+ assert_eq ! ( socket. peek( ) , Ok ( ( & PACKET_BYTES [ ..] , & ethmeta ) ) ) ;
520
+ assert_eq ! ( socket. peek( ) , Ok ( ( & PACKET_BYTES [ ..] , & ethmeta ) ) ) ;
521
+ assert_eq ! ( socket. recv( ) , Ok ( ( & PACKET_BYTES [ ..] , ethmeta ) ) ) ;
468
522
assert ! ( !socket. can_recv( ) ) ;
469
523
assert_eq ! ( socket. peek( ) , Err ( RecvError :: Exhausted ) ) ;
470
524
}
0 commit comments