@@ -3,6 +3,7 @@ use core::cmp::min;
33use core:: task:: Waker ;
44
55use crate :: iface:: Context ;
6+ use crate :: phy:: PacketMeta ;
67use crate :: socket:: PollAt ;
78#[ cfg( feature = "async" ) ]
89use crate :: socket:: WakerRegistration ;
@@ -50,11 +51,25 @@ impl core::fmt::Display for RecvError {
5051#[ cfg( feature = "std" ) ]
5152impl std:: error:: Error for RecvError { }
5253
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+
5368/// A Eth packet metadata.
54- pub type PacketMetadata = crate :: storage:: PacketMetadata < ( ) > ;
69+ pub type PacketMetadata = crate :: storage:: PacketMetadata < EthMetadata > ;
5570
5671/// A Eth packet ring buffer.
57- pub type PacketBuffer < ' a > = crate :: storage:: PacketBuffer < ' a , ( ) > ;
72+ pub type PacketBuffer < ' a > = crate :: storage:: PacketBuffer < ' a , EthMetadata > ;
5873
5974pub type Ethertype = u16 ;
6075
@@ -176,10 +191,15 @@ impl<'a> Socket<'a> {
176191 ///
177192 /// If the buffer is filled in a way that does not match the socket's
178193 /// 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 ( ) ;
180200 let packet_buf = self
181201 . tx_buffer
182- . enqueue ( size, ( ) )
202+ . enqueue ( size, meta )
183203 . map_err ( |_| SendError :: BufferFull ) ?;
184204
185205 net_trace ! (
@@ -194,13 +214,19 @@ impl<'a> Socket<'a> {
194214 /// The closure then returns the size of the data written into the buffer.
195215 ///
196216 /// 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 >
198223 where
199224 F : FnOnce ( & mut [ u8 ] ) -> usize ,
200225 {
226+ let meta = meta. into ( ) ;
201227 let size = self
202228 . tx_buffer
203- . enqueue_with_infallible ( max_size, ( ) , f)
229+ . enqueue_with_infallible ( max_size, meta , f)
204230 . map_err ( |_| SendError :: BufferFull ) ?;
205231
206232 net_trace ! (
@@ -215,23 +241,27 @@ impl<'a> Socket<'a> {
215241 /// Enqueue a packet to send, and fill it from a slice.
216242 ///
217243 /// 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) ;
220250 Ok ( ( ) )
221251 }
222252
223253 /// Dequeue a packet, and return a pointer to the payload.
224254 ///
225255 /// 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 ) ?;
228258
229259 net_trace ! (
230260 "eth:{}: receive {} buffered octets" ,
231261 self . ethertype. unwrap_or( 0 ) ,
232262 packet_buf. len( )
233263 ) ;
234- Ok ( packet_buf)
264+ Ok ( ( packet_buf, meta ) )
235265 }
236266
237267 /// Dequeue a packet, and copy the payload into the given slice.
@@ -240,32 +270,32 @@ impl<'a> Socket<'a> {
240270 /// the packet is dropped and a `RecvError::Truncated` error is returned.
241271 ///
242272 /// 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 ( ) ?;
245275 if data. len ( ) < buffer. len ( ) {
246276 return Err ( RecvError :: Truncated ) ;
247277 }
248278
249279 let length = min ( data. len ( ) , buffer. len ( ) ) ;
250280 data[ ..length] . copy_from_slice ( & buffer[ ..length] ) ;
251- Ok ( length)
281+ Ok ( ( length, meta ) )
252282 }
253283
254284 /// Peek at a packet in the receive buffer and return a pointer to the
255285 /// payload without removing the packet from the receive buffer.
256286 /// This function otherwise behaves identically to [recv](#method.recv).
257287 ///
258288 /// 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 ) ?;
261291
262292 net_trace ! (
263293 "eth:{}: receive {} buffered octets" ,
264294 self . ethertype. unwrap_or( 0 ) ,
265295 packet_buf. len( )
266296 ) ;
267297
268- Ok ( packet_buf)
298+ Ok ( ( packet_buf, meta ) )
269299 }
270300
271301 /// Peek at a packet in the receive buffer, copy the payload into the given slice,
@@ -276,15 +306,15 @@ impl<'a> Socket<'a> {
276306 /// no data is copied into the provided buffer and a `RecvError::Truncated` error is returned.
277307 ///
278308 /// 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 ( ) ?;
281311 if data. len ( ) < buffer. len ( ) {
282312 return Err ( RecvError :: Truncated ) ;
283313 }
284314
285315 let length = min ( data. len ( ) , buffer. len ( ) ) ;
286316 data[ ..length] . copy_from_slice ( & buffer[ ..length] ) ;
287- Ok ( length)
317+ Ok ( ( length, meta ) )
288318 }
289319
290320 /// Return the amount of octets queued in the transmit buffer.
@@ -305,7 +335,13 @@ impl<'a> Socket<'a> {
305335 }
306336 }
307337
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+ ) {
309345 debug_assert ! ( self . accepts( eth_repr) ) ;
310346
311347 let header_len = eth_repr. buffer_len ( ) ;
@@ -317,7 +353,9 @@ impl<'a> Socket<'a> {
317353 total_len
318354 ) ;
319355
320- match self . rx_buffer . enqueue ( total_len, ( ) ) {
356+ let metadata = EthMetadata { meta } ;
357+
358+ match self . rx_buffer . enqueue ( total_len, metadata) {
321359 Ok ( buf) => {
322360 let mut frame = EthernetFrame :: new_checked ( buf) . expect ( "internal ethernet error" ) ;
323361 eth_repr. emit ( & mut frame) ;
@@ -335,10 +373,10 @@ impl<'a> Socket<'a> {
335373
336374 pub ( crate ) fn dispatch < F , E > ( & mut self , cx : & mut Context , emit : F ) -> Result < ( ) , E >
337375 where
338- F : FnOnce ( & mut Context , ( EthernetRepr , & [ u8 ] ) ) -> Result < ( ) , E > ,
376+ F : FnOnce ( & mut Context , PacketMeta , ( EthernetRepr , & [ u8 ] ) ) -> Result < ( ) , E > ,
339377 {
340378 let ethertype = self . ethertype ;
341- let res = self . tx_buffer . dequeue_with ( |& mut ( ) , buffer| {
379+ let res = self . tx_buffer . dequeue_with ( |meta , buffer| {
342380 #[ allow( clippy:: useless_asref) ]
343381 let frame = match EthernetFrame :: new_checked ( buffer. as_ref ( ) ) {
344382 Ok ( x) => x,
@@ -355,7 +393,7 @@ impl<'a> Socket<'a> {
355393 }
356394 } ;
357395 net_trace ! ( "eth:{}: sending" , ethertype. unwrap_or( 0 ) ) ;
358- emit ( cx, ( eth_repr, frame. payload ( ) ) )
396+ emit ( cx, meta . meta , ( eth_repr, frame. payload ( ) ) )
359397 } ) ;
360398 match res {
361399 Err ( Empty ) => Ok ( ( ) ) ,
@@ -415,12 +453,21 @@ mod test {
415453 let ( mut iface, _, _) = setup ( Medium :: Ethernet ) ;
416454 let cx = iface. context ( ) ;
417455 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+ } ;
418462 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+ ) ;
421468 assert ! ( !socket. can_send( ) ) ;
422469 assert_eq ! (
423- socket. dispatch( cx, |_, ( eth_repr, eth_payload) | {
470+ socket. dispatch( cx, |_, _ , ( eth_repr, eth_payload) | {
424471 assert_eq!( eth_repr. ethertype, EtherType :: from( ETHER_TYPE ) ) ;
425472 assert_eq!( eth_payload, PACKET_PAYLOAD ) ;
426473 Err ( ( ) )
@@ -429,7 +476,7 @@ mod test {
429476 ) ;
430477 assert ! ( !socket. can_send( ) ) ;
431478 assert_eq ! (
432- socket. dispatch( cx, |_, ( eth_repr, eth_payload) | {
479+ socket. dispatch( cx, |_, _ , ( eth_repr, eth_payload) | {
433480 assert_eq!( eth_repr. ethertype, EtherType :: from( ETHER_TYPE ) ) ;
434481 assert_eq!( eth_payload, PACKET_PAYLOAD ) ;
435482 Ok :: <_, ( ) >( ( ) )
@@ -449,22 +496,29 @@ mod test {
449496 assert_eq ! ( socket. recv( ) , Err ( RecvError :: Exhausted ) ) ;
450497 assert_eq ! ( socket. peek( ) , Err ( RecvError :: Exhausted ) ) ;
451498
499+ let pktmeta = PacketMeta {
500+ #[ cfg( feature = "packetmeta-id" ) ]
501+ id : 43 ,
502+ } ;
503+
504+ let ethmeta = EthMetadata { meta : pktmeta } ;
505+
452506 let frameinfo = EthernetRepr {
453507 src_addr : EthernetAddress :: from_bytes ( & PACKET_SENDER ) ,
454508 dst_addr : EthernetAddress :: from_bytes ( & PACKET_RECEIVER ) ,
455509 ethertype : ETHER_TYPE . into ( ) ,
456510 } ;
457511
458512 assert ! ( socket. accepts( & frameinfo) ) ;
459- socket. process ( cx, & frameinfo, & PACKET_PAYLOAD ) ;
513+ socket. process ( cx, pktmeta , & frameinfo, & PACKET_PAYLOAD ) ;
460514 assert ! ( socket. can_recv( ) ) ;
461515
462516 assert ! ( socket. accepts( & frameinfo) ) ;
463- socket. process ( cx, & frameinfo, & PACKET_PAYLOAD ) ;
517+ socket. process ( cx, pktmeta , & frameinfo, & PACKET_PAYLOAD ) ;
464518
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 ) ) ) ;
468522 assert ! ( !socket. can_recv( ) ) ;
469523 assert_eq ! ( socket. peek( ) , Err ( RecvError :: Exhausted ) ) ;
470524 }
0 commit comments