Skip to content

Commit

Permalink
Add basic AP support (esp-rs#134)
Browse files Browse the repository at this point in the history
* Add basic AP support

* Remove IS_AP global static
  • Loading branch information
bjoernQ committed May 23, 2024
1 parent dcc9223 commit 3c2f1b8
Show file tree
Hide file tree
Showing 10 changed files with 672 additions and 31 deletions.
194 changes: 194 additions & 0 deletions esp-wifi/examples/access_point.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
#![no_std]
#![no_main]
#![feature(c_variadic)]
#![feature(const_mut_refs)]

#[cfg(feature = "esp32")]
use esp32_hal as hal;
#[cfg(feature = "esp32c2")]
use esp32c2_hal as hal;
#[cfg(feature = "esp32c3")]
use esp32c3_hal as hal;
#[cfg(feature = "esp32s2")]
use esp32s2_hal as hal;
#[cfg(feature = "esp32s3")]
use esp32s3_hal as hal;

use embedded_io::blocking::*;
use embedded_svc::ipv4::Interface;
use embedded_svc::wifi::{AccessPointConfiguration, Configuration, Wifi};

use esp_backtrace as _;
use esp_println::logger::init_logger;
use esp_println::{print, println};
use esp_wifi::current_millis;
use esp_wifi::initialize;
use esp_wifi::wifi::utils::create_network_interface;
use esp_wifi::wifi::WifiMode;
use esp_wifi::wifi_interface::WifiStack;
use hal::clock::{ClockControl, CpuClock};
use hal::Rng;
use hal::{peripherals::Peripherals, prelude::*, Rtc};

#[cfg(any(feature = "esp32c3", feature = "esp32c2"))]
use hal::system::SystemExt;

#[cfg(any(feature = "esp32c3", feature = "esp32c2"))]
use riscv_rt::entry;
use smoltcp::iface::SocketStorage;
#[cfg(any(feature = "esp32", feature = "esp32s3", feature = "esp32s2"))]
use xtensa_lx_rt::entry;

#[entry]
fn main() -> ! {
init_logger(log::LevelFilter::Info);
esp_wifi::init_heap();

let peripherals = Peripherals::take();

#[cfg(not(feature = "esp32"))]
let system = peripherals.SYSTEM.split();
#[cfg(feature = "esp32")]
let system = peripherals.DPORT.split();

#[cfg(feature = "esp32c3")]
let clocks = ClockControl::configure(system.clock_control, CpuClock::Clock160MHz).freeze();
#[cfg(feature = "esp32c2")]
let clocks = ClockControl::configure(system.clock_control, CpuClock::Clock120MHz).freeze();
#[cfg(any(feature = "esp32", feature = "esp32s3", feature = "esp32s2"))]
let clocks = ClockControl::configure(system.clock_control, CpuClock::Clock240MHz).freeze();

let mut rtc = Rtc::new(peripherals.RTC_CNTL);

// Disable watchdog timers
#[cfg(not(any(feature = "esp32", feature = "esp32s2")))]
rtc.swd.disable();

rtc.rwdt.disable();

let mut socket_set_entries: [SocketStorage; 3] = Default::default();
let (iface, device, mut controller, sockets) =
create_network_interface(WifiMode::Ap, &mut socket_set_entries);
let mut wifi_stack = WifiStack::new(iface, device, sockets, current_millis);

#[cfg(any(feature = "esp32c3", feature = "esp32c2"))]
{
use hal::systimer::SystemTimer;
let syst = SystemTimer::new(peripherals.SYSTIMER);
initialize(syst.alarm0, Rng::new(peripherals.RNG), &clocks).unwrap();
}
#[cfg(any(feature = "esp32", feature = "esp32s3", feature = "esp32s2"))]
{
use hal::timer::TimerGroup;
let timg1 = TimerGroup::new(peripherals.TIMG1, &clocks);
initialize(timg1.timer0, Rng::new(peripherals.RNG), &clocks).unwrap();
}

let client_config = Configuration::AccessPoint(AccessPointConfiguration {
ssid: "esp-wifi".into(),
..Default::default()
});
let res = controller.set_configuration(&client_config);
println!("wifi_set_configuration returned {:?}", res);

controller.start().unwrap();
println!("is wifi started: {:?}", controller.is_started());

println!("{:?}", controller.get_capabilities());

wifi_stack
.set_iface_configuration(&embedded_svc::ipv4::Configuration::Client(
embedded_svc::ipv4::ClientConfiguration::Fixed(embedded_svc::ipv4::ClientSettings {
ip: embedded_svc::ipv4::Ipv4Addr::from(parse_ip("192.168.2.1")),
subnet: embedded_svc::ipv4::Subnet {
gateway: embedded_svc::ipv4::Ipv4Addr::from(parse_ip("192.168.2.1")),
mask: embedded_svc::ipv4::Mask(24),
},
dns: None,
secondary_dns: None,
}),
))
.unwrap();

println!("Start busy loop on main. Connect to the AP `esp-wifi` and point your browser to http://192.168.2.1:8080/");
println!("Use a static IP in the range 192.168.2.2 .. 192.168.2.255, use gateway 192.168.2.1");

let mut rx_buffer = [0u8; 1536];
let mut tx_buffer = [0u8; 1536];
let mut socket = wifi_stack.get_socket(&mut rx_buffer, &mut tx_buffer);

socket.listen(8080).unwrap();

loop {
socket.work();

if !socket.is_open() {
socket.listen(8080).unwrap();
}

if socket.is_connected() {
println!("Connected");

let mut time_out = false;
let wait_end = current_millis() + 20 * 1000;
let mut buffer = [0u8; 1024];
let mut pos = 0;
loop {
if let Ok(len) = socket.read(&mut buffer[pos..]) {
let to_print =
unsafe { core::str::from_utf8_unchecked(&buffer[..(pos + len)]) };

if to_print.contains("\r\n\r\n") {
print!("{}", to_print);
println!();
break;
}

pos += len;
} else {
break;
}

if current_millis() > wait_end {
println!("Timeout");
time_out = true;
break;
}
}

if !time_out {
socket
.write_all(
b"HTTP/1.0 200 OK\r\n\r\n\
<html>\
<body>\
<h1>Hello Rust! Hello esp-wifi!</h1>\
</body>\
</html>\r\n\
",
)
.unwrap();

socket.flush().unwrap();
}

socket.close();

println!("Done\n");
println!();
}

let wait_end = current_millis() + 5 * 1000;
while current_millis() < wait_end {
socket.work();
}
}
}

fn parse_ip(ip: &str) -> [u8; 4] {
let mut result = [0u8; 4];
for (idx, octet) in ip.split(".").into_iter().enumerate() {
result[idx] = u8::from_str_radix(octet, 10).unwrap();
}
result
}
6 changes: 4 additions & 2 deletions esp-wifi/examples/coex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ use bleps::{
Ble, HciConnector,
};

use esp_wifi::{ble::controller::BleConnector, current_millis, wifi_interface::WifiStack};
use esp_wifi::{
ble::controller::BleConnector, current_millis, wifi::WifiMode, wifi_interface::WifiStack,
};

use embedded_io::blocking::*;
use embedded_svc::ipv4::Interface;
Expand Down Expand Up @@ -73,7 +75,7 @@ fn main() -> ! {

let mut socket_set_entries: [SocketStorage; 3] = Default::default();
let (iface, device, mut controller, sockets) =
create_network_interface(&mut socket_set_entries);
create_network_interface(WifiMode::Sta, &mut socket_set_entries);
let wifi_stack = WifiStack::new(iface, device, sockets, current_millis);

#[cfg(feature = "esp32c3")]
Expand Down
4 changes: 2 additions & 2 deletions esp-wifi/examples/dhcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use esp_backtrace as _;
use esp_println::logger::init_logger;
use esp_println::{print, println};
use esp_wifi::wifi::utils::create_network_interface;
use esp_wifi::wifi::WifiError;
use esp_wifi::wifi::{WifiError, WifiMode};
use esp_wifi::wifi_interface::WifiStack;
use esp_wifi::{current_millis, initialize};
use hal::clock::{ClockControl, CpuClock};
Expand Down Expand Up @@ -71,7 +71,7 @@ fn main() -> ! {

let mut socket_set_entries: [SocketStorage; 3] = Default::default();
let (iface, device, mut controller, sockets) =
create_network_interface(&mut socket_set_entries);
create_network_interface(WifiMode::Sta, &mut socket_set_entries);
let wifi_stack = WifiStack::new(iface, device, sockets, current_millis);

#[cfg(any(feature = "esp32c3", feature = "esp32c2"))]
Expand Down
Loading

0 comments on commit 3c2f1b8

Please sign in to comment.