Skip to content

Commit ee85f30

Browse files
committed
socket: create basic ethernet socket
1 parent beaf2d2 commit ee85f30

File tree

1 file changed

+305
-0
lines changed

1 file changed

+305
-0
lines changed

src/socket/eth.rs

Lines changed: 305 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,306 @@
1+
use core::cmp::min;
2+
#[cfg(feature = "async")]
3+
use core::task::Waker;
4+
5+
use crate::iface::Context;
6+
use crate::socket::PollAt;
7+
#[cfg(feature = "async")]
8+
use crate::socket::WakerRegistration;
9+
10+
use crate::storage::Empty;
11+
12+
/// Error returned by [`Socket::send`]
13+
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
14+
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
15+
pub enum SendError {
16+
BufferFull,
17+
}
18+
19+
impl core::fmt::Display for SendError {
20+
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
21+
match self {
22+
SendError::BufferFull => write!(f, "buffer full"),
23+
}
24+
}
25+
}
26+
27+
#[cfg(feature = "std")]
28+
impl std::error::Error for SendError {}
29+
30+
/// Error returned by [`Socket::recv`]
31+
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
32+
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
33+
pub enum RecvError {
34+
Exhausted,
35+
Truncated,
36+
}
37+
38+
impl core::fmt::Display for RecvError {
39+
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
40+
match self {
41+
RecvError::Exhausted => write!(f, "exhausted"),
42+
RecvError::Truncated => write!(f, "truncated"),
43+
}
44+
}
45+
}
46+
47+
#[cfg(feature = "std")]
48+
impl std::error::Error for RecvError {}
49+
50+
/// A Eth packet metadata.
51+
pub type PacketMetadata = crate::storage::PacketMetadata<()>;
52+
53+
/// A Eth packet ring buffer.
54+
pub type PacketBuffer<'a> = crate::storage::PacketBuffer<'a, ()>;
55+
56+
pub type Ethertype = u16;
57+
58+
/// A raw Ethernet socket.
59+
///
60+
/// A eth socket may be bound to a specific ethertype, and owns
61+
/// transmit and receive packet buffers.
62+
#[derive(Debug)]
63+
pub struct Socket<'a> {
64+
ethertype: Option<Ethertype>,
65+
rx_buffer: PacketBuffer<'a>,
66+
tx_buffer: PacketBuffer<'a>,
67+
#[cfg(feature = "async")]
68+
rx_waker: WakerRegistration,
69+
#[cfg(feature = "async")]
70+
tx_waker: WakerRegistration,
71+
}
72+
73+
impl<'a> Socket<'a> {
74+
/// Create a raw ETH socket bound to the given ethertype, with the given buffers.
75+
pub fn new(
76+
ethertype: Option<Ethertype>,
77+
rx_buffer: PacketBuffer<'a>,
78+
tx_buffer: PacketBuffer<'a>,
79+
) -> Socket<'a> {
80+
Socket {
81+
ethertype,
82+
rx_buffer,
83+
tx_buffer,
84+
#[cfg(feature = "async")]
85+
rx_waker: WakerRegistration::new(),
86+
#[cfg(feature = "async")]
87+
tx_waker: WakerRegistration::new(),
88+
}
89+
}
90+
91+
/// Register a waker for receive operations.
92+
///
93+
/// The waker is woken on state changes that might affect the return value
94+
/// of `recv` method calls, such as receiving data, or the socket closing.
95+
///
96+
/// Notes:
97+
///
98+
/// - Only one waker can be registered at a time. If another waker was previously registered,
99+
/// it is overwritten and will no longer be woken.
100+
/// - The Waker is woken only once. Once woken, you must register it again to receive more wakes.
101+
/// - "Spurious wakes" are allowed: a wake doesn't guarantee the result of `recv` has
102+
/// necessarily changed.
103+
#[cfg(feature = "async")]
104+
pub fn register_recv_waker(&mut self, waker: &Waker) {
105+
self.rx_waker.register(waker)
106+
}
107+
108+
/// Register a waker for send operations.
109+
///
110+
/// The waker is woken on state changes that might affect the return value
111+
/// of `send` method calls, such as space becoming available in the transmit
112+
/// buffer, or the socket closing.
113+
///
114+
/// Notes:
115+
///
116+
/// - Only one waker can be registered at a time. If another waker was previously registered,
117+
/// it is overwritten and will no longer be woken.
118+
/// - The Waker is woken only once. Once woken, you must register it again to receive more wakes.
119+
/// - "Spurious wakes" are allowed: a wake doesn't guarantee the result of `send` has
120+
/// necessarily changed.
121+
#[cfg(feature = "async")]
122+
pub fn register_send_waker(&mut self, waker: &Waker) {
123+
self.tx_waker.register(waker)
124+
}
125+
126+
/// Return the ethertype the socket is bound to.
127+
#[inline]
128+
pub fn ethertype(&self) -> Option<Ethertype> {
129+
self.ethertype
130+
}
131+
132+
/// Check whether the transmit buffer is full.
133+
#[inline]
134+
pub fn can_send(&self) -> bool {
135+
!self.tx_buffer.is_full()
136+
}
137+
138+
/// Check whether the receive buffer is not empty.
139+
#[inline]
140+
pub fn can_recv(&self) -> bool {
141+
!self.rx_buffer.is_empty()
142+
}
143+
144+
/// Return the maximum number packets the socket can receive.
145+
#[inline]
146+
pub fn packet_recv_capacity(&self) -> usize {
147+
self.rx_buffer.packet_capacity()
148+
}
149+
150+
/// Return the maximum number packets the socket can transmit.
151+
#[inline]
152+
pub fn packet_send_capacity(&self) -> usize {
153+
self.tx_buffer.packet_capacity()
154+
}
155+
156+
/// Return the maximum number of bytes inside the recv buffer.
157+
#[inline]
158+
pub fn payload_recv_capacity(&self) -> usize {
159+
self.rx_buffer.payload_capacity()
160+
}
161+
162+
/// Return the maximum number of bytes inside the transmit buffer.
163+
#[inline]
164+
pub fn payload_send_capacity(&self) -> usize {
165+
self.tx_buffer.payload_capacity()
166+
}
167+
168+
/// Enqueue a packet to send, and return a pointer to its payload.
169+
///
170+
/// This function returns `Err(Error::Exhausted)` if the transmit buffer is full,
171+
/// and `Err(Error::Truncated)` if there is not enough transmit buffer capacity
172+
/// to ever send this packet.
173+
///
174+
/// If the buffer is filled in a way that does not match the socket's
175+
/// ethertype, the packet will be silently dropped.
176+
pub fn send(&mut self, size: usize) -> Result<&mut [u8], SendError> {
177+
let packet_buf = self
178+
.tx_buffer
179+
.enqueue(size, ())
180+
.map_err(|_| SendError::BufferFull)?;
181+
182+
net_trace!(
183+
"eth:{}: buffer to send {} octets",
184+
self.ethertype.unwrap_or(0),
185+
packet_buf.len()
186+
);
187+
Ok(packet_buf)
188+
}
189+
190+
/// Enqueue a packet to be send and pass the buffer to the provided closure.
191+
/// The closure then returns the size of the data written into the buffer.
192+
///
193+
/// Also see [send](#method.send).
194+
pub fn send_with<F>(&mut self, max_size: usize, f: F) -> Result<usize, SendError>
195+
where
196+
F: FnOnce(&mut [u8]) -> usize,
197+
{
198+
let size = self
199+
.tx_buffer
200+
.enqueue_with_infallible(max_size, (), f)
201+
.map_err(|_| SendError::BufferFull)?;
202+
203+
net_trace!(
204+
"eth:{}: buffer to send {} octets",
205+
self.ethertype.unwrap_or(0),
206+
size
207+
);
208+
209+
Ok(size)
210+
}
211+
212+
/// Enqueue a packet to send, and fill it from a slice.
213+
///
214+
/// See also [send](#method.send).
215+
pub fn send_slice(&mut self, data: &[u8]) -> Result<(), SendError> {
216+
self.send(data.len())?.copy_from_slice(data);
217+
Ok(())
218+
}
219+
220+
/// Dequeue a packet, and return a pointer to the payload.
221+
///
222+
/// This function returns `Err(Error::Exhausted)` if the receive buffer is empty.
223+
pub fn recv(&mut self) -> Result<&[u8], RecvError> {
224+
let ((), packet_buf) = self.rx_buffer.dequeue().map_err(|_| RecvError::Exhausted)?;
225+
226+
net_trace!(
227+
"eth:{}: receive {} buffered octets",
228+
self.ethertype.unwrap_or(0),
229+
packet_buf.len()
230+
);
231+
Ok(packet_buf)
232+
}
233+
234+
/// Dequeue a packet, and copy the payload into the given slice.
235+
///
236+
/// **Note**: when the size of the provided buffer is smaller than the size of the payload,
237+
/// the packet is dropped and a `RecvError::Truncated` error is returned.
238+
///
239+
/// See also [recv](#method.recv).
240+
pub fn recv_slice(&mut self, data: &mut [u8]) -> Result<usize, RecvError> {
241+
let buffer = self.recv()?;
242+
if data.len() < buffer.len() {
243+
return Err(RecvError::Truncated);
244+
}
245+
246+
let length = min(data.len(), buffer.len());
247+
data[..length].copy_from_slice(&buffer[..length]);
248+
Ok(length)
249+
}
250+
251+
/// Peek at a packet in the receive buffer and return a pointer to the
252+
/// payload without removing the packet from the receive buffer.
253+
/// This function otherwise behaves identically to [recv](#method.recv).
254+
///
255+
/// It returns `Err(Error::Exhausted)` if the receive buffer is empty.
256+
pub fn peek(&mut self) -> Result<&[u8], RecvError> {
257+
let ((), packet_buf) = self.rx_buffer.peek().map_err(|_| RecvError::Exhausted)?;
258+
259+
net_trace!(
260+
"eth:{}: receive {} buffered octets",
261+
self.ethertype.unwrap_or(0),
262+
packet_buf.len()
263+
);
264+
265+
Ok(packet_buf)
266+
}
267+
268+
/// Peek at a packet in the receive buffer, copy the payload into the given slice,
269+
/// and return the amount of octets copied without removing the packet from the receive buffer.
270+
/// This function otherwise behaves identically to [recv_slice](#method.recv_slice).
271+
///
272+
/// **Note**: when the size of the provided buffer is smaller than the size of the payload,
273+
/// no data is copied into the provided buffer and a `RecvError::Truncated` error is returned.
274+
///
275+
/// See also [peek](#method.peek).
276+
pub fn peek_slice(&mut self, data: &mut [u8]) -> Result<usize, RecvError> {
277+
let buffer = self.peek()?;
278+
if data.len() < buffer.len() {
279+
return Err(RecvError::Truncated);
280+
}
281+
282+
let length = min(data.len(), buffer.len());
283+
data[..length].copy_from_slice(&buffer[..length]);
284+
Ok(length)
285+
}
286+
287+
/// Return the amount of octets queued in the transmit buffer.
288+
pub fn send_queue(&self) -> usize {
289+
self.tx_buffer.payload_bytes_count()
290+
}
291+
292+
/// Return the amount of octets queued in the receive buffer.
293+
pub fn recv_queue(&self) -> usize {
294+
self.rx_buffer.payload_bytes_count()
295+
}
296+
297+
pub(crate) fn poll_at(&self, _cx: &mut Context) -> PollAt {
298+
if self.tx_buffer.is_empty() {
299+
PollAt::Ingress
300+
} else {
301+
PollAt::Now
302+
}
303+
}
304+
}
305+
1306

0 commit comments

Comments
 (0)