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