diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e78c5a6e9b5..8ed2be14c1d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -89,4 +89,7 @@ jobs: RUSTFLAGS: "${{ matrix.idf-version == 'v5.1.1' && '--cfg espidf_time64 ' || ''}} ${{ '-C default-linker-libraries' }}" WIFI_SSID: "ssid" WIFI_PASS: "pass" + ESP_DEVICE_IP: "192.168.1.250" + GATEWAY_IP: "192.168.1.1" + GATEWAY_NETMASK: "24" run: cargo build --examples --target ${{ matrix.target }} -Zbuild-std=std,panic_abort -Zbuild-std-features=panic_immediate_abort diff --git a/Cargo.toml b/Cargo.toml index 22b82ee31c0..b52b64487e6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -70,6 +70,9 @@ name = "wifi" [[example]] name = "wifi_async" +[[example]] +name = "wifi_static_ip" + [[example]] name = "json_post_handler" diff --git a/examples/wifi_static_ip.rs b/examples/wifi_static_ip.rs new file mode 100644 index 00000000000..833f62e45cc --- /dev/null +++ b/examples/wifi_static_ip.rs @@ -0,0 +1,106 @@ +//! Example of using blocking wifi with a static IP configuration +//! +//! Add your own ssid and password for the access point +//! Add your own gateway IP, netmask, and local device IP for interface configuration + +use embedded_svc::wifi::{AuthMethod, ClientConfiguration, Configuration as WifiConfiguration}; +use std::net::Ipv4Addr; +use std::str::FromStr; + +use esp_idf_svc::hal::prelude::Peripherals; +use esp_idf_svc::ipv4::{ + ClientConfiguration as IpClientConfiguration, ClientSettings as IpClientSettings, + Configuration as IpConfiguration, Mask, Subnet, +}; +use esp_idf_svc::log::EspLogger; +use esp_idf_svc::netif::{EspNetif, NetifConfiguration, NetifStack}; +use esp_idf_svc::wifi::{BlockingWifi, EspWifi, WifiDriver}; +use esp_idf_svc::{eventloop::EspSystemEventLoop, nvs::EspDefaultNvsPartition}; + +use log::info; + +const SSID: &str = env!("WIFI_SSID"); +const PASSWORD: &str = env!("WIFI_PASS"); + +// Expects IPv4 address +const DEVICE_IP: &str = env!("ESP_DEVICE_IP"); +// Expects IPv4 address +const GATEWAY_IP: &str = env!("GATEWAY_IP"); +// Expects a number between 0 and 32, defaults to 24 +const GATEWAY_NETMASK: Option<&str> = option_env!("GATEWAY_NETMASK"); + +fn main() -> anyhow::Result<()> { + esp_idf_svc::sys::link_patches(); + EspLogger::initialize_default(); + + let peripherals = Peripherals::take()?; + let sys_loop = EspSystemEventLoop::take()?; + let nvs = EspDefaultNvsPartition::take()?; + + let wifi = WifiDriver::new(peripherals.modem, sys_loop.clone(), Some(nvs))?; + let wifi = configure_wifi(wifi)?; + + let mut wifi = BlockingWifi::wrap(wifi, sys_loop)?; + connect_wifi(&mut wifi)?; + + let ip_info = wifi.wifi().sta_netif().get_ip_info()?; + + info!("Wifi Interface info: {:?}", ip_info); + + info!("Shutting down in 5s..."); + + std::thread::sleep(core::time::Duration::from_secs(5)); + + Ok(()) +} + +fn configure_wifi(wifi: WifiDriver) -> anyhow::Result { + let netmask = GATEWAY_NETMASK.unwrap_or("24"); + let netmask = u8::from_str(netmask)?; + let gateway_addr = Ipv4Addr::from_str(GATEWAY_IP)?; + let static_ip = Ipv4Addr::from_str(DEVICE_IP)?; + + let mut wifi = EspWifi::wrap_all( + wifi, + EspNetif::new_with_conf(&NetifConfiguration { + ip_configuration: IpConfiguration::Client(IpClientConfiguration::Fixed( + IpClientSettings { + ip: static_ip, + subnet: Subnet { + gateway: gateway_addr, + mask: Mask(netmask), + }, + // Can also be set to Ipv4Addrs if you need DNS + dns: None, + secondary_dns: None, + }, + )), + ..NetifConfiguration::wifi_default_client() + })?, + EspNetif::new(NetifStack::Ap)?, + )?; + + let wifi_configuration = WifiConfiguration::Client(ClientConfiguration { + ssid: SSID.into(), + bssid: None, + auth_method: AuthMethod::WPA2Personal, + password: PASSWORD.into(), + channel: None, + }); + wifi.set_configuration(&wifi_configuration)?; + + Ok(wifi) +} + +fn connect_wifi(wifi: &mut BlockingWifi>) -> anyhow::Result<()> { + wifi.start()?; + info!("Wifi started"); + + wifi.connect()?; + info!("Wifi connected"); + + wifi.wait_netif_up()?; + info!("Wifi netif up"); + + Ok(()) +}