2021-02-03 05:09:37 +01:00
#![ cfg_attr(not(feature = " std " ), no_std) ]
2023-05-14 23:44:53 +02:00
#![ cfg_attr(feature = " nightly " , feature(async_fn_in_trait, impl_trait_projections)) ]
2023-05-15 00:39:57 +02:00
#![ warn(missing_docs) ]
#![ doc = include_str!( " ../README.md " ) ]
2021-02-03 05:09:37 +01:00
// This mod MUST go first, so that the others see its macros.
pub ( crate ) mod fmt ;
2023-02-08 17:52:02 +01:00
mod device ;
2023-01-31 22:06:41 +01:00
#[ cfg(feature = " dns " ) ]
pub mod dns ;
2021-04-07 19:06:45 +02:00
#[ cfg(feature = " tcp " ) ]
2022-05-04 20:48:37 +02:00
pub mod tcp ;
2023-05-15 00:38:58 +02:00
mod time ;
2022-07-28 10:25:47 +02:00
#[ cfg(feature = " udp " ) ]
pub mod udp ;
2022-12-07 16:02:28 +01:00
use core ::cell ::RefCell ;
use core ::future ::{ poll_fn , Future } ;
use core ::task ::{ Context , Poll } ;
2023-05-15 00:39:57 +02:00
pub use embassy_net_driver as driver ;
2022-12-26 03:33:49 +01:00
use embassy_net_driver ::{ Driver , LinkState , Medium } ;
2022-12-07 16:02:28 +01:00
use embassy_sync ::waitqueue ::WakerRegistration ;
use embassy_time ::{ Instant , Timer } ;
use futures ::pin_mut ;
use heapless ::Vec ;
2023-05-15 00:39:57 +02:00
#[ cfg(feature = " igmp " ) ]
pub use smoltcp ::iface ::MulticastError ;
2023-04-18 22:11:15 +02:00
use smoltcp ::iface ::{ Interface , SocketHandle , SocketSet , SocketStorage } ;
2022-12-07 16:02:28 +01:00
#[ cfg(feature = " dhcpv4 " ) ]
2023-04-18 22:11:15 +02:00
use smoltcp ::socket ::dhcpv4 ::{ self , RetryConfig } ;
2023-05-15 00:55:34 +02:00
#[ cfg(feature = " udp " ) ]
pub use smoltcp ::wire ::IpListenEndpoint ;
2021-11-26 20:39:21 +01:00
#[ cfg(feature = " medium-ethernet " ) ]
pub use smoltcp ::wire ::{ EthernetAddress , HardwareAddress } ;
pub use smoltcp ::wire ::{ IpAddress , IpCidr , Ipv4Address , Ipv4Cidr } ;
2022-06-01 13:48:09 +02:00
#[ cfg(feature = " proto-ipv6 " ) ]
pub use smoltcp ::wire ::{ Ipv6Address , Ipv6Cidr } ;
2022-12-07 16:02:28 +01:00
2022-12-26 03:33:49 +01:00
use crate ::device ::DriverAdapter ;
2023-05-15 00:38:58 +02:00
use crate ::time ::{ instant_from_smoltcp , instant_to_smoltcp } ;
2022-12-07 16:02:28 +01:00
const LOCAL_PORT_MIN : u16 = 1025 ;
const LOCAL_PORT_MAX : u16 = 65535 ;
2023-02-10 18:34:21 +01:00
#[ cfg(feature = " dns " ) ]
const MAX_QUERIES : usize = 4 ;
2022-12-07 16:02:28 +01:00
2023-05-15 00:39:57 +02:00
/// Memory resources needed for a network stack.
2023-01-18 10:10:33 +01:00
pub struct StackResources < const SOCK : usize > {
2022-12-07 16:02:28 +01:00
sockets : [ SocketStorage < 'static > ; SOCK ] ,
2023-02-10 17:43:23 +01:00
#[ cfg(feature = " dns " ) ]
2023-02-10 18:30:17 +01:00
queries : [ Option < dns ::DnsQuery > ; MAX_QUERIES ] ,
2022-12-07 16:02:28 +01:00
}
2023-01-18 10:10:33 +01:00
impl < const SOCK : usize > StackResources < SOCK > {
2023-05-15 00:39:57 +02:00
/// Create a new set of stack resources.
2022-12-07 16:02:28 +01:00
pub fn new ( ) -> Self {
2023-02-10 17:43:23 +01:00
#[ cfg(feature = " dns " ) ]
const INIT : Option < dns ::DnsQuery > = None ;
2022-12-07 16:02:28 +01:00
Self {
sockets : [ SocketStorage ::EMPTY ; SOCK ] ,
2023-02-10 17:43:23 +01:00
#[ cfg(feature = " dns " ) ]
2023-02-10 18:30:17 +01:00
queries : [ INIT ; MAX_QUERIES ] ,
2022-12-07 16:02:28 +01:00
}
}
}
2023-05-15 00:39:57 +02:00
/// Static IP address configuration.
2022-12-07 16:02:28 +01:00
#[ derive(Debug, Clone, PartialEq, Eq) ]
2023-06-05 14:57:17 +02:00
pub struct StaticConfigV4 {
2023-05-15 00:39:57 +02:00
/// IP address and subnet mask.
2022-12-07 16:02:28 +01:00
pub address : Ipv4Cidr ,
2023-05-15 00:39:57 +02:00
/// Default gateway.
2022-12-07 16:02:28 +01:00
pub gateway : Option < Ipv4Address > ,
2023-05-15 00:39:57 +02:00
/// DNS servers.
2022-12-07 16:02:28 +01:00
pub dns_servers : Vec < Ipv4Address , 3 > ,
}
2023-05-15 00:39:57 +02:00
/// DHCP configuration.
2023-04-18 22:11:15 +02:00
#[ cfg(feature = " dhcpv4 " ) ]
2023-01-18 10:10:33 +01:00
#[ derive(Debug, Clone, PartialEq, Eq) ]
pub struct DhcpConfig {
2023-05-15 00:39:57 +02:00
/// Maximum lease duration.
///
/// If not set, the lease duration specified by the server will be used.
/// If set, the lease duration will be capped at this value.
2023-05-15 00:38:58 +02:00
pub max_lease_duration : Option < embassy_time ::Duration > ,
2023-05-15 00:39:57 +02:00
/// Retry configuration.
2023-01-18 10:10:33 +01:00
pub retry_config : RetryConfig ,
2023-05-15 00:39:57 +02:00
/// Ignore NAKs from DHCP servers.
///
/// This is not compliant with the DHCP RFCs, since theoretically we must stop using the assigned IP when receiving a NAK. This can increase reliability on broken networks with buggy routers or rogue DHCP servers, however.
2023-01-18 10:10:33 +01:00
pub ignore_naks : bool ,
2023-05-15 00:39:57 +02:00
/// Server port. This is almost always 67. Do not change unless you know what you're doing.
2023-01-18 10:10:33 +01:00
pub server_port : u16 ,
2023-05-15 00:39:57 +02:00
/// Client port. This is almost always 68. Do not change unless you know what you're doing.
2023-01-18 10:10:33 +01:00
pub client_port : u16 ,
}
2023-04-18 22:11:15 +02:00
#[ cfg(feature = " dhcpv4 " ) ]
2023-01-18 10:10:33 +01:00
impl Default for DhcpConfig {
fn default ( ) -> Self {
Self {
max_lease_duration : Default ::default ( ) ,
retry_config : Default ::default ( ) ,
ignore_naks : Default ::default ( ) ,
server_port : smoltcp ::wire ::DHCP_SERVER_PORT ,
client_port : smoltcp ::wire ::DHCP_CLIENT_PORT ,
}
}
}
2023-05-15 00:39:57 +02:00
/// Network stack configuration.
2023-01-18 10:10:33 +01:00
pub enum Config {
2023-05-15 00:39:57 +02:00
/// Use a static IP address configuration.
2023-06-05 14:57:17 +02:00
Static ( StaticConfigV4 ) ,
2023-05-15 00:39:57 +02:00
/// Use DHCP to obtain an IP address configuration.
2022-12-07 16:02:28 +01:00
#[ cfg(feature = " dhcpv4 " ) ]
2023-01-18 10:10:33 +01:00
Dhcp ( DhcpConfig ) ,
2022-12-07 16:02:28 +01:00
}
2023-05-15 00:39:57 +02:00
/// A network stack.
///
/// This is the main entry point for the network stack.
2022-12-26 03:33:49 +01:00
pub struct Stack < D : Driver > {
2022-12-07 16:02:28 +01:00
pub ( crate ) socket : RefCell < SocketStack > ,
inner : RefCell < Inner < D > > ,
}
2022-12-26 03:33:49 +01:00
struct Inner < D : Driver > {
2022-12-07 16:02:28 +01:00
device : D ,
link_up : bool ,
2023-06-05 14:57:17 +02:00
config : Option < StaticConfigV4 > ,
2022-12-07 16:02:28 +01:00
#[ cfg(feature = " dhcpv4 " ) ]
dhcp_socket : Option < SocketHandle > ,
2023-02-10 17:43:23 +01:00
#[ cfg(feature = " dns " ) ]
2023-02-10 18:30:17 +01:00
dns_socket : SocketHandle ,
2023-02-10 18:44:51 +01:00
#[ cfg(feature = " dns " ) ]
dns_waker : WakerRegistration ,
2022-12-07 16:02:28 +01:00
}
pub ( crate ) struct SocketStack {
pub ( crate ) sockets : SocketSet < 'static > ,
2023-01-19 14:41:39 +01:00
pub ( crate ) iface : Interface ,
2022-12-07 16:02:28 +01:00
pub ( crate ) waker : WakerRegistration ,
next_local_port : u16 ,
}
2022-12-26 03:33:49 +01:00
impl < D : Driver + 'static > Stack < D > {
2023-05-15 00:39:57 +02:00
/// Create a new network stack.
2023-01-18 10:10:33 +01:00
pub fn new < const SOCK : usize > (
2022-12-07 16:02:28 +01:00
mut device : D ,
2023-01-18 10:10:33 +01:00
config : Config ,
resources : & 'static mut StackResources < SOCK > ,
2022-12-07 16:02:28 +01:00
random_seed : u64 ,
) -> Self {
#[ cfg(feature = " medium-ethernet " ) ]
let medium = device . capabilities ( ) . medium ;
2023-01-19 14:41:39 +01:00
let mut iface_cfg = smoltcp ::iface ::Config ::new ( ) ;
iface_cfg . random_seed = random_seed ;
2022-12-07 16:02:28 +01:00
#[ cfg(feature = " medium-ethernet " ) ]
if medium = = Medium ::Ethernet {
2023-01-19 14:41:39 +01:00
iface_cfg . hardware_addr = Some ( HardwareAddress ::Ethernet ( EthernetAddress ( device . ethernet_address ( ) ) ) ) ;
2022-12-07 16:02:28 +01:00
}
2023-01-19 14:41:39 +01:00
let iface = Interface ::new (
iface_cfg ,
& mut DriverAdapter {
inner : & mut device ,
cx : None ,
} ,
) ;
2022-12-07 16:02:28 +01:00
let sockets = SocketSet ::new ( & mut resources . sockets [ .. ] ) ;
let next_local_port = ( random_seed % ( LOCAL_PORT_MAX - LOCAL_PORT_MIN ) as u64 ) as u16 + LOCAL_PORT_MIN ;
2023-02-10 18:30:17 +01:00
let mut socket = SocketStack {
sockets ,
iface ,
waker : WakerRegistration ::new ( ) ,
next_local_port ,
} ;
2022-12-07 16:02:28 +01:00
let mut inner = Inner {
device ,
link_up : false ,
config : None ,
#[ cfg(feature = " dhcpv4 " ) ]
dhcp_socket : None ,
2023-02-10 17:43:23 +01:00
#[ cfg(feature = " dns " ) ]
2023-02-10 18:44:51 +01:00
dns_socket : socket . sockets . add ( dns ::Socket ::new (
& [ ] ,
managed ::ManagedSlice ::Borrowed ( & mut resources . queries ) ,
) ) ,
#[ cfg(feature = " dns " ) ]
dns_waker : WakerRegistration ::new ( ) ,
2022-12-07 16:02:28 +01:00
} ;
2023-02-10 17:43:23 +01:00
2022-12-07 16:02:28 +01:00
match config {
2023-02-10 17:43:23 +01:00
Config ::Static ( config ) = > {
inner . apply_config ( & mut socket , config ) ;
}
2022-12-07 16:02:28 +01:00
#[ cfg(feature = " dhcpv4 " ) ]
2023-01-18 10:10:33 +01:00
Config ::Dhcp ( config ) = > {
let mut dhcp_socket = smoltcp ::socket ::dhcpv4 ::Socket ::new ( ) ;
inner . apply_dhcp_config ( & mut dhcp_socket , config ) ;
let handle = socket . sockets . add ( dhcp_socket ) ;
2022-12-07 16:02:28 +01:00
inner . dhcp_socket = Some ( handle ) ;
}
}
Self {
socket : RefCell ::new ( socket ) ,
inner : RefCell ::new ( inner ) ,
}
}
fn with < R > ( & self , f : impl FnOnce ( & SocketStack , & Inner < D > ) -> R ) -> R {
f ( & * self . socket . borrow ( ) , & * self . inner . borrow ( ) )
}
fn with_mut < R > ( & self , f : impl FnOnce ( & mut SocketStack , & mut Inner < D > ) -> R ) -> R {
f ( & mut * self . socket . borrow_mut ( ) , & mut * self . inner . borrow_mut ( ) )
}
2023-05-15 00:39:57 +02:00
/// Get the MAC address of the network interface.
2022-12-07 16:02:28 +01:00
pub fn ethernet_address ( & self ) -> [ u8 ; 6 ] {
self . with ( | _s , i | i . device . ethernet_address ( ) )
}
2023-05-15 00:39:57 +02:00
/// Get whether the link is up.
2022-12-07 16:02:28 +01:00
pub fn is_link_up ( & self ) -> bool {
self . with ( | _s , i | i . link_up )
}
2023-05-15 00:39:57 +02:00
/// Get whether the network stack has a valid IP configuration.
/// This is true if the network stack has a static IP configuration or if DHCP has completed
2022-12-07 16:02:28 +01:00
pub fn is_config_up ( & self ) -> bool {
self . with ( | _s , i | i . config . is_some ( ) )
}
2023-05-15 00:39:57 +02:00
/// Get the current IP configuration.
2023-06-05 14:57:17 +02:00
pub fn config ( & self ) -> Option < StaticConfigV4 > {
2022-12-07 16:02:28 +01:00
self . with ( | _s , i | i . config . clone ( ) )
}
2023-05-15 00:39:57 +02:00
/// Run the network stack.
///
/// You must call this in a background task, to process network events.
2022-12-07 16:02:28 +01:00
pub async fn run ( & self ) -> ! {
poll_fn ( | cx | {
self . with_mut ( | s , i | i . poll ( cx , s ) ) ;
Poll ::< ( ) > ::Pending
} )
. await ;
unreachable! ( )
}
2023-02-10 17:43:23 +01:00
2023-02-10 18:20:50 +01:00
/// Make a query for a given name and return the corresponding IP addresses.
2023-02-10 17:43:23 +01:00
#[ cfg(feature = " dns " ) ]
2023-02-10 18:20:50 +01:00
pub async fn dns_query ( & self , name : & str , qtype : dns ::DnsQueryType ) -> Result < Vec < IpAddress , 1 > , dns ::Error > {
2023-02-25 20:58:28 +01:00
// For A and AAAA queries we try detect whether `name` is just an IP address
match qtype {
dns ::DnsQueryType ::A = > {
if let Ok ( ip ) = name . parse ( ) . map ( IpAddress ::Ipv4 ) {
return Ok ( [ ip ] . into_iter ( ) . collect ( ) ) ;
}
}
#[ cfg(feature = " proto-ipv6 " ) ]
dns ::DnsQueryType ::Aaaa = > {
if let Ok ( ip ) = name . parse ( ) . map ( IpAddress ::Ipv6 ) {
return Ok ( [ ip ] . into_iter ( ) . collect ( ) ) ;
}
}
_ = > { }
}
2023-02-10 18:44:51 +01:00
let query = poll_fn ( | cx | {
self . with_mut ( | s , i | {
let socket = s . sockets . get_mut ::< dns ::Socket > ( i . dns_socket ) ;
match socket . start_query ( s . iface . context ( ) , name , qtype ) {
Ok ( handle ) = > Poll ::Ready ( Ok ( handle ) ) ,
Err ( dns ::StartQueryError ::NoFreeSlot ) = > {
i . dns_waker . register ( cx . waker ( ) ) ;
Poll ::Pending
}
Err ( e ) = > Poll ::Ready ( Err ( e ) ) ,
}
} )
} )
. await ? ;
2023-02-10 17:43:23 +01:00
use embassy_hal_common ::drop ::OnDrop ;
let drop = OnDrop ::new ( | | {
self . with_mut ( | s , i | {
2023-02-10 18:30:17 +01:00
let socket = s . sockets . get_mut ::< dns ::Socket > ( i . dns_socket ) ;
socket . cancel_query ( query ) ;
s . waker . wake ( ) ;
2023-02-10 18:44:51 +01:00
i . dns_waker . wake ( ) ;
2023-02-10 17:43:23 +01:00
} )
} ) ;
let res = poll_fn ( | cx | {
self . with_mut ( | s , i | {
2023-02-10 18:30:17 +01:00
let socket = s . sockets . get_mut ::< dns ::Socket > ( i . dns_socket ) ;
match socket . get_query_result ( query ) {
2023-02-10 18:44:51 +01:00
Ok ( addrs ) = > {
i . dns_waker . wake ( ) ;
Poll ::Ready ( Ok ( addrs ) )
}
2023-02-10 18:30:17 +01:00
Err ( dns ::GetQueryResultError ::Pending ) = > {
socket . register_query_waker ( query , cx . waker ( ) ) ;
Poll ::Pending
2023-02-10 17:43:23 +01:00
}
2023-02-10 18:44:51 +01:00
Err ( e ) = > {
i . dns_waker . wake ( ) ;
Poll ::Ready ( Err ( e . into ( ) ) )
}
2023-02-10 17:43:23 +01:00
}
} )
} )
. await ;
drop . defuse ( ) ;
res
}
2022-12-07 16:02:28 +01:00
}
2023-03-06 17:50:57 +01:00
#[ cfg(feature = " igmp " ) ]
impl < D : Driver + smoltcp ::phy ::Device + 'static > Stack < D > {
2023-05-15 00:39:57 +02:00
/// Join a multicast group.
pub fn join_multicast_group < T > ( & self , addr : T ) -> Result < bool , MulticastError >
2023-03-07 23:40:20 +01:00
where
T : Into < IpAddress > ,
2023-03-06 17:50:57 +01:00
{
let addr = addr . into ( ) ;
self . with_mut ( | s , i | {
2023-03-07 23:40:20 +01:00
s . iface
. join_multicast_group ( & mut i . device , addr , instant_to_smoltcp ( Instant ::now ( ) ) )
2023-03-06 17:50:57 +01:00
} )
}
2023-05-15 00:39:57 +02:00
/// Leave a multicast group.
pub fn leave_multicast_group < T > ( & self , addr : T ) -> Result < bool , MulticastError >
2023-03-07 23:40:20 +01:00
where
T : Into < IpAddress > ,
2023-03-06 17:50:57 +01:00
{
let addr = addr . into ( ) ;
self . with_mut ( | s , i | {
2023-03-07 23:40:20 +01:00
s . iface
. leave_multicast_group ( & mut i . device , addr , instant_to_smoltcp ( Instant ::now ( ) ) )
2023-03-06 17:50:57 +01:00
} )
}
2023-05-15 00:39:57 +02:00
/// Get whether the network stack has joined the given multicast group.
2023-03-08 12:37:00 +01:00
pub fn has_multicast_group < T : Into < IpAddress > > ( & self , addr : T ) -> bool {
2023-03-06 17:50:57 +01:00
self . socket . borrow ( ) . iface . has_multicast_group ( addr )
}
}
2022-12-07 16:02:28 +01:00
impl SocketStack {
2023-01-18 10:10:33 +01:00
#[ allow(clippy::absurd_extreme_comparisons, dead_code) ]
2022-12-07 16:02:28 +01:00
pub fn get_local_port ( & mut self ) -> u16 {
let res = self . next_local_port ;
self . next_local_port = if res > = LOCAL_PORT_MAX { LOCAL_PORT_MIN } else { res + 1 } ;
res
}
}
2022-12-26 03:33:49 +01:00
impl < D : Driver + 'static > Inner < D > {
2023-06-05 14:57:17 +02:00
fn apply_config ( & mut self , s : & mut SocketStack , config : StaticConfigV4 ) {
2022-12-07 16:02:28 +01:00
#[ cfg(feature = " medium-ethernet " ) ]
let medium = self . device . capabilities ( ) . medium ;
debug! ( " Acquired IP configuration: " ) ;
debug! ( " IP address: {} " , config . address ) ;
2023-01-19 14:41:39 +01:00
s . iface . update_ip_addrs ( | addrs | {
if addrs . is_empty ( ) {
addrs . push ( IpCidr ::Ipv4 ( config . address ) ) . unwrap ( ) ;
} else {
addrs [ 0 ] = IpCidr ::Ipv4 ( config . address ) ;
}
} ) ;
2022-12-07 16:02:28 +01:00
#[ cfg(feature = " medium-ethernet " ) ]
if medium = = Medium ::Ethernet {
if let Some ( gateway ) = config . gateway {
debug! ( " Default gateway: {} " , gateway ) ;
s . iface . routes_mut ( ) . add_default_ipv4_route ( gateway ) . unwrap ( ) ;
} else {
debug! ( " Default gateway: None " ) ;
s . iface . routes_mut ( ) . remove_default_ipv4_route ( ) ;
}
}
for ( i , s ) in config . dns_servers . iter ( ) . enumerate ( ) {
debug! ( " DNS server {}: {} " , i , s ) ;
}
2023-02-10 17:43:23 +01:00
#[ cfg(feature = " dns " ) ]
2023-02-10 19:00:00 +01:00
{
let socket = s . sockets . get_mut ::< smoltcp ::socket ::dns ::Socket > ( self . dns_socket ) ;
let servers : Vec < IpAddress , 3 > = config . dns_servers . iter ( ) . map ( | c | IpAddress ::Ipv4 ( * c ) ) . collect ( ) ;
socket . update_servers ( & servers [ .. ] ) ;
}
2023-02-10 17:43:23 +01:00
2022-12-07 16:02:28 +01:00
self . config = Some ( config )
}
2023-04-18 22:11:15 +02:00
#[ cfg(feature = " dhcpv4 " ) ]
2023-01-18 10:10:33 +01:00
fn apply_dhcp_config ( & self , socket : & mut smoltcp ::socket ::dhcpv4 ::Socket , config : DhcpConfig ) {
socket . set_ignore_naks ( config . ignore_naks ) ;
2023-05-15 00:38:58 +02:00
socket . set_max_lease_duration ( config . max_lease_duration . map ( crate ::time ::duration_to_smoltcp ) ) ;
2023-01-18 10:10:33 +01:00
socket . set_ports ( config . server_port , config . client_port ) ;
socket . set_retry_config ( config . retry_config ) ;
}
2022-12-07 16:02:28 +01:00
#[ allow(unused) ] // used only with dhcp
fn unapply_config ( & mut self , s : & mut SocketStack ) {
#[ cfg(feature = " medium-ethernet " ) ]
let medium = self . device . capabilities ( ) . medium ;
debug! ( " Lost IP configuration " ) ;
2023-01-19 14:41:39 +01:00
s . iface . update_ip_addrs ( | ip_addrs | ip_addrs . clear ( ) ) ;
2022-12-07 16:02:28 +01:00
#[ cfg(feature = " medium-ethernet " ) ]
if medium = = Medium ::Ethernet {
s . iface . routes_mut ( ) . remove_default_ipv4_route ( ) ;
}
self . config = None
}
fn poll ( & mut self , cx : & mut Context < '_ > , s : & mut SocketStack ) {
s . waker . register ( cx . waker ( ) ) ;
2022-12-27 01:04:55 +01:00
#[ cfg(feature = " medium-ethernet " ) ]
if self . device . capabilities ( ) . medium = = Medium ::Ethernet {
s . iface . set_hardware_addr ( HardwareAddress ::Ethernet ( EthernetAddress (
self . device . ethernet_address ( ) ,
) ) ) ;
}
2022-12-07 16:02:28 +01:00
let timestamp = instant_to_smoltcp ( Instant ::now ( ) ) ;
2022-12-26 03:33:49 +01:00
let mut smoldev = DriverAdapter {
2022-12-07 16:02:28 +01:00
cx : Some ( cx ) ,
inner : & mut self . device ,
} ;
2023-01-19 13:30:51 +01:00
s . iface . poll ( timestamp , & mut smoldev , & mut s . sockets ) ;
2022-12-07 16:02:28 +01:00
// Update link up
let old_link_up = self . link_up ;
self . link_up = self . device . link_state ( cx ) = = LinkState ::Up ;
// Print when changed
if old_link_up ! = self . link_up {
info! ( " link_up = {:?} " , self . link_up ) ;
}
#[ cfg(feature = " dhcpv4 " ) ]
if let Some ( dhcp_handle ) = self . dhcp_socket {
let socket = s . sockets . get_mut ::< dhcpv4 ::Socket > ( dhcp_handle ) ;
if self . link_up {
match socket . poll ( ) {
None = > { }
Some ( dhcpv4 ::Event ::Deconfigured ) = > self . unapply_config ( s ) ,
Some ( dhcpv4 ::Event ::Configured ( config ) ) = > {
2023-06-05 14:57:17 +02:00
let config = StaticConfigV4 {
2022-12-07 16:02:28 +01:00
address : config . address ,
gateway : config . router ,
dns_servers : config . dns_servers ,
} ;
self . apply_config ( s , config )
}
}
} else if old_link_up {
socket . reset ( ) ;
self . unapply_config ( s ) ;
}
}
//if old_link_up || self.link_up {
// self.poll_configurator(timestamp)
//}
2023-02-10 17:43:23 +01:00
//
2022-12-07 16:02:28 +01:00
if let Some ( poll_at ) = s . iface . poll_at ( timestamp , & mut s . sockets ) {
let t = Timer ::at ( instant_from_smoltcp ( poll_at ) ) ;
pin_mut! ( t ) ;
if t . poll ( cx ) . is_ready ( ) {
cx . waker ( ) . wake_by_ref ( ) ;
}
}
}
}