mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-09-27 12:20:56 +00:00

* 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
111 lines
3.7 KiB
Rust
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));
|
|
}
|
|
}
|