Dániel Buga 646495eb16
Runtime wifi config options (#4121)
* Turn country code and default power mode into runtime configs

* Move G_CONFIG setup to wifi::new

* Turn most configs into runtime options

* Set core ID to current one

* Mark most options unstable
2025-09-17 08:13:18 +00:00

111 lines
3.7 KiB
Rust

//! WiFi frame injection example
//!
//! Periodically transmits a beacon frame.
#![no_std]
#![no_main]
use core::marker::PhantomData;
use esp_alloc as _;
use esp_backtrace as _;
use esp_hal::{clock::CpuClock, delay::Delay, main, time::Duration, timer::timg::TimerGroup};
use esp_println::println;
use esp_radio::wifi;
use ieee80211::{
common::{CapabilitiesInformation, FCFFlags},
element_chain,
elements::{DSSSParameterSetElement, RawIEEE80211Element, SSIDElement},
mgmt_frame::{BeaconFrame, body::BeaconBody, header::ManagementFrameHeader},
scroll::Pwrite,
supported_rates,
};
esp_bootloader_esp_idf::esp_app_desc!();
const SSID: &str = "esp-radio 802.11 injection";
/// This is an arbitrary MAC address, used for the fake beacon frames.
const MAC_ADDRESS: [u8; 6] = [0x00, 0x80, 0x41, 0x13, 0x37, 0x42];
#[main]
fn main() -> ! {
esp_println::logger::init_logger_from_env();
let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
let peripherals = esp_hal::init(config);
esp_alloc::heap_allocator!(size: 72 * 1024);
let delay = Delay::new();
let timg0 = TimerGroup::new(peripherals.TIMG0);
esp_preempt::start(timg0.timer0);
let esp_radio_ctrl = esp_radio::init().unwrap();
// We must initialize some kind of interface and start it.
let (mut controller, interfaces) =
esp_radio::wifi::new(&esp_radio_ctrl, peripherals.WIFI, Default::default()).unwrap();
controller.set_mode(wifi::WifiMode::Sta).unwrap();
controller.start().unwrap();
let mut sniffer = interfaces.sniffer;
// Create a buffer, which can hold the enitre serialized beacon frame.
let mut beacon = [0u8; 300];
let length = beacon
.pwrite(
BeaconFrame {
header: ManagementFrameHeader {
fcf_flags: FCFFlags::new(),
duration: 0,
receiver_address: [0xff; 6].into(),
transmitter_address: MAC_ADDRESS.into(),
bssid: MAC_ADDRESS.into(),
..Default::default()
},
body: BeaconBody {
timestamp: 0,
// We transmit a beacon every 100 ms/TUs
beacon_interval: 100,
capabilities_info: CapabilitiesInformation::new().with_is_ess(true),
elements: element_chain! {
SSIDElement::new(SSID).unwrap(),
// These are known good values.
supported_rates![
1 B,
2 B,
5.5 B,
11 B,
6,
9,
12,
18
],
DSSSParameterSetElement {
current_channel: 1,
},
// This contains the Traffic Indication Map(TIM), for which `ieee80211-rs` currently lacks support.
RawIEEE80211Element {
tlv_type: 5,
slice: [0x01, 0x02, 0x00, 0x00].as_slice(),
_phantom: PhantomData
}
},
_phantom: PhantomData,
},
},
0,
)
.unwrap();
// Only use the actually written bytes.
let beacon = &beacon[..length];
println!("Scan for WiFi networks and find `esp-radio 802.11 injection`");
loop {
sniffer.send_raw_frame(true, beacon, false).unwrap();
delay.delay(Duration::from_millis(100));
}
}