aboutsummaryrefslogtreecommitdiff
path: root/embassy-net/src/device.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-net/src/device.rs')
-rw-r--r--embassy-net/src/device.rs105
1 files changed, 105 insertions, 0 deletions
diff --git a/embassy-net/src/device.rs b/embassy-net/src/device.rs
new file mode 100644
index 000000000..6c06b0605
--- /dev/null
+++ b/embassy-net/src/device.rs
@@ -0,0 +1,105 @@
1use core::task::Waker;
2use smoltcp::phy::Device as SmolDevice;
3use smoltcp::phy::DeviceCapabilities;
4use smoltcp::time::Instant as SmolInstant;
5
6use crate::fmt::*;
7use crate::packet_pool::PacketBoxExt;
8use crate::Result;
9use crate::{Packet, PacketBox, PacketBuf};
10
11#[derive(PartialEq, Eq, Clone, Copy)]
12pub enum LinkState {
13 Down,
14 Up,
15}
16
17pub trait Device {
18 fn is_transmit_ready(&mut self) -> bool;
19 fn transmit(&mut self, pkt: PacketBuf);
20 fn receive(&mut self) -> Option<PacketBuf>;
21
22 fn register_waker(&mut self, waker: &Waker);
23 fn capabilities(&mut self) -> DeviceCapabilities;
24 fn link_state(&mut self) -> LinkState;
25 fn ethernet_address(&mut self) -> [u8; 6];
26}
27
28pub struct DeviceAdapter {
29 pub device: &'static mut dyn Device,
30 caps: DeviceCapabilities,
31}
32
33impl DeviceAdapter {
34 pub(crate) fn new(device: &'static mut dyn Device) -> Self {
35 Self {
36 caps: device.capabilities(),
37 device,
38 }
39 }
40}
41
42impl<'a> SmolDevice<'a> for DeviceAdapter {
43 type RxToken = RxToken;
44 type TxToken = TxToken<'a>;
45
46 fn receive(&'a mut self) -> Option<(Self::RxToken, Self::TxToken)> {
47 let rx_pkt = self.device.receive()?;
48 let tx_pkt = PacketBox::new(Packet::new()).unwrap(); // TODO: not sure about unwrap
49 let rx_token = RxToken { pkt: rx_pkt };
50 let tx_token = TxToken {
51 device: self.device,
52 pkt: tx_pkt,
53 };
54
55 Some((rx_token, tx_token))
56 }
57
58 /// Construct a transmit token.
59 fn transmit(&'a mut self) -> Option<Self::TxToken> {
60 if !self.device.is_transmit_ready() {
61 return None;
62 }
63
64 let tx_pkt = PacketBox::new(Packet::new())?;
65 Some(TxToken {
66 device: self.device,
67 pkt: tx_pkt,
68 })
69 }
70
71 /// Get a description of device capabilities.
72 fn capabilities(&self) -> DeviceCapabilities {
73 self.caps.clone()
74 }
75}
76
77pub struct RxToken {
78 pkt: PacketBuf,
79}
80
81impl smoltcp::phy::RxToken for RxToken {
82 fn consume<R, F>(mut self, _timestamp: SmolInstant, f: F) -> Result<R>
83 where
84 F: FnOnce(&mut [u8]) -> Result<R>,
85 {
86 f(&mut self.pkt)
87 }
88}
89
90pub struct TxToken<'a> {
91 device: &'a mut dyn Device,
92 pkt: PacketBox,
93}
94
95impl<'a> smoltcp::phy::TxToken for TxToken<'a> {
96 fn consume<R, F>(self, _timestamp: SmolInstant, len: usize, f: F) -> Result<R>
97 where
98 F: FnOnce(&mut [u8]) -> Result<R>,
99 {
100 let mut buf = self.pkt.slice(0..len);
101 let r = f(&mut buf)?;
102 self.device.transmit(buf);
103 Ok(r)
104 }
105}