1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
//! Convenience utilities for non-async code

use smoltcp::{
    iface::{Config, Interface},
    wire::{EthernetAddress, HardwareAddress},
};

use super::{WifiApDevice, WifiController, WifiDevice, WifiDeviceMode, WifiError, WifiStaDevice};
use crate::EspWifiController;

// [esp_hal::time::now()] as a smoltcp [`Instant]`
#[cfg(feature = "smoltcp")]
fn timestamp() -> smoltcp::time::Instant {
    smoltcp::time::Instant::from_micros(
        esp_hal::time::now().duration_since_epoch().to_micros() as i64
    )
}

fn setup_iface<MODE: WifiDeviceMode>(device: &mut WifiDevice<'_, MODE>, mode: MODE) -> Interface {
    let mac = mode.mac_address();
    let hw_address = HardwareAddress::Ethernet(EthernetAddress::from_bytes(&mac));

    let config = Config::new(hw_address);
    let iface = Interface::new(config, device, timestamp());
    iface
}

/// Convenient way to create an `smoltcp` ethernet interface
pub fn create_network_interface<'d, MODE: WifiDeviceMode>(
    inited: &'d EspWifiController<'d>,
    device: impl crate::hal::peripheral::Peripheral<P = crate::hal::peripherals::WIFI> + 'd,
    mode: MODE,
) -> Result<(Interface, WifiDevice<'d, MODE>, WifiController<'d>), WifiError> {
    let (mut device, controller) = crate::wifi::new_with_mode(inited, device, mode)?;

    let iface = setup_iface(&mut device, mode);

    Ok((iface, device, controller))
}

pub struct ApStaInterface<'d> {
    pub ap_interface: Interface,
    pub sta_interface: Interface,
    pub ap_device: WifiDevice<'d, WifiApDevice>,
    pub sta_device: WifiDevice<'d, WifiStaDevice>,
    pub controller: WifiController<'d>,
}

pub fn create_ap_sta_network_interface<'d>(
    inited: &'d EspWifiController<'d>,
    device: impl crate::hal::peripheral::Peripheral<P = crate::hal::peripherals::WIFI> + 'd,
) -> Result<ApStaInterface<'d>, WifiError> {
    let (mut ap_device, mut sta_device, controller) = crate::wifi::new_ap_sta(inited, device)?;

    let ap_interface = setup_iface(&mut ap_device, WifiApDevice);
    let sta_interface = setup_iface(&mut sta_device, WifiStaDevice);

    Ok(ApStaInterface {
        ap_interface,
        sta_interface,
        ap_device,
        sta_device,
        controller,
    })
}