Skip to content

Commit

Permalink
A way to update iface-config (esp-rs#177)
Browse files Browse the repository at this point in the history
  • Loading branch information
bjoernQ committed May 23, 2024
1 parent 28a0aaa commit b7e2a8a
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 41 deletions.
49 changes: 30 additions & 19 deletions esp-wifi/src/wifi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ pub enum WifiError {
InternalError(InternalWifiError),
WrongClockConfig,
Disconnected,
UnknownWifiMode,
}
#[repr(i32)]
#[derive(Debug, FromPrimitive, EnumSetType)]
Expand Down Expand Up @@ -694,14 +695,14 @@ pub fn new_with_config<'d>(
config: embedded_svc::wifi::Configuration,
) -> (WifiDevice<'d>, WifiController<'d>) {
esp_hal_common::into_ref!(device);
let mode = match config {
match config {
embedded_svc::wifi::Configuration::None => panic!(),
embedded_svc::wifi::Configuration::Client(_) => WifiMode::Sta,
embedded_svc::wifi::Configuration::AccessPoint(_) => WifiMode::Ap,
embedded_svc::wifi::Configuration::Client(_) => (),
embedded_svc::wifi::Configuration::AccessPoint(_) => (),
embedded_svc::wifi::Configuration::Mixed(_, _) => panic!(),
};
(
WifiDevice::new(unsafe { device.clone_unchecked() }, mode),
WifiDevice::new(unsafe { device.clone_unchecked() }),
WifiController::new_with_config(device, config),
)
}
Expand All @@ -728,18 +729,23 @@ pub fn new<'d>(
/// A wifi device implementing smoltcp's Device trait.
pub struct WifiDevice<'d> {
_device: PeripheralRef<'d, esp_hal_common::radio::Wifi>,

// only used by embassy-net
#[allow(unused)]
mode: WifiMode,
}

