embassy_net_driver/lib.rs
1#![no_std]
2#![warn(missing_docs)]
3#![doc = include_str!("../README.md")]
4
5use core::task::Context;
6
7/// Representation of an hardware address, such as an Ethernet address or an IEEE802.15.4 address.
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9#[cfg_attr(feature = "defmt", derive(defmt::Format))]
10#[non_exhaustive]
11pub enum HardwareAddress {
12 /// Ethernet medium, with a A six-octet Ethernet address.
13 ///
14 /// Devices of this type send and receive Ethernet frames,
15 /// and interfaces using it must do neighbor discovery via ARP or NDISC.
16 ///
17 /// Examples of devices of this type are Ethernet, WiFi (802.11), Linux `tap`, and VPNs in tap (layer 2) mode.
18 Ethernet([u8; 6]),
19 /// 6LoWPAN over IEEE802.15.4, with an eight-octet address.
20 Ieee802154([u8; 8]),
21 /// Indicates that a Driver is IP-native, and has no hardware address.
22 ///
23 /// Devices of this type send and receive IP frames, without an
24 /// Ethernet header. MAC addresses are not used, and no neighbor discovery (ARP, NDISC) is done.
25 ///
26 /// Examples of devices of this type are the Linux `tun`, PPP interfaces, VPNs in tun (layer 3) mode.
27 Ip,
28}
29
30/// Main `embassy-net` driver API.
31///
32/// This is essentially an interface for sending and receiving raw network frames.
33///
34/// The interface is based on _tokens_, which are types that allow to receive/transmit a
35/// single packet. The `receive` and `transmit` functions only construct such tokens, the
36/// real sending/receiving operation are performed when the tokens are consumed.
37pub trait Driver {
38 /// A token to receive a single network packet.
39 type RxToken<'a>: RxToken
40 where
41 Self: 'a;
42
43 /// A token to transmit a single network packet.
44 type TxToken<'a>: TxToken
45 where
46 Self: 'a;
47
48 /// Construct a token pair consisting of one receive token and one transmit token.
49 ///
50 /// If there is a packet ready to be received, this function must return `Some`.
51 /// If there isn't, it must return `None`, and wake `cx.waker()` when a packet is ready.
52 ///
53 /// The additional transmit token makes it possible to generate a reply packet based
54 /// on the contents of the received packet. For example, this makes it possible to
55 /// handle arbitrarily large ICMP echo ("ping") requests, where the all received bytes
56 /// need to be sent back, without heap allocation.
57 fn receive(&mut self, cx: &mut Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)>;
58
59 /// Construct a transmit token.
60 ///
61 /// If there is free space in the transmit buffer to transmit a packet, this function must return `Some`.
62 /// If there isn't, it must return `None`, and wake `cx.waker()` when space becomes available.
63 ///
64 /// Note that [`TxToken::consume`] is infallible, so it is not allowed to return a token
65 /// if there is no free space and fail later.
66 fn transmit(&mut self, cx: &mut Context) -> Option<Self::TxToken<'_>>;
67
68 /// Get the link state.
69 ///
70 /// This function must return the current link state of the device, and wake `cx.waker()` when
71 /// the link state changes.
72 fn link_state(&mut self, cx: &mut Context) -> LinkState;
73
74 /// Get a description of device capabilities.
75 fn capabilities(&self) -> Capabilities;
76
77 /// Get the device's hardware address.
78 ///
79 /// The returned hardware address also determines the "medium" of this driver. This indicates
80 /// what kind of packet the sent/received bytes are, and determines some behaviors of
81 /// the interface. For example, ARP/NDISC address resolution is only done for Ethernet mediums.
82 fn hardware_address(&self) -> HardwareAddress;
83}
84
85impl<T: ?Sized + Driver> Driver for &mut T {
86 type RxToken<'a> = T::RxToken<'a>
87 where
88 Self: 'a;
89 type TxToken<'a> = T::TxToken<'a>
90 where
91 Self: 'a;
92
93 fn transmit(&mut self, cx: &mut Context) -> Option<Self::TxToken<'_>> {
94 T::transmit(self, cx)
95 }
96 fn receive(&mut self, cx: &mut Context) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
97 T::receive(self, cx)
98 }
99 fn capabilities(&self) -> Capabilities {
100 T::capabilities(self)
101 }
102 fn link_state(&mut self, cx: &mut Context) -> LinkState {
103 T::link_state(self, cx)
104 }
105 fn hardware_address(&self) -> HardwareAddress {
106 T::hardware_address(self)
107 }
108}
109
110/// A token to receive a single network packet.
111pub trait RxToken {
112 /// Consumes the token to receive a single network packet.
113 ///
114 /// This method receives a packet and then calls the given closure `f` with the raw
115 /// packet bytes as argument.
116 fn consume<R, F>(self, f: F) -> R
117 where
118 F: FnOnce(&mut [u8]) -> R;
119}
120
121/// A token to transmit a single network packet.
122pub trait TxToken {
123 /// Consumes the token to send a single network packet.
124 ///
125 /// This method constructs a transmit buffer of size `len` and calls the passed
126 /// closure `f` with a mutable reference to that buffer. The closure should construct
127 /// a valid network packet (e.g. an ethernet packet) in the buffer. When the closure
128 /// returns, the transmit buffer is sent out.
129 fn consume<R, F>(self, len: usize, f: F) -> R
130 where
131 F: FnOnce(&mut [u8]) -> R;
132}
133
134/// A description of device capabilities.
135///
136/// Higher-level protocols may achieve higher throughput or lower latency if they consider
137/// the bandwidth or packet size limitations.
138#[derive(Debug, Clone, Default)]
139#[cfg_attr(feature = "defmt", derive(defmt::Format))]
140#[non_exhaustive]
141pub struct Capabilities {
142 /// Maximum transmission unit.
143 ///
144 /// The network device is unable to send or receive frames larger than the value returned
145 /// by this function.
146 ///
147 /// For Ethernet devices, this is the maximum Ethernet frame size, including the Ethernet header (14 octets), but
148 /// *not* including the Ethernet FCS (4 octets). Therefore, Ethernet MTU = IP MTU + 14.
149 ///
150 /// Note that in Linux and other OSes, "MTU" is the IP MTU, not the Ethernet MTU, even for Ethernet
151 /// devices. This is a common source of confusion.
152 ///
153 /// Most common IP MTU is 1500. Minimum is 576 (for IPv4) or 1280 (for IPv6). Maximum is 9216 octets.
154 pub max_transmission_unit: usize,
155
156 /// Maximum burst size, in terms of MTU.
157 ///
158 /// The network device is unable to send or receive bursts large than the value returned
159 /// by this function.
160 ///
161 /// If `None`, there is no fixed limit on burst size, e.g. if network buffers are
162 /// dynamically allocated.
163 pub max_burst_size: Option<usize>,
164
165 /// Checksum behavior.
166 ///
167 /// If the network device is capable of verifying or computing checksums for some protocols,
168 /// it can request that the stack not do so in software to improve performance.
169 pub checksum: ChecksumCapabilities,
170}
171
172/// A description of checksum behavior for every supported protocol.
173#[derive(Debug, Clone, Default)]
174#[cfg_attr(feature = "defmt", derive(defmt::Format))]
175#[non_exhaustive]
176pub struct ChecksumCapabilities {
177 /// Checksum behavior for IPv4.
178 pub ipv4: Checksum,
179 /// Checksum behavior for UDP.
180 pub udp: Checksum,
181 /// Checksum behavior for TCP.
182 pub tcp: Checksum,
183 /// Checksum behavior for ICMPv4.
184 pub icmpv4: Checksum,
185 /// Checksum behavior for ICMPv6.
186 pub icmpv6: Checksum,
187}
188
189/// A description of checksum behavior for a particular protocol.
190#[derive(Debug, Clone, Copy)]
191#[cfg_attr(feature = "defmt", derive(defmt::Format))]
192pub enum Checksum {
193 /// Verify checksum when receiving and compute checksum when sending.
194 Both,
195 /// Verify checksum when receiving.
196 Rx,
197 /// Compute checksum before sending.
198 Tx,
199 /// Ignore checksum completely.
200 None,
201}
202
203impl Default for Checksum {
204 fn default() -> Checksum {
205 Checksum::Both
206 }
207}
208
209/// The link state of a network device.
210#[derive(PartialEq, Eq, Clone, Copy)]
211#[cfg_attr(feature = "defmt", derive(defmt::Format))]
212pub enum LinkState {
213 /// The link is down.
214 Down,
215 /// The link is up.
216 Up,
217}