diff --git a/ci.sh b/ci.sh index 32ae7855e..2693c1be5 100755 --- a/ci.sh +++ b/ci.sh @@ -36,6 +36,9 @@ cargo batch \ --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,proto-ipv6,medium-ethernet,unstable-traits \ --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,proto-ipv6,medium-ethernet,nightly \ --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,proto-ipv6,medium-ethernet,unstable-traits,nightly \ + --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,proto-ipv6,medium-ip,unstable-traits,nightly \ + --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,proto-ipv6,medium-ip,medium-ethernet,unstable-traits,nightly \ + --- build --release --manifest-path embassy-net/Cargo.toml --target thumbv7em-none-eabi --features defmt,tcp,udp,dns,proto-ipv4,proto-ipv6,medium-ip,medium-ethernet,medium-ieee802154,unstable-traits,nightly \ --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52805,gpiote,time-driver-rtc1 \ --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52810,gpiote,time-driver-rtc1 \ --- build --release --manifest-path embassy-nrf/Cargo.toml --target thumbv7em-none-eabi --features nightly,nrf52811,gpiote,time-driver-rtc1 \ diff --git a/cyw43/src/lib.rs b/cyw43/src/lib.rs index fd11f3674..30a3d5f26 100644 --- a/cyw43/src/lib.rs +++ b/cyw43/src/lib.rs @@ -216,7 +216,7 @@ where PWR: OutputPin, SPI: SpiBusCyw43, { - let (ch_runner, device) = ch::new(&mut state.ch, [0; 6]); + let (ch_runner, device) = ch::new(&mut state.ch, ch::driver::HardwareAddress::Ethernet([0; 6])); let state_ch = ch_runner.state_runner(); let mut runner = Runner::new(ch_runner, Bus::new(pwr, spi), &state.ioctl_state, &state.events); diff --git a/embassy-net-driver-channel/src/lib.rs b/embassy-net-driver-channel/src/lib.rs index 02a4c00d6..076238ba0 100644 --- a/embassy-net-driver-channel/src/lib.rs +++ b/embassy-net-driver-channel/src/lib.rs @@ -42,7 +42,7 @@ struct StateInner<'d, const MTU: usize> { struct Shared { link_state: LinkState, waker: WakerRegistration, - ethernet_address: [u8; 6], + hardware_address: driver::HardwareAddress, } pub struct Runner<'d, const MTU: usize> { @@ -85,10 +85,10 @@ impl<'d, const MTU: usize> Runner<'d, MTU> { }); } - pub fn set_ethernet_address(&mut self, address: [u8; 6]) { + pub fn set_hardware_address(&mut self, address: driver::HardwareAddress) { self.shared.lock(|s| { let s = &mut *s.borrow_mut(); - s.ethernet_address = address; + s.hardware_address = address; s.waker.wake(); }); } @@ -150,7 +150,15 @@ impl<'d> StateRunner<'d> { pub fn set_ethernet_address(&self, address: [u8; 6]) { self.shared.lock(|s| { let s = &mut *s.borrow_mut(); - s.ethernet_address = address; + s.hardware_address = driver::HardwareAddress::Ethernet(address); + s.waker.wake(); + }); + } + + pub fn set_ieee802154_address(&self, address: [u8; 8]) { + self.shared.lock(|s| { + let s = &mut *s.borrow_mut(); + s.hardware_address = driver::HardwareAddress::Ieee802154(address); s.waker.wake(); }); } @@ -206,7 +214,7 @@ impl<'d, const MTU: usize> TxRunner<'d, MTU> { pub fn new<'d, const MTU: usize, const N_RX: usize, const N_TX: usize>( state: &'d mut State, - ethernet_address: [u8; 6], + hardware_address: driver::HardwareAddress, ) -> (Runner<'d, MTU>, Device<'d, MTU>) { let mut caps = Capabilities::default(); caps.max_transmission_unit = MTU; @@ -222,7 +230,7 @@ pub fn new<'d, const MTU: usize, const N_RX: usize, const N_TX: usize>( tx: zerocopy_channel::Channel::new(&mut state.tx[..]), shared: Mutex::new(RefCell::new(Shared { link_state: LinkState::Down, - ethernet_address, + hardware_address, waker: WakerRegistration::new(), })), }); @@ -289,8 +297,8 @@ impl<'d, const MTU: usize> embassy_net_driver::Driver for Device<'d, MTU> { self.caps.clone() } - fn ethernet_address(&self) -> [u8; 6] { - self.shared.lock(|s| s.borrow().ethernet_address) + fn hardware_address(&self) -> driver::HardwareAddress { + self.shared.lock(|s| s.borrow().hardware_address) } fn link_state(&mut self, cx: &mut Context) -> LinkState { diff --git a/embassy-net-driver/Cargo.toml b/embassy-net-driver/Cargo.toml index da6d9ad62..e25950b6b 100644 --- a/embassy-net-driver/Cargo.toml +++ b/embassy-net-driver/Cargo.toml @@ -21,4 +21,4 @@ target = "thumbv7em-none-eabi" features = ["defmt"] [dependencies] -defmt = { version = "0.3", optional = true } \ No newline at end of file +defmt = { version = "0.3", optional = true } diff --git a/embassy-net-driver/src/lib.rs b/embassy-net-driver/src/lib.rs index 09def20c4..b64c10000 100644 --- a/embassy-net-driver/src/lib.rs +++ b/embassy-net-driver/src/lib.rs @@ -4,6 +4,18 @@ use core::task::Context; +/// Representation of an hardware address, such as an Ethernet address or an IEEE802.15.4 address. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum HardwareAddress { + /// A six-octet Ethernet address + Ethernet([u8; 6]), + /// An eight-octet IEEE802.15.4 address + Ieee802154([u8; 8]), + /// Indicates that a Driver is IP-native, and has no hardware address + Ip, +} + /// Main `embassy-net` driver API. /// /// This is essentially an interface for sending and receiving raw network frames. @@ -51,8 +63,8 @@ pub trait Driver { /// Get a description of device capabilities. fn capabilities(&self) -> Capabilities; - /// Get the device's Ethernet address. - fn ethernet_address(&self) -> [u8; 6]; + /// Get the device's hardware address. + fn hardware_address(&self) -> HardwareAddress; } impl Driver for &mut T { @@ -75,8 +87,8 @@ impl Driver for &mut T { fn link_state(&mut self, cx: &mut Context) -> LinkState { T::link_state(self, cx) } - fn ethernet_address(&self) -> [u8; 6] { - T::ethernet_address(self) + fn hardware_address(&self) -> HardwareAddress { + T::hardware_address(self) } } diff --git a/embassy-net-esp-hosted/src/lib.rs b/embassy-net-esp-hosted/src/lib.rs index a35adfca0..96fddce58 100644 --- a/embassy-net-esp-hosted/src/lib.rs +++ b/embassy-net-esp-hosted/src/lib.rs @@ -124,7 +124,7 @@ where IN: InputPin + Wait, OUT: OutputPin, { - let (ch_runner, device) = ch::new(&mut state.ch, [0; 6]); + let (ch_runner, device) = ch::new(&mut state.ch, ch::driver::HardwareAddress::Ethernet([0; 6])); let state_ch = ch_runner.state_runner(); let mut runner = Runner { diff --git a/embassy-net-w5500/src/lib.rs b/embassy-net-w5500/src/lib.rs index efd9bed66..52494b443 100644 --- a/embassy-net-w5500/src/lib.rs +++ b/embassy-net-w5500/src/lib.rs @@ -96,7 +96,7 @@ pub async fn new<'a, const N_RX: usize, const N_TX: usize, SPI: SpiDevice, INT: let mac = W5500::new(spi_dev, mac_addr).await.unwrap(); - let (runner, device) = ch::new(&mut state.ch_state, mac_addr); + let (runner, device) = ch::new(&mut state.ch_state, ch::driver::HardwareAddress::Ethernet(mac_addr)); ( device, Runner { diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs index 3f9150168..2fb34f43a 100644 --- a/embassy-net/src/lib.rs +++ b/embassy-net/src/lib.rs @@ -34,7 +34,7 @@ use smoltcp::iface::{Interface, SocketHandle, SocketSet, SocketStorage}; use smoltcp::socket::dhcpv4::{self, RetryConfig}; #[cfg(feature = "medium-ethernet")] pub use smoltcp::wire::EthernetAddress; -#[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))] +#[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154", feature = "medium-ip"))] pub use smoltcp::wire::HardwareAddress; #[cfg(feature = "udp")] pub use smoltcp::wire::IpListenEndpoint; @@ -230,6 +230,20 @@ pub(crate) struct SocketStack { next_local_port: u16, } +fn to_smoltcp_hardware_address(addr: driver::HardwareAddress) -> HardwareAddress { + match addr { + #[cfg(feature = "medium-ethernet")] + driver::HardwareAddress::Ethernet(eth) => HardwareAddress::Ethernet(EthernetAddress(eth)), + #[cfg(feature = "medium-ieee802154")] + driver::HardwareAddress::Ieee802154(ieee) => HardwareAddress::Ieee802154(Ieee802154Address::Extended(ieee)), + #[cfg(feature = "medium-ip")] + driver::HardwareAddress::Ip => HardwareAddress::Ip, + + #[allow(unreachable_patterns)] + _ => panic!("Unsupported address {:?}. Make sure to enable medium-ethernet or medium-ieee802154 in embassy-net's Cargo features.", addr), + } +} + impl Stack { /// Create a new network stack. pub fn new( @@ -238,23 +252,7 @@ impl Stack { resources: &'static mut StackResources, random_seed: u64, ) -> Self { - #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))] - let medium = device.capabilities().medium; - - let hardware_addr = match medium { - #[cfg(feature = "medium-ethernet")] - Medium::Ethernet => HardwareAddress::Ethernet(EthernetAddress(device.ethernet_address())), - #[cfg(feature = "medium-ip")] - Medium::Ip => HardwareAddress::Ip, - #[cfg(feature = "medium-ieee802154")] - Medium::Ieee802154 => HardwareAddress::Ieee802154(Ieee802154Address::Absent), - #[allow(unreachable_patterns)] - _ => panic!( - "Unsupported medium {:?}. Make sure to enable it in embassy-net's Cargo features.", - medium - ), - }; - let mut iface_cfg = smoltcp::iface::Config::new(hardware_addr); + let mut iface_cfg = smoltcp::iface::Config::new(to_smoltcp_hardware_address(device.hardware_address())); iface_cfg.random_seed = random_seed; let iface = Interface::new( @@ -336,9 +334,9 @@ impl Stack { f(&mut *self.socket.borrow_mut(), &mut *self.inner.borrow_mut()) } - /// Get the MAC address of the network interface. - pub fn ethernet_address(&self) -> [u8; 6] { - self.with(|_s, i| i.device.ethernet_address()) + /// Get the hardware address of the network interface. + pub fn hardware_address(&self) -> HardwareAddress { + self.with(|_s, i| to_smoltcp_hardware_address(i.device.hardware_address())) } /// Get whether the link is up. @@ -585,9 +583,6 @@ impl SocketStack { impl Inner { #[cfg(feature = "proto-ipv4")] fn apply_config_v4(&mut self, s: &mut SocketStack, config: StaticConfigV4) { - #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))] - let medium = self.device.capabilities().medium; - debug!("Acquired IP configuration:"); debug!(" IP address: {}", config.address); @@ -602,8 +597,12 @@ impl Inner { addrs.push(IpCidr::Ipv4(config.address)).unwrap(); }); - #[cfg(feature = "medium-ethernet")] - if medium == Medium::Ethernet { + #[cfg(feature = "medium-ip")] + let skip_gateway = self.device.capabilities().medium != Medium::Ip; + #[cfg(not(feature = "medium-ip"))] + let skip_gateway = false; + + if !skip_gateway { if let Some(gateway) = config.gateway { debug!(" Default gateway: {}", gateway); s.iface.routes_mut().add_default_ipv4_route(gateway).unwrap(); @@ -740,11 +739,12 @@ impl Inner { fn poll(&mut self, cx: &mut Context<'_>, s: &mut SocketStack) { s.waker.register(cx.waker()); - #[cfg(feature = "medium-ethernet")] - if self.device.capabilities().medium == Medium::Ethernet { - s.iface.set_hardware_addr(HardwareAddress::Ethernet(EthernetAddress( - self.device.ethernet_address(), - ))); + #[cfg(any(feature = "medium-ethernet", feature = "medium-ieee802154"))] + if self.device.capabilities().medium == Medium::Ethernet + || self.device.capabilities().medium == Medium::Ieee802154 + { + s.iface + .set_hardware_addr(to_smoltcp_hardware_address(self.device.hardware_address())); } let timestamp = instant_to_smoltcp(Instant::now()); diff --git a/embassy-stm32-wpan/src/mac/driver.rs b/embassy-stm32-wpan/src/mac/driver.rs index fffbb9edc..f8e3a2b08 100644 --- a/embassy-stm32-wpan/src/mac/driver.rs +++ b/embassy-stm32-wpan/src/mac/driver.rs @@ -3,7 +3,7 @@ use core::task::Context; -use embassy_net_driver::{Capabilities, LinkState, Medium}; +use embassy_net_driver::{Capabilities, HardwareAddress, LinkState, Medium}; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::channel::Channel; @@ -73,10 +73,10 @@ impl<'d> embassy_net_driver::Driver for Driver<'d> { LinkState::Down } - fn ethernet_address(&self) -> [u8; 6] { + fn hardware_address(&self) -> HardwareAddress { // self.mac_addr - [0; 6] + HardwareAddress::Ieee802154([0; 8]) } } diff --git a/embassy-stm32/src/eth/mod.rs b/embassy-stm32/src/eth/mod.rs index 1687cb319..1e057235a 100644 --- a/embassy-stm32/src/eth/mod.rs +++ b/embassy-stm32/src/eth/mod.rs @@ -8,7 +8,7 @@ pub mod generic_smi; use core::mem::MaybeUninit; use core::task::Context; -use embassy_net_driver::{Capabilities, LinkState}; +use embassy_net_driver::{Capabilities, HardwareAddress, LinkState}; use embassy_sync::waitqueue::AtomicWaker; pub use self::_version::{InterruptHandler, *}; @@ -88,8 +88,8 @@ impl<'d, T: Instance, P: PHY> embassy_net_driver::Driver for Ethernet<'d, T, P> } } - fn ethernet_address(&self) -> [u8; 6] { - self.mac_addr + fn hardware_address(&self) -> HardwareAddress { + HardwareAddress::Ethernet(self.mac_addr) } } diff --git a/embassy-usb/src/class/cdc_ncm/embassy_net.rs b/embassy-usb/src/class/cdc_ncm/embassy_net.rs index 670709021..57d322946 100644 --- a/embassy-usb/src/class/cdc_ncm/embassy_net.rs +++ b/embassy-usb/src/class/cdc_ncm/embassy_net.rs @@ -87,7 +87,10 @@ impl<'d, D: Driver<'d>> CdcNcmClass<'d, D> { ethernet_address: [u8; 6], ) -> (Runner<'d, D, MTU>, Device<'d, MTU>) { let (tx_usb, rx_usb) = self.split(); - let (runner, device) = ch::new(&mut state.ch_state, ethernet_address); + let (runner, device) = ch::new( + &mut state.ch_state, + ch::driver::HardwareAddress::Ethernet(ethernet_address), + ); ( Runner { diff --git a/examples/std/src/tuntap.rs b/examples/std/src/tuntap.rs index d918a2e62..167c3da5f 100644 --- a/examples/std/src/tuntap.rs +++ b/examples/std/src/tuntap.rs @@ -4,7 +4,7 @@ use std::os::unix::io::{AsRawFd, RawFd}; use std::task::Context; use async_io::Async; -use embassy_net_driver::{self, Capabilities, Driver, LinkState}; +use embassy_net_driver::{self, Capabilities, Driver, HardwareAddress, LinkState}; use log::*; pub const SIOCGIFMTU: libc::c_ulong = 0x8921; @@ -180,8 +180,8 @@ impl Driver for TunTapDevice { LinkState::Up } - fn ethernet_address(&self) -> [u8; 6] { - [0x02, 0x03, 0x04, 0x05, 0x06, 0x07] + fn hardware_address(&self) -> HardwareAddress { + HardwareAddress::Ethernet([0x02, 0x03, 0x04, 0x05, 0x06, 0x07]) } }