aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/consts.rs18
-rw-r--r--src/control.rs67
-rw-r--r--src/structs.rs9
3 files changed, 94 insertions, 0 deletions
diff --git a/src/consts.rs b/src/consts.rs
index 18502bd1a..1f6551589 100644
--- a/src/consts.rs
+++ b/src/consts.rs
@@ -93,8 +93,11 @@ pub(crate) const IRQ_F2_INTR: u16 = 0x4000;
93pub(crate) const IRQ_F3_INTR: u16 = 0x8000; 93pub(crate) const IRQ_F3_INTR: u16 = 0x8000;
94 94
95pub(crate) const IOCTL_CMD_UP: u32 = 2; 95pub(crate) const IOCTL_CMD_UP: u32 = 2;
96pub(crate) const IOCTL_CMD_DOWN: u32 = 3;
96pub(crate) const IOCTL_CMD_SET_SSID: u32 = 26; 97pub(crate) const IOCTL_CMD_SET_SSID: u32 = 26;
98pub(crate) const IOCTL_CMD_SET_CHANNEL: u32 = 30;
97pub(crate) const IOCTL_CMD_ANTDIV: u32 = 64; 99pub(crate) const IOCTL_CMD_ANTDIV: u32 = 64;
100pub(crate) const IOCTL_CMD_SET_AP: u32 = 118;
98pub(crate) const IOCTL_CMD_SET_VAR: u32 = 263; 101pub(crate) const IOCTL_CMD_SET_VAR: u32 = 263;
99pub(crate) const IOCTL_CMD_GET_VAR: u32 = 262; 102pub(crate) const IOCTL_CMD_GET_VAR: u32 = 262;
100pub(crate) const IOCTL_CMD_SET_PASSPHRASE: u32 = 268; 103pub(crate) const IOCTL_CMD_SET_PASSPHRASE: u32 = 268;
@@ -109,6 +112,21 @@ pub(crate) const READ: bool = false;
109pub(crate) const INC_ADDR: bool = true; 112pub(crate) const INC_ADDR: bool = true;
110pub(crate) const FIXED_ADDR: bool = false; 113pub(crate) const FIXED_ADDR: bool = false;
111 114
115pub(crate) const AES_ENABLED: u32 = 0x0004;
116pub(crate) const WPA2_SECURITY: u32 = 0x00400000;
117
118pub(crate) const MIN_PSK_LEN: usize = 8;
119pub(crate) const MAX_PSK_LEN: usize = 64;
120
121// Security type (authentication and encryption types are combined using bit mask)
122#[allow(non_camel_case_types)]
123#[derive(Copy, Clone, PartialEq)]
124#[repr(u32)]
125pub(crate) enum Security {
126 OPEN = 0,
127 WPA2_AES_PSK = WPA2_SECURITY | AES_ENABLED,
128}
129
112#[allow(non_camel_case_types)] 130#[allow(non_camel_case_types)]
113#[derive(Copy, Clone)] 131#[derive(Copy, Clone)]
114#[repr(u8)] 132#[repr(u8)]
diff --git a/src/control.rs b/src/control.rs
index 934bade23..e1ad06e6b 100644
--- a/src/control.rs
+++ b/src/control.rs
@@ -226,6 +226,73 @@ impl<'a> Control<'a> {
226 .await 226 .await
227 } 227 }
228 228
229 pub async fn start_ap_open(&mut self, ssid: &str, channel: u8) {
230 self.start_ap(ssid, "", Security::OPEN, channel).await;
231 }
232
233 pub async fn start_ap_wpa2(&mut self, ssid: &str, passphrase: &str, channel: u8) {
234 self.start_ap(ssid, passphrase, Security::WPA2_AES_PSK, channel).await;
235 }
236
237 async fn start_ap(&mut self, ssid: &str, passphrase: &str, security: Security, channel: u8) {
238 if security != Security::OPEN
239 && (passphrase.as_bytes().len() < MIN_PSK_LEN || passphrase.as_bytes().len() > MAX_PSK_LEN)
240 {
241 panic!("Passphrase is too short or too long");
242 }
243
244 // Temporarily set wifi down
245 self.ioctl(IoctlType::Set, IOCTL_CMD_DOWN, 0, &mut []).await;
246
247 // Turn off APSTA mode
248 self.set_iovar_u32("apsta", 0).await;
249
250 // Set wifi up again
251 self.ioctl(IoctlType::Set, IOCTL_CMD_UP, 0, &mut []).await;
252
253 // Turn on AP mode
254 self.ioctl_set_u32(IOCTL_CMD_SET_AP, 0, 1).await;
255
256 // Set SSID
257 let mut i = SsidInfoWithIndex {
258 index: 0,
259 ssid_info: SsidInfo {
260 len: ssid.as_bytes().len() as _,
261 ssid: [0; 32],
262 },
263 };
264 i.ssid_info.ssid[..ssid.as_bytes().len()].copy_from_slice(ssid.as_bytes());
265 self.set_iovar("bsscfg:ssid", &i.to_bytes()).await;
266
267 // Set channel number
268 self.ioctl_set_u32(IOCTL_CMD_SET_CHANNEL, 0, channel as u32).await;
269
270 // Set security
271 self.set_iovar_u32x2("bsscfg:wsec", 0, (security as u32) & 0xFF).await;
272
273 if security != Security::OPEN {
274 self.set_iovar_u32x2("bsscfg:wpa_auth", 0, 0x0084).await; // wpa_auth = WPA2_AUTH_PSK | WPA_AUTH_PSK
275
276 Timer::after(Duration::from_millis(100)).await;
277
278 // Set passphrase
279 let mut pfi = PassphraseInfo {
280 len: passphrase.as_bytes().len() as _,
281 flags: 1, // WSEC_PASSPHRASE
282 passphrase: [0; 64],
283 };
284 pfi.passphrase[..passphrase.as_bytes().len()].copy_from_slice(passphrase.as_bytes());
285 self.ioctl(IoctlType::Set, IOCTL_CMD_SET_PASSPHRASE, 0, &mut pfi.to_bytes())
286 .await;
287 }
288
289 // Change mutlicast rate from 1 Mbps to 11 Mbps
290 self.set_iovar_u32("2g_mrate", 11000000 / 500000).await;
291
292 // Start AP
293 self.set_iovar_u32x2("bss", 0, 1).await; // bss = BSS_UP
294 }
295
229 async fn set_iovar_u32x2(&mut self, name: &str, val1: u32, val2: u32) { 296 async fn set_iovar_u32x2(&mut self, name: &str, val1: u32, val2: u32) {
230 let mut buf = [0; 8]; 297 let mut buf = [0; 8];
231 buf[0..4].copy_from_slice(&val1.to_le_bytes()); 298 buf[0..4].copy_from_slice(&val1.to_le_bytes());
diff --git a/src/structs.rs b/src/structs.rs
index d01d5a65c..3b646e1a8 100644
--- a/src/structs.rs
+++ b/src/structs.rs
@@ -392,6 +392,15 @@ impl_bytes!(PassphraseInfo);
392#[derive(Clone, Copy)] 392#[derive(Clone, Copy)]
393#[cfg_attr(feature = "defmt", derive(defmt::Format))] 393#[cfg_attr(feature = "defmt", derive(defmt::Format))]
394#[repr(C)] 394#[repr(C)]
395pub struct SsidInfoWithIndex {
396 pub index: u32,
397 pub ssid_info: SsidInfo,
398}
399impl_bytes!(SsidInfoWithIndex);
400
401#[derive(Clone, Copy)]
402#[cfg_attr(feature = "defmt", derive(defmt::Format))]
403#[repr(C)]
395pub struct EventMask { 404pub struct EventMask {
396 pub iface: u32, 405 pub iface: u32,
397 pub events: [u8; 24], 406 pub events: [u8; 24],