From 099ec7443bed2183397005b4e8ebfcd2492e2b4c Mon Sep 17 00:00:00 2001 From: Satoshi Tanaka Date: Mon, 1 May 2023 04:30:21 +0900 Subject: [PATCH 1/2] Add AP mode (unencrypted) --- src/consts.rs | 3 +++ src/control.rs | 37 +++++++++++++++++++++++++++++++++++++ src/structs.rs | 9 +++++++++ 3 files changed, 49 insertions(+) diff --git a/src/consts.rs b/src/consts.rs index 18502bd1..ade3cb2c 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -93,8 +93,11 @@ pub(crate) const IRQ_F2_INTR: u16 = 0x4000; pub(crate) const IRQ_F3_INTR: u16 = 0x8000; pub(crate) const IOCTL_CMD_UP: u32 = 2; +pub(crate) const IOCTL_CMD_DOWN: u32 = 3; pub(crate) const IOCTL_CMD_SET_SSID: u32 = 26; +pub(crate) const IOCTL_CMD_SET_CHANNEL: u32 = 30; pub(crate) const IOCTL_CMD_ANTDIV: u32 = 64; +pub(crate) const IOCTL_CMD_SET_AP: u32 = 118; pub(crate) const IOCTL_CMD_SET_VAR: u32 = 263; pub(crate) const IOCTL_CMD_GET_VAR: u32 = 262; pub(crate) const IOCTL_CMD_SET_PASSPHRASE: u32 = 268; diff --git a/src/control.rs b/src/control.rs index 934bade2..44024649 100644 --- a/src/control.rs +++ b/src/control.rs @@ -226,6 +226,43 @@ impl<'a> Control<'a> { .await } + pub async fn start_ap_open(&mut self, ssid: &str, channel: u8) { + // Temporarily set wifi down + self.ioctl(IoctlType::Set, IOCTL_CMD_DOWN, 0, &mut []).await; + + // Turn off APSTA mode + self.set_iovar_u32("apsta", 0).await; + + // Set wifi up again + self.ioctl(IoctlType::Set, IOCTL_CMD_UP, 0, &mut []).await; + + // Turn on AP mode + self.ioctl_set_u32(IOCTL_CMD_SET_AP, 0, 1).await; + + // Set SSID + let mut i = SsidInfoWithIndex { + index: 0, + ssid_info: SsidInfo { + len: ssid.as_bytes().len() as _, + ssid: [0; 32], + }, + }; + i.ssid_info.ssid[..ssid.as_bytes().len()].copy_from_slice(ssid.as_bytes()); + self.set_iovar("bsscfg:ssid", &i.to_bytes()).await; + + // Set channel number + self.ioctl_set_u32(IOCTL_CMD_SET_CHANNEL, 0, channel as u32).await; + + // Set security + self.set_iovar_u32x2("bsscfg:wsec", 0, 0).await; // wsec = open + + // Change mutlicast rate from 1 Mbps to 11 Mbps + self.set_iovar_u32("2g_mrate", 11000000 / 500000).await; + + // Start AP + self.set_iovar_u32x2("bss", 0, 1).await; // bss = BSS_UP + } + async fn set_iovar_u32x2(&mut self, name: &str, val1: u32, val2: u32) { let mut buf = [0; 8]; buf[0..4].copy_from_slice(&val1.to_le_bytes()); diff --git a/src/structs.rs b/src/structs.rs index d01d5a65..3b646e1a 100644 --- a/src/structs.rs +++ b/src/structs.rs @@ -389,6 +389,15 @@ pub struct PassphraseInfo { } impl_bytes!(PassphraseInfo); +#[derive(Clone, Copy)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +#[repr(C)] +pub struct SsidInfoWithIndex { + pub index: u32, + pub ssid_info: SsidInfo, +} +impl_bytes!(SsidInfoWithIndex); + #[derive(Clone, Copy)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] #[repr(C)] From a186694fddd00beb4c3b45349cd79ca1959b4d17 Mon Sep 17 00:00:00 2001 From: Satoshi Tanaka Date: Mon, 1 May 2023 06:54:26 +0900 Subject: [PATCH 2/2] Implement WPA2 AP mode --- src/consts.rs | 15 +++++++++++++++ src/control.rs | 32 +++++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/consts.rs b/src/consts.rs index ade3cb2c..1f655158 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -112,6 +112,21 @@ pub(crate) const READ: bool = false; pub(crate) const INC_ADDR: bool = true; pub(crate) const FIXED_ADDR: bool = false; +pub(crate) const AES_ENABLED: u32 = 0x0004; +pub(crate) const WPA2_SECURITY: u32 = 0x00400000; + +pub(crate) const MIN_PSK_LEN: usize = 8; +pub(crate) const MAX_PSK_LEN: usize = 64; + +// Security type (authentication and encryption types are combined using bit mask) +#[allow(non_camel_case_types)] +#[derive(Copy, Clone, PartialEq)] +#[repr(u32)] +pub(crate) enum Security { + OPEN = 0, + WPA2_AES_PSK = WPA2_SECURITY | AES_ENABLED, +} + #[allow(non_camel_case_types)] #[derive(Copy, Clone)] #[repr(u8)] diff --git a/src/control.rs b/src/control.rs index 44024649..e1ad06e6 100644 --- a/src/control.rs +++ b/src/control.rs @@ -227,6 +227,20 @@ impl<'a> Control<'a> { } pub async fn start_ap_open(&mut self, ssid: &str, channel: u8) { + self.start_ap(ssid, "", Security::OPEN, channel).await; + } + + pub async fn start_ap_wpa2(&mut self, ssid: &str, passphrase: &str, channel: u8) { + self.start_ap(ssid, passphrase, Security::WPA2_AES_PSK, channel).await; + } + + async fn start_ap(&mut self, ssid: &str, passphrase: &str, security: Security, channel: u8) { + if security != Security::OPEN + && (passphrase.as_bytes().len() < MIN_PSK_LEN || passphrase.as_bytes().len() > MAX_PSK_LEN) + { + panic!("Passphrase is too short or too long"); + } + // Temporarily set wifi down self.ioctl(IoctlType::Set, IOCTL_CMD_DOWN, 0, &mut []).await; @@ -254,7 +268,23 @@ impl<'a> Control<'a> { self.ioctl_set_u32(IOCTL_CMD_SET_CHANNEL, 0, channel as u32).await; // Set security - self.set_iovar_u32x2("bsscfg:wsec", 0, 0).await; // wsec = open + self.set_iovar_u32x2("bsscfg:wsec", 0, (security as u32) & 0xFF).await; + + if security != Security::OPEN { + self.set_iovar_u32x2("bsscfg:wpa_auth", 0, 0x0084).await; // wpa_auth = WPA2_AUTH_PSK | WPA_AUTH_PSK + + Timer::after(Duration::from_millis(100)).await; + + // Set passphrase + let mut pfi = PassphraseInfo { + len: passphrase.as_bytes().len() as _, + flags: 1, // WSEC_PASSPHRASE + passphrase: [0; 64], + }; + pfi.passphrase[..passphrase.as_bytes().len()].copy_from_slice(passphrase.as_bytes()); + self.ioctl(IoctlType::Set, IOCTL_CMD_SET_PASSPHRASE, 0, &mut pfi.to_bytes()) + .await; + } // Change mutlicast rate from 1 Mbps to 11 Mbps self.set_iovar_u32("2g_mrate", 11000000 / 500000).await;