impl<'d> WifiDevice<'d> {
pub(crate) fn new(
_device: PeripheralRef<'d, esp_hal_common::radio::Wifi>,
mode: WifiMode,
) -> WifiDevice {
Self { _device, mode }
pub(crate) fn new(_device: PeripheralRef<'d, esp_hal_common::radio::Wifi>) -> WifiDevice {
Self { _device }
}

pub(crate) fn get_wifi_mode(&self) -> Result<WifiMode, WifiError> {
let mut mode = wifi_mode_t_WIFI_MODE_NULL;
esp_wifi_result!(unsafe { esp_wifi_get_mode(&mut mode) })?;

#[allow(non_upper_case_globals)]
match mode {
wifi_mode_t_WIFI_MODE_STA => Ok(WifiMode::Sta),
wifi_mode_t_WIFI_MODE_AP => Ok(WifiMode::Ap),
_ => Err(WifiError::UnknownWifiMode),
}
}
}

Expand Down Expand Up @@ -1331,15 +1337,15 @@ pub(crate) mod embassy {
fn link_state(&mut self, cx: &mut core::task::Context) -> embassy_net_driver::LinkState {
LINK_STATE.register(cx.waker());

match self.mode {
WifiMode::Sta => {
match self.get_wifi_mode() {
Ok(WifiMode::Sta) => {
if matches!(get_wifi_state(), WifiState::StaConnected) {
embassy_net_driver::LinkState::Up
} else {
embassy_net_driver::LinkState::Down
}
}
WifiMode::Ap => {
Ok(WifiMode::Ap) => {
if matches!(
get_wifi_state(),
WifiState::ApStart
Expand All @@ -1351,6 +1357,10 @@ pub(crate) mod embassy {
embassy_net_driver::LinkState::Down
}
}
_ => {
log::warn!("Unknown wifi mode in link_state");
embassy_net_driver::LinkState::Down
}
}
}

Expand All @@ -1363,9 +1373,10 @@ pub(crate) mod embassy {

fn ethernet_address(&self) -> [u8; 6] {
let mut mac = [0; 6];
match self.mode.is_ap() {
true => get_ap_mac(&mut mac),
false => get_sta_mac(&mut mac),
match self.get_wifi_mode() {
Ok(WifiMode::Ap) => get_ap_mac(&mut mac),
Ok(WifiMode::Sta) => get_sta_mac(&mut mac),
_ => get_sta_mac(&mut mac),
}
mac
}
Expand Down
85 changes: 63 additions & 22 deletions esp-wifi/src/wifi_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use smoltcp::time::Instant;
use smoltcp::wire::{IpAddress, IpCidr, IpEndpoint, Ipv4Address};

use crate::current_millis;
use crate::wifi::WifiDevice;
use crate::wifi::{get_ap_mac, get_sta_mac, WifiDevice, WifiMode};

use core::borrow::BorrowMut;

Expand All @@ -23,7 +23,7 @@ pub struct WifiStack<'a> {
local_port: RefCell<u16>,
pub(crate) network_config: RefCell<ipv4::Configuration>,
pub(crate) ip_info: RefCell<Option<ipv4::IpInfo>>,
pub(crate) dhcp_socket_handle: Option<SocketHandle>,
pub(crate) dhcp_socket_handle: RefCell<Option<SocketHandle>>,
}

impl<'a> WifiStack<'a> {
Expand Down Expand Up @@ -52,17 +52,73 @@ impl<'a> WifiStack<'a> {
}),
)),
ip_info: RefCell::new(None),
dhcp_socket_handle,
dhcp_socket_handle: RefCell::new(dhcp_socket_handle),
sockets: RefCell::new(sockets),
current_millis_fn,
local_port: RefCell::new(41000),
}
}

pub fn update_iface_configuration(
&self,
conf: &ipv4::Configuration,
) -> Result<(), WifiStackError> {
let mut mac = [0u8; 6];
match self.device.borrow().get_wifi_mode() {
Ok(WifiMode::Sta) => get_sta_mac(&mut mac),
Ok(WifiMode::Ap) => get_ap_mac(&mut mac),
_ => (),
}
let hw_address = smoltcp::wire::HardwareAddress::Ethernet(
smoltcp::wire::EthernetAddress::from_bytes(&mac),
);
self.network_interface
.borrow_mut()
.set_hardware_addr(hw_address);
log::info!("Set hardware address: {:02x?}", hw_address);

self.reset(); // reset IP address

let mut dhcp_socket_handle_ref = self.dhcp_socket_handle.borrow_mut();
let mut sockets_ref = self.sockets.borrow_mut();

if let Some(dhcp_handle) = *dhcp_socket_handle_ref {
// remove the DHCP client if we use a static IP
if matches!(
conf,
ipv4::Configuration::Client(ipv4::ClientConfiguration::Fixed(_))
) {
sockets_ref.remove(dhcp_handle);
*dhcp_socket_handle_ref = None;
}
}

// re-add the DHCP client if we use DHCP and it has been removed before
if matches!(
conf,
ipv4::Configuration::Client(ipv4::ClientConfiguration::DHCP(_))
) && dhcp_socket_handle_ref.is_none()
{
let dhcp_socket = Dhcpv4Socket::new();
let dhcp_socket_handle = sockets_ref.add(dhcp_socket);
*dhcp_socket_handle_ref = Some(dhcp_socket_handle);
}

if let Some(dhcp_handle) = *dhcp_socket_handle_ref {
let dhcp_socket = sockets_ref.get_mut::<Dhcpv4Socket>(dhcp_handle);
log::info!("Reset DHCP client");
dhcp_socket.reset();
}

*self.network_config.borrow_mut() = conf.clone();
Ok(())
}

pub fn reset(&self) {
log::debug!("Reset TCP stack");

if let Some(dhcp_handle) = self.dhcp_socket_handle {
let dhcp_socket_handle_ref = self.dhcp_socket_handle.borrow_mut();
if let Some(dhcp_handle) = *dhcp_socket_handle_ref {
self.with_mut(|_, _, sockets| {
let dhcp_socket = sockets.get_mut::<Dhcpv4Socket>(dhcp_handle);
log::debug!("Reset DHCP client");
Expand All @@ -84,7 +140,8 @@ impl<'a> WifiStack<'a> {
interface: &mut Interface,
sockets: &mut SocketSet<'a>,
) -> Result<(), WifiStackError> {
if let Some(dhcp_handle) = self.dhcp_socket_handle {
let dhcp_socket_handle_ref = self.dhcp_socket_handle.borrow_mut();
if let Some(dhcp_handle) = *dhcp_socket_handle_ref {
let dhcp_socket = sockets.get_mut::<Dhcpv4Socket>(dhcp_handle);
let event = dhcp_socket.poll();
if let Some(event) = event {
Expand Down Expand Up @@ -258,23 +315,7 @@ impl<'a> ipv4::Interface for WifiStack<'a> {
}

fn set_iface_configuration(&mut self, conf: &ipv4::Configuration) -> Result<(), Self::Error> {
if let Some(dhcp_handle) = self.dhcp_socket_handle {
let dhcp_socket = self.sockets.get_mut().get_mut::<Dhcpv4Socket>(dhcp_handle);
log::info!("Reset DHCP client");
dhcp_socket.reset();

// remove the DHCP client if we use a static IP
if matches!(
conf,
ipv4::Configuration::Client(ipv4::ClientConfiguration::Fixed(_))
) {
self.sockets.get_mut().remove(dhcp_handle);
self.dhcp_socket_handle = None;
}
}

*self.network_config.borrow_mut() = conf.clone();
Ok(())
self.update_iface_configuration(conf)
}

fn is_iface_up(&self) -> bool {
Expand Down

0 comments on commit b7e2a8a

Please sign in to comment.