mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-22 06:42:32 +00:00
Merge pull request #3323 from embassy-rs/cyw43-wpa3
cyw43: add support for WPA3 and more extensive security options.
This commit is contained in:
commit
0ef06cc19b
@ -113,17 +113,6 @@ pub(crate) const IRQ_F1_INTR: u16 = 0x2000;
|
|||||||
pub(crate) const IRQ_F2_INTR: u16 = 0x4000;
|
pub(crate) const IRQ_F2_INTR: u16 = 0x4000;
|
||||||
pub(crate) const IRQ_F3_INTR: u16 = 0x8000;
|
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_DISASSOC: u32 = 52;
|
|
||||||
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;
|
|
||||||
|
|
||||||
pub(crate) const CHANNEL_TYPE_CONTROL: u8 = 0;
|
pub(crate) const CHANNEL_TYPE_CONTROL: u8 = 0;
|
||||||
pub(crate) const CHANNEL_TYPE_EVENT: u8 = 1;
|
pub(crate) const CHANNEL_TYPE_EVENT: u8 = 1;
|
||||||
pub(crate) const CHANNEL_TYPE_DATA: u8 = 2;
|
pub(crate) const CHANNEL_TYPE_DATA: u8 = 2;
|
||||||
@ -376,3 +365,306 @@ impl core::fmt::Display for FormatInterrupt {
|
|||||||
core::fmt::Debug::fmt(self, f)
|
core::fmt::Debug::fmt(self, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
|
#[repr(u32)]
|
||||||
|
pub(crate) enum Ioctl {
|
||||||
|
GetMagic = 0,
|
||||||
|
GetVersion = 1,
|
||||||
|
Up = 2,
|
||||||
|
Down = 3,
|
||||||
|
GetLoop = 4,
|
||||||
|
SetLoop = 5,
|
||||||
|
Dump = 6,
|
||||||
|
GetMsglevel = 7,
|
||||||
|
SetMsglevel = 8,
|
||||||
|
GetPromisc = 9,
|
||||||
|
SetPromisc = 10,
|
||||||
|
GetRate = 12,
|
||||||
|
GetInstance = 14,
|
||||||
|
GetInfra = 19,
|
||||||
|
SetInfra = 20,
|
||||||
|
GetAuth = 21,
|
||||||
|
SetAuth = 22,
|
||||||
|
GetBssid = 23,
|
||||||
|
SetBssid = 24,
|
||||||
|
GetSsid = 25,
|
||||||
|
SetSsid = 26,
|
||||||
|
Restart = 27,
|
||||||
|
GetChannel = 29,
|
||||||
|
SetChannel = 30,
|
||||||
|
GetSrl = 31,
|
||||||
|
SetSrl = 32,
|
||||||
|
GetLrl = 33,
|
||||||
|
SetLrl = 34,
|
||||||
|
GetPlcphdr = 35,
|
||||||
|
SetPlcphdr = 36,
|
||||||
|
GetRadio = 37,
|
||||||
|
SetRadio = 38,
|
||||||
|
GetPhytype = 39,
|
||||||
|
DumpRate = 40,
|
||||||
|
SetRateParams = 41,
|
||||||
|
GetKey = 44,
|
||||||
|
SetKey = 45,
|
||||||
|
GetRegulatory = 46,
|
||||||
|
SetRegulatory = 47,
|
||||||
|
GetPassiveScan = 48,
|
||||||
|
SetPassiveScan = 49,
|
||||||
|
Scan = 50,
|
||||||
|
ScanResults = 51,
|
||||||
|
Disassoc = 52,
|
||||||
|
Reassoc = 53,
|
||||||
|
GetRoamTrigger = 54,
|
||||||
|
SetRoamTrigger = 55,
|
||||||
|
GetRoamDelta = 56,
|
||||||
|
SetRoamDelta = 57,
|
||||||
|
GetRoamScanPeriod = 58,
|
||||||
|
SetRoamScanPeriod = 59,
|
||||||
|
Evm = 60,
|
||||||
|
GetTxant = 61,
|
||||||
|
SetTxant = 62,
|
||||||
|
GetAntdiv = 63,
|
||||||
|
SetAntdiv = 64,
|
||||||
|
GetClosed = 67,
|
||||||
|
SetClosed = 68,
|
||||||
|
GetMaclist = 69,
|
||||||
|
SetMaclist = 70,
|
||||||
|
GetRateset = 71,
|
||||||
|
SetRateset = 72,
|
||||||
|
Longtrain = 74,
|
||||||
|
GetBcnprd = 75,
|
||||||
|
SetBcnprd = 76,
|
||||||
|
GetDtimprd = 77,
|
||||||
|
SetDtimprd = 78,
|
||||||
|
GetSrom = 79,
|
||||||
|
SetSrom = 80,
|
||||||
|
GetWepRestrict = 81,
|
||||||
|
SetWepRestrict = 82,
|
||||||
|
GetCountry = 83,
|
||||||
|
SetCountry = 84,
|
||||||
|
GetPm = 85,
|
||||||
|
SetPm = 86,
|
||||||
|
GetWake = 87,
|
||||||
|
SetWake = 88,
|
||||||
|
GetForcelink = 90,
|
||||||
|
SetForcelink = 91,
|
||||||
|
FreqAccuracy = 92,
|
||||||
|
CarrierSuppress = 93,
|
||||||
|
GetPhyreg = 94,
|
||||||
|
SetPhyreg = 95,
|
||||||
|
GetRadioreg = 96,
|
||||||
|
SetRadioreg = 97,
|
||||||
|
GetRevinfo = 98,
|
||||||
|
GetUcantdiv = 99,
|
||||||
|
SetUcantdiv = 100,
|
||||||
|
RReg = 101,
|
||||||
|
WReg = 102,
|
||||||
|
GetMacmode = 105,
|
||||||
|
SetMacmode = 106,
|
||||||
|
GetMonitor = 107,
|
||||||
|
SetMonitor = 108,
|
||||||
|
GetGmode = 109,
|
||||||
|
SetGmode = 110,
|
||||||
|
GetLegacyErp = 111,
|
||||||
|
SetLegacyErp = 112,
|
||||||
|
GetRxAnt = 113,
|
||||||
|
GetCurrRateset = 114,
|
||||||
|
GetScansuppress = 115,
|
||||||
|
SetScansuppress = 116,
|
||||||
|
GetAp = 117,
|
||||||
|
SetAp = 118,
|
||||||
|
GetEapRestrict = 119,
|
||||||
|
SetEapRestrict = 120,
|
||||||
|
ScbAuthorize = 121,
|
||||||
|
ScbDeauthorize = 122,
|
||||||
|
GetWdslist = 123,
|
||||||
|
SetWdslist = 124,
|
||||||
|
GetAtim = 125,
|
||||||
|
SetAtim = 126,
|
||||||
|
GetRssi = 127,
|
||||||
|
GetPhyantdiv = 128,
|
||||||
|
SetPhyantdiv = 129,
|
||||||
|
ApRxOnly = 130,
|
||||||
|
GetTxPathPwr = 131,
|
||||||
|
SetTxPathPwr = 132,
|
||||||
|
GetWsec = 133,
|
||||||
|
SetWsec = 134,
|
||||||
|
GetPhyNoise = 135,
|
||||||
|
GetBssInfo = 136,
|
||||||
|
GetPktcnts = 137,
|
||||||
|
GetLazywds = 138,
|
||||||
|
SetLazywds = 139,
|
||||||
|
GetBandlist = 140,
|
||||||
|
GetBand = 141,
|
||||||
|
SetBand = 142,
|
||||||
|
ScbDeauthenticate = 143,
|
||||||
|
GetShortslot = 144,
|
||||||
|
GetShortslotOverride = 145,
|
||||||
|
SetShortslotOverride = 146,
|
||||||
|
GetShortslotRestrict = 147,
|
||||||
|
SetShortslotRestrict = 148,
|
||||||
|
GetGmodeProtection = 149,
|
||||||
|
GetGmodeProtectionOverride = 150,
|
||||||
|
SetGmodeProtectionOverride = 151,
|
||||||
|
Upgrade = 152,
|
||||||
|
GetIgnoreBcns = 155,
|
||||||
|
SetIgnoreBcns = 156,
|
||||||
|
GetScbTimeout = 157,
|
||||||
|
SetScbTimeout = 158,
|
||||||
|
GetAssoclist = 159,
|
||||||
|
GetClk = 160,
|
||||||
|
SetClk = 161,
|
||||||
|
GetUp = 162,
|
||||||
|
Out = 163,
|
||||||
|
GetWpaAuth = 164,
|
||||||
|
SetWpaAuth = 165,
|
||||||
|
GetUcflags = 166,
|
||||||
|
SetUcflags = 167,
|
||||||
|
GetPwridx = 168,
|
||||||
|
SetPwridx = 169,
|
||||||
|
GetTssi = 170,
|
||||||
|
GetSupRatesetOverride = 171,
|
||||||
|
SetSupRatesetOverride = 172,
|
||||||
|
GetProtectionControl = 178,
|
||||||
|
SetProtectionControl = 179,
|
||||||
|
GetPhylist = 180,
|
||||||
|
EncryptStrength = 181,
|
||||||
|
DecryptStatus = 182,
|
||||||
|
GetKeySeq = 183,
|
||||||
|
GetScanChannelTime = 184,
|
||||||
|
SetScanChannelTime = 185,
|
||||||
|
GetScanUnassocTime = 186,
|
||||||
|
SetScanUnassocTime = 187,
|
||||||
|
GetScanHomeTime = 188,
|
||||||
|
SetScanHomeTime = 189,
|
||||||
|
GetScanNprobes = 190,
|
||||||
|
SetScanNprobes = 191,
|
||||||
|
GetPrbRespTimeout = 192,
|
||||||
|
SetPrbRespTimeout = 193,
|
||||||
|
GetAtten = 194,
|
||||||
|
SetAtten = 195,
|
||||||
|
GetShmem = 196,
|
||||||
|
SetShmem = 197,
|
||||||
|
SetWsecTest = 200,
|
||||||
|
ScbDeauthenticateForReason = 201,
|
||||||
|
TkipCountermeasures = 202,
|
||||||
|
GetPiomode = 203,
|
||||||
|
SetPiomode = 204,
|
||||||
|
SetAssocPrefer = 205,
|
||||||
|
GetAssocPrefer = 206,
|
||||||
|
SetRoamPrefer = 207,
|
||||||
|
GetRoamPrefer = 208,
|
||||||
|
SetLed = 209,
|
||||||
|
GetLed = 210,
|
||||||
|
GetInterferenceMode = 211,
|
||||||
|
SetInterferenceMode = 212,
|
||||||
|
GetChannelQa = 213,
|
||||||
|
StartChannelQa = 214,
|
||||||
|
GetChannelSel = 215,
|
||||||
|
StartChannelSel = 216,
|
||||||
|
GetValidChannels = 217,
|
||||||
|
GetFakefrag = 218,
|
||||||
|
SetFakefrag = 219,
|
||||||
|
GetPwroutPercentage = 220,
|
||||||
|
SetPwroutPercentage = 221,
|
||||||
|
SetBadFramePreempt = 222,
|
||||||
|
GetBadFramePreempt = 223,
|
||||||
|
SetLeapList = 224,
|
||||||
|
GetLeapList = 225,
|
||||||
|
GetCwmin = 226,
|
||||||
|
SetCwmin = 227,
|
||||||
|
GetCwmax = 228,
|
||||||
|
SetCwmax = 229,
|
||||||
|
GetWet = 230,
|
||||||
|
SetWet = 231,
|
||||||
|
GetPub = 232,
|
||||||
|
GetKeyPrimary = 235,
|
||||||
|
SetKeyPrimary = 236,
|
||||||
|
GetAciArgs = 238,
|
||||||
|
SetAciArgs = 239,
|
||||||
|
UnsetCallback = 240,
|
||||||
|
SetCallback = 241,
|
||||||
|
GetRadar = 242,
|
||||||
|
SetRadar = 243,
|
||||||
|
SetSpectManagment = 244,
|
||||||
|
GetSpectManagment = 245,
|
||||||
|
WdsGetRemoteHwaddr = 246,
|
||||||
|
WdsGetWpaSup = 247,
|
||||||
|
SetCsScanTimer = 248,
|
||||||
|
GetCsScanTimer = 249,
|
||||||
|
MeasureRequest = 250,
|
||||||
|
Init = 251,
|
||||||
|
SendQuiet = 252,
|
||||||
|
Keepalive = 253,
|
||||||
|
SendPwrConstraint = 254,
|
||||||
|
UpgradeStatus = 255,
|
||||||
|
CurrentPwr = 256,
|
||||||
|
GetScanPassiveTime = 257,
|
||||||
|
SetScanPassiveTime = 258,
|
||||||
|
LegacyLinkBehavior = 259,
|
||||||
|
GetChannelsInCountry = 260,
|
||||||
|
GetCountryList = 261,
|
||||||
|
GetVar = 262,
|
||||||
|
SetVar = 263,
|
||||||
|
NvramGet = 264,
|
||||||
|
NvramSet = 265,
|
||||||
|
NvramDump = 266,
|
||||||
|
Reboot = 267,
|
||||||
|
SetWsecPmk = 268,
|
||||||
|
GetAuthMode = 269,
|
||||||
|
SetAuthMode = 270,
|
||||||
|
GetWakeentry = 271,
|
||||||
|
SetWakeentry = 272,
|
||||||
|
NdconfigItem = 273,
|
||||||
|
Nvotpw = 274,
|
||||||
|
Otpw = 275,
|
||||||
|
IovBlockGet = 276,
|
||||||
|
IovModulesGet = 277,
|
||||||
|
SoftReset = 278,
|
||||||
|
GetAllowMode = 279,
|
||||||
|
SetAllowMode = 280,
|
||||||
|
GetDesiredBssid = 281,
|
||||||
|
SetDesiredBssid = 282,
|
||||||
|
DisassocMyap = 283,
|
||||||
|
GetNbands = 284,
|
||||||
|
GetBandstates = 285,
|
||||||
|
GetWlcBssInfo = 286,
|
||||||
|
GetAssocInfo = 287,
|
||||||
|
GetOidPhy = 288,
|
||||||
|
SetOidPhy = 289,
|
||||||
|
SetAssocTime = 290,
|
||||||
|
GetDesiredSsid = 291,
|
||||||
|
GetChanspec = 292,
|
||||||
|
GetAssocState = 293,
|
||||||
|
SetPhyState = 294,
|
||||||
|
GetScanPending = 295,
|
||||||
|
GetScanreqPending = 296,
|
||||||
|
GetPrevRoamReason = 297,
|
||||||
|
SetPrevRoamReason = 298,
|
||||||
|
GetBandstatesPi = 299,
|
||||||
|
GetPhyState = 300,
|
||||||
|
GetBssWpaRsn = 301,
|
||||||
|
GetBssWpa2Rsn = 302,
|
||||||
|
GetBssBcnTs = 303,
|
||||||
|
GetIntDisassoc = 304,
|
||||||
|
SetNumPeers = 305,
|
||||||
|
GetNumBss = 306,
|
||||||
|
GetWsecPmk = 318,
|
||||||
|
GetRandomBytes = 319,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) const WSEC_TKIP: u32 = 0x02;
|
||||||
|
pub(crate) const WSEC_AES: u32 = 0x04;
|
||||||
|
|
||||||
|
pub(crate) const AUTH_OPEN: u32 = 0x00;
|
||||||
|
pub(crate) const AUTH_SAE: u32 = 0x03;
|
||||||
|
|
||||||
|
pub(crate) const MFP_NONE: u32 = 0;
|
||||||
|
pub(crate) const MFP_CAPABLE: u32 = 1;
|
||||||
|
pub(crate) const MFP_REQUIRED: u32 = 2;
|
||||||
|
|
||||||
|
pub(crate) const WPA_AUTH_DISABLED: u32 = 0x0000;
|
||||||
|
pub(crate) const WPA_AUTH_WPA_PSK: u32 = 0x0004;
|
||||||
|
pub(crate) const WPA_AUTH_WPA2_PSK: u32 = 0x0080;
|
||||||
|
pub(crate) const WPA_AUTH_WPA3_SAE_PSK: u32 = 0x40000;
|
||||||
|
@ -35,7 +35,7 @@ pub struct Control<'a> {
|
|||||||
ioctl_state: &'a IoctlState,
|
ioctl_state: &'a IoctlState,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
pub enum ScanType {
|
pub enum ScanType {
|
||||||
Active,
|
Active,
|
||||||
@ -43,8 +43,9 @@ pub enum ScanType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Scan options.
|
/// Scan options.
|
||||||
#[derive(Clone)]
|
#[derive(Clone, Debug)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
|
#[non_exhaustive]
|
||||||
pub struct ScanOptions {
|
pub struct ScanOptions {
|
||||||
/// SSID to scan for.
|
/// SSID to scan for.
|
||||||
pub ssid: Option<heapless::String<32>>,
|
pub ssid: Option<heapless::String<32>>,
|
||||||
@ -74,6 +75,79 @@ impl Default for ScanOptions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Authentication type, used in [`JoinOptions::auth`].
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
|
pub enum JoinAuth {
|
||||||
|
/// Open network
|
||||||
|
Open,
|
||||||
|
/// WPA only
|
||||||
|
Wpa,
|
||||||
|
/// WPA2 only
|
||||||
|
Wpa2,
|
||||||
|
/// WPA3 only
|
||||||
|
Wpa3,
|
||||||
|
/// WPA2 + WPA3
|
||||||
|
Wpa2Wpa3,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Options for [`Control::join`].
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
|
#[non_exhaustive]
|
||||||
|
pub struct JoinOptions<'a> {
|
||||||
|
/// Authentication type. Default `Wpa2Wpa3`.
|
||||||
|
pub auth: JoinAuth,
|
||||||
|
/// Enable TKIP encryption. Default false.
|
||||||
|
pub cipher_tkip: bool,
|
||||||
|
/// Enable AES encryption. Default true.
|
||||||
|
pub cipher_aes: bool,
|
||||||
|
/// Passphrase. Default empty.
|
||||||
|
pub passphrase: &'a [u8],
|
||||||
|
/// If false, `passphrase` is the human-readable passphrase string.
|
||||||
|
/// If true, `passphrase` is the result of applying the PBKDF2 hash to the
|
||||||
|
/// passphrase string. This makes it possible to avoid storing unhashed passwords.
|
||||||
|
///
|
||||||
|
/// This is not compatible with WPA3.
|
||||||
|
/// Default false.
|
||||||
|
pub passphrase_is_prehashed: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> JoinOptions<'a> {
|
||||||
|
/// Create a new `JoinOptions` for joining open networks.
|
||||||
|
pub fn new_open() -> Self {
|
||||||
|
Self {
|
||||||
|
auth: JoinAuth::Open,
|
||||||
|
cipher_tkip: false,
|
||||||
|
cipher_aes: false,
|
||||||
|
passphrase: &[],
|
||||||
|
passphrase_is_prehashed: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a new `JoinOptions` for joining encrypted networks.
|
||||||
|
///
|
||||||
|
/// Defaults to supporting WPA2+WPA3 with AES only, you may edit
|
||||||
|
/// the returned options to change this.
|
||||||
|
pub fn new(passphrase: &'a [u8]) -> Self {
|
||||||
|
let mut this = Self::default();
|
||||||
|
this.passphrase = passphrase;
|
||||||
|
this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Default for JoinOptions<'a> {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
auth: JoinAuth::Wpa2Wpa3,
|
||||||
|
cipher_tkip: false,
|
||||||
|
cipher_aes: true,
|
||||||
|
passphrase: &[],
|
||||||
|
passphrase_is_prehashed: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a> Control<'a> {
|
impl<'a> Control<'a> {
|
||||||
pub(crate) fn new(state_ch: ch::StateRunner<'a>, event_sub: &'a Events, ioctl_state: &'a IoctlState) -> Self {
|
pub(crate) fn new(state_ch: ch::StateRunner<'a>, event_sub: &'a Events, ioctl_state: &'a IoctlState) -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -109,7 +183,7 @@ impl<'a> Control<'a> {
|
|||||||
buf[0..8].copy_from_slice(b"clmload\x00");
|
buf[0..8].copy_from_slice(b"clmload\x00");
|
||||||
buf[8..20].copy_from_slice(&header.to_bytes());
|
buf[8..20].copy_from_slice(&header.to_bytes());
|
||||||
buf[20..][..chunk.len()].copy_from_slice(&chunk);
|
buf[20..][..chunk.len()].copy_from_slice(&chunk);
|
||||||
self.ioctl(IoctlType::Set, IOCTL_CMD_SET_VAR, 0, &mut buf[..8 + 12 + chunk.len()])
|
self.ioctl(IoctlType::Set, Ioctl::SetVar, 0, &mut buf[..8 + 12 + chunk.len()])
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,7 +219,7 @@ impl<'a> Control<'a> {
|
|||||||
Timer::after_millis(100).await;
|
Timer::after_millis(100).await;
|
||||||
|
|
||||||
// Set antenna to chip antenna
|
// Set antenna to chip antenna
|
||||||
self.ioctl_set_u32(IOCTL_CMD_ANTDIV, 0, 0).await;
|
self.ioctl_set_u32(Ioctl::SetAntdiv, 0, 0).await;
|
||||||
|
|
||||||
self.set_iovar_u32("bus:txglom", 0).await;
|
self.set_iovar_u32("bus:txglom", 0).await;
|
||||||
Timer::after_millis(100).await;
|
Timer::after_millis(100).await;
|
||||||
@ -183,8 +257,8 @@ impl<'a> Control<'a> {
|
|||||||
|
|
||||||
Timer::after_millis(100).await;
|
Timer::after_millis(100).await;
|
||||||
|
|
||||||
self.ioctl_set_u32(110, 0, 1).await; // SET_GMODE = auto
|
self.ioctl_set_u32(Ioctl::SetGmode, 0, 1).await; // SET_GMODE = auto
|
||||||
self.ioctl_set_u32(142, 0, 0).await; // SET_BAND = any
|
self.ioctl_set_u32(Ioctl::SetBand, 0, 0).await; // SET_BAND = any
|
||||||
|
|
||||||
Timer::after_millis(100).await;
|
Timer::after_millis(100).await;
|
||||||
|
|
||||||
@ -195,12 +269,12 @@ impl<'a> Control<'a> {
|
|||||||
|
|
||||||
/// Set the WiFi interface up.
|
/// Set the WiFi interface up.
|
||||||
async fn up(&mut self) {
|
async fn up(&mut self) {
|
||||||
self.ioctl(IoctlType::Set, IOCTL_CMD_UP, 0, &mut []).await;
|
self.ioctl(IoctlType::Set, Ioctl::Up, 0, &mut []).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the interface down.
|
/// Set the interface down.
|
||||||
async fn down(&mut self) {
|
async fn down(&mut self) {
|
||||||
self.ioctl(IoctlType::Set, IOCTL_CMD_DOWN, 0, &mut []).await;
|
self.ioctl(IoctlType::Set, Ioctl::Down, 0, &mut []).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set power management mode.
|
/// Set power management mode.
|
||||||
@ -213,17 +287,74 @@ impl<'a> Control<'a> {
|
|||||||
self.set_iovar_u32("bcn_li_dtim", mode.dtim_period() as u32).await;
|
self.set_iovar_u32("bcn_li_dtim", mode.dtim_period() as u32).await;
|
||||||
self.set_iovar_u32("assoc_listen", mode.assoc() as u32).await;
|
self.set_iovar_u32("assoc_listen", mode.assoc() as u32).await;
|
||||||
}
|
}
|
||||||
self.ioctl_set_u32(86, 0, mode_num).await;
|
self.ioctl_set_u32(Ioctl::SetPm, 0, mode_num).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Join an unprotected network with the provided ssid.
|
/// Join an unprotected network with the provided ssid.
|
||||||
pub async fn join_open(&mut self, ssid: &str) -> Result<(), Error> {
|
pub async fn join(&mut self, ssid: &str, options: JoinOptions<'_>) -> Result<(), Error> {
|
||||||
self.set_iovar_u32("ampdu_ba_wsize", 8).await;
|
self.set_iovar_u32("ampdu_ba_wsize", 8).await;
|
||||||
|
|
||||||
self.ioctl_set_u32(134, 0, 0).await; // wsec = open
|
if options.auth == JoinAuth::Open {
|
||||||
self.set_iovar_u32x2("bsscfg:sup_wpa", 0, 0).await;
|
self.ioctl_set_u32(Ioctl::SetWsec, 0, 0).await;
|
||||||
self.ioctl_set_u32(20, 0, 1).await; // set_infra = 1
|
self.set_iovar_u32x2("bsscfg:sup_wpa", 0, 0).await;
|
||||||
self.ioctl_set_u32(22, 0, 0).await; // set_auth = open (0)
|
self.ioctl_set_u32(Ioctl::SetInfra, 0, 1).await;
|
||||||
|
self.ioctl_set_u32(Ioctl::SetAuth, 0, 0).await;
|
||||||
|
self.ioctl_set_u32(Ioctl::SetWpaAuth, 0, WPA_AUTH_DISABLED).await;
|
||||||
|
} else {
|
||||||
|
let mut wsec = 0;
|
||||||
|
if options.cipher_aes {
|
||||||
|
wsec |= WSEC_AES;
|
||||||
|
}
|
||||||
|
if options.cipher_tkip {
|
||||||
|
wsec |= WSEC_TKIP;
|
||||||
|
}
|
||||||
|
self.ioctl_set_u32(Ioctl::SetWsec, 0, wsec).await;
|
||||||
|
|
||||||
|
self.set_iovar_u32x2("bsscfg:sup_wpa", 0, 1).await;
|
||||||
|
self.set_iovar_u32x2("bsscfg:sup_wpa2_eapver", 0, 0xFFFF_FFFF).await;
|
||||||
|
self.set_iovar_u32x2("bsscfg:sup_wpa_tmo", 0, 2500).await;
|
||||||
|
|
||||||
|
Timer::after_millis(100).await;
|
||||||
|
|
||||||
|
let (wpa12, wpa3, auth, mfp, wpa_auth) = match options.auth {
|
||||||
|
JoinAuth::Open => unreachable!(),
|
||||||
|
JoinAuth::Wpa => (true, false, AUTH_OPEN, MFP_NONE, WPA_AUTH_WPA_PSK),
|
||||||
|
JoinAuth::Wpa2 => (true, false, AUTH_OPEN, MFP_CAPABLE, WPA_AUTH_WPA2_PSK),
|
||||||
|
JoinAuth::Wpa3 => (false, true, AUTH_SAE, MFP_REQUIRED, WPA_AUTH_WPA3_SAE_PSK),
|
||||||
|
JoinAuth::Wpa2Wpa3 => (true, true, AUTH_SAE, MFP_CAPABLE, WPA_AUTH_WPA3_SAE_PSK),
|
||||||
|
};
|
||||||
|
|
||||||
|
if wpa12 {
|
||||||
|
let mut flags = 0;
|
||||||
|
if !options.passphrase_is_prehashed {
|
||||||
|
flags |= 1;
|
||||||
|
}
|
||||||
|
let mut pfi = PassphraseInfo {
|
||||||
|
len: options.passphrase.len() as _,
|
||||||
|
flags,
|
||||||
|
passphrase: [0; 64],
|
||||||
|
};
|
||||||
|
pfi.passphrase[..options.passphrase.len()].copy_from_slice(options.passphrase);
|
||||||
|
Timer::after_millis(3).await;
|
||||||
|
self.ioctl(IoctlType::Set, Ioctl::SetWsecPmk, 0, &mut pfi.to_bytes())
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
|
||||||
|
if wpa3 {
|
||||||
|
let mut pfi = SaePassphraseInfo {
|
||||||
|
len: options.passphrase.len() as _,
|
||||||
|
passphrase: [0; 128],
|
||||||
|
};
|
||||||
|
pfi.passphrase[..options.passphrase.len()].copy_from_slice(options.passphrase);
|
||||||
|
Timer::after_millis(3).await;
|
||||||
|
self.set_iovar("sae_password", &pfi.to_bytes()).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.ioctl_set_u32(Ioctl::SetInfra, 0, 1).await;
|
||||||
|
self.ioctl_set_u32(Ioctl::SetAuth, 0, auth).await;
|
||||||
|
self.set_iovar_u32("mfp", mfp).await;
|
||||||
|
self.ioctl_set_u32(Ioctl::SetWpaAuth, 0, wpa_auth).await;
|
||||||
|
}
|
||||||
|
|
||||||
let mut i = SsidInfo {
|
let mut i = SsidInfo {
|
||||||
len: ssid.len() as _,
|
len: ssid.len() as _,
|
||||||
@ -234,69 +365,13 @@ impl<'a> Control<'a> {
|
|||||||
self.wait_for_join(i).await
|
self.wait_for_join(i).await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Join a protected network with the provided ssid and [`PassphraseInfo`].
|
|
||||||
async fn join_wpa2_passphrase_info(&mut self, ssid: &str, passphrase_info: &PassphraseInfo) -> Result<(), Error> {
|
|
||||||
self.set_iovar_u32("ampdu_ba_wsize", 8).await;
|
|
||||||
|
|
||||||
self.ioctl_set_u32(134, 0, 4).await; // wsec = wpa2
|
|
||||||
self.set_iovar_u32x2("bsscfg:sup_wpa", 0, 1).await;
|
|
||||||
self.set_iovar_u32x2("bsscfg:sup_wpa2_eapver", 0, 0xFFFF_FFFF).await;
|
|
||||||
self.set_iovar_u32x2("bsscfg:sup_wpa_tmo", 0, 2500).await;
|
|
||||||
|
|
||||||
Timer::after_millis(100).await;
|
|
||||||
|
|
||||||
self.ioctl(
|
|
||||||
IoctlType::Set,
|
|
||||||
IOCTL_CMD_SET_PASSPHRASE,
|
|
||||||
0,
|
|
||||||
&mut passphrase_info.to_bytes(),
|
|
||||||
)
|
|
||||||
.await; // WLC_SET_WSEC_PMK
|
|
||||||
|
|
||||||
self.ioctl_set_u32(20, 0, 1).await; // set_infra = 1
|
|
||||||
self.ioctl_set_u32(22, 0, 0).await; // set_auth = 0 (open)
|
|
||||||
self.ioctl_set_u32(165, 0, 0x80).await; // set_wpa_auth
|
|
||||||
|
|
||||||
let mut i = SsidInfo {
|
|
||||||
len: ssid.len() as _,
|
|
||||||
ssid: [0; 32],
|
|
||||||
};
|
|
||||||
i.ssid[..ssid.len()].copy_from_slice(ssid.as_bytes());
|
|
||||||
|
|
||||||
self.wait_for_join(i).await
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Join a protected network with the provided ssid and passphrase.
|
|
||||||
pub async fn join_wpa2(&mut self, ssid: &str, passphrase: &str) -> Result<(), Error> {
|
|
||||||
let mut pfi = PassphraseInfo {
|
|
||||||
len: passphrase.len() as _,
|
|
||||||
flags: 1,
|
|
||||||
passphrase: [0; 64],
|
|
||||||
};
|
|
||||||
pfi.passphrase[..passphrase.len()].copy_from_slice(passphrase.as_bytes());
|
|
||||||
self.join_wpa2_passphrase_info(ssid, &pfi).await
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Join a protected network with the provided ssid and precomputed PSK.
|
|
||||||
pub async fn join_wpa2_psk(&mut self, ssid: &str, psk: &[u8; 32]) -> Result<(), Error> {
|
|
||||||
let mut pfi = PassphraseInfo {
|
|
||||||
len: psk.len() as _,
|
|
||||||
flags: 0,
|
|
||||||
passphrase: [0; 64],
|
|
||||||
};
|
|
||||||
pfi.passphrase[..psk.len()].copy_from_slice(psk);
|
|
||||||
self.join_wpa2_passphrase_info(ssid, &pfi).await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn wait_for_join(&mut self, i: SsidInfo) -> Result<(), Error> {
|
async fn wait_for_join(&mut self, i: SsidInfo) -> Result<(), Error> {
|
||||||
self.events.mask.enable(&[Event::SET_SSID, Event::AUTH]);
|
self.events.mask.enable(&[Event::SET_SSID, Event::AUTH]);
|
||||||
let mut subscriber = self.events.queue.subscriber().unwrap();
|
let mut subscriber = self.events.queue.subscriber().unwrap();
|
||||||
// the actual join operation starts here
|
// the actual join operation starts here
|
||||||
// we make sure to enable events before so we don't miss any
|
// we make sure to enable events before so we don't miss any
|
||||||
|
|
||||||
// set_ssid
|
self.ioctl(IoctlType::Set, Ioctl::SetSsid, 0, &mut i.to_bytes()).await;
|
||||||
self.ioctl(IoctlType::Set, IOCTL_CMD_SET_SSID, 0, &mut i.to_bytes())
|
|
||||||
.await;
|
|
||||||
|
|
||||||
// to complete the join, we wait for a SET_SSID event
|
// to complete the join, we wait for a SET_SSID event
|
||||||
// we also save the AUTH status for the user, it may be interesting
|
// we also save the AUTH status for the user, it may be interesting
|
||||||
@ -357,7 +432,7 @@ impl<'a> Control<'a> {
|
|||||||
self.up().await;
|
self.up().await;
|
||||||
|
|
||||||
// Turn on AP mode
|
// Turn on AP mode
|
||||||
self.ioctl_set_u32(IOCTL_CMD_SET_AP, 0, 1).await;
|
self.ioctl_set_u32(Ioctl::SetAp, 0, 1).await;
|
||||||
|
|
||||||
// Set SSID
|
// Set SSID
|
||||||
let mut i = SsidInfoWithIndex {
|
let mut i = SsidInfoWithIndex {
|
||||||
@ -371,7 +446,7 @@ impl<'a> Control<'a> {
|
|||||||
self.set_iovar("bsscfg:ssid", &i.to_bytes()).await;
|
self.set_iovar("bsscfg:ssid", &i.to_bytes()).await;
|
||||||
|
|
||||||
// Set channel number
|
// Set channel number
|
||||||
self.ioctl_set_u32(IOCTL_CMD_SET_CHANNEL, 0, channel as u32).await;
|
self.ioctl_set_u32(Ioctl::SetChannel, 0, channel as u32).await;
|
||||||
|
|
||||||
// Set security
|
// Set security
|
||||||
self.set_iovar_u32x2("bsscfg:wsec", 0, (security as u32) & 0xFF).await;
|
self.set_iovar_u32x2("bsscfg:wsec", 0, (security as u32) & 0xFF).await;
|
||||||
@ -388,7 +463,7 @@ impl<'a> Control<'a> {
|
|||||||
passphrase: [0; 64],
|
passphrase: [0; 64],
|
||||||
};
|
};
|
||||||
pfi.passphrase[..passphrase.as_bytes().len()].copy_from_slice(passphrase.as_bytes());
|
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())
|
self.ioctl(IoctlType::Set, Ioctl::SetWsecPmk, 0, &mut pfi.to_bytes())
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -405,7 +480,7 @@ impl<'a> Control<'a> {
|
|||||||
self.set_iovar_u32x2("bss", 0, 0).await; // bss = BSS_DOWN
|
self.set_iovar_u32x2("bss", 0, 0).await; // bss = BSS_DOWN
|
||||||
|
|
||||||
// Turn off AP mode
|
// Turn off AP mode
|
||||||
self.ioctl_set_u32(IOCTL_CMD_SET_AP, 0, 0).await;
|
self.ioctl_set_u32(Ioctl::SetAp, 0, 0).await;
|
||||||
|
|
||||||
// Temporarily set wifi down
|
// Temporarily set wifi down
|
||||||
self.down().await;
|
self.down().await;
|
||||||
@ -484,11 +559,11 @@ impl<'a> Control<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn set_iovar(&mut self, name: &str, val: &[u8]) {
|
async fn set_iovar(&mut self, name: &str, val: &[u8]) {
|
||||||
self.set_iovar_v::<64>(name, val).await
|
self.set_iovar_v::<196>(name, val).await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn set_iovar_v<const BUFSIZE: usize>(&mut self, name: &str, val: &[u8]) {
|
async fn set_iovar_v<const BUFSIZE: usize>(&mut self, name: &str, val: &[u8]) {
|
||||||
debug!("set {} = {:02x}", name, Bytes(val));
|
debug!("iovar set {} = {:02x}", name, Bytes(val));
|
||||||
|
|
||||||
let mut buf = [0; BUFSIZE];
|
let mut buf = [0; BUFSIZE];
|
||||||
buf[..name.len()].copy_from_slice(name.as_bytes());
|
buf[..name.len()].copy_from_slice(name.as_bytes());
|
||||||
@ -496,13 +571,13 @@ impl<'a> Control<'a> {
|
|||||||
buf[name.len() + 1..][..val.len()].copy_from_slice(val);
|
buf[name.len() + 1..][..val.len()].copy_from_slice(val);
|
||||||
|
|
||||||
let total_len = name.len() + 1 + val.len();
|
let total_len = name.len() + 1 + val.len();
|
||||||
self.ioctl(IoctlType::Set, IOCTL_CMD_SET_VAR, 0, &mut buf[..total_len])
|
self.ioctl_inner(IoctlType::Set, Ioctl::SetVar, 0, &mut buf[..total_len])
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO this is not really working, it always returns all zeros.
|
// TODO this is not really working, it always returns all zeros.
|
||||||
async fn get_iovar(&mut self, name: &str, res: &mut [u8]) -> usize {
|
async fn get_iovar(&mut self, name: &str, res: &mut [u8]) -> usize {
|
||||||
debug!("get {}", name);
|
debug!("iovar get {}", name);
|
||||||
|
|
||||||
let mut buf = [0; 64];
|
let mut buf = [0; 64];
|
||||||
buf[..name.len()].copy_from_slice(name.as_bytes());
|
buf[..name.len()].copy_from_slice(name.as_bytes());
|
||||||
@ -510,7 +585,7 @@ impl<'a> Control<'a> {
|
|||||||
|
|
||||||
let total_len = max(name.len() + 1, res.len());
|
let total_len = max(name.len() + 1, res.len());
|
||||||
let res_len = self
|
let res_len = self
|
||||||
.ioctl(IoctlType::Get, IOCTL_CMD_GET_VAR, 0, &mut buf[..total_len])
|
.ioctl_inner(IoctlType::Get, Ioctl::GetVar, 0, &mut buf[..total_len])
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let out_len = min(res.len(), res_len);
|
let out_len = min(res.len(), res_len);
|
||||||
@ -518,12 +593,20 @@ impl<'a> Control<'a> {
|
|||||||
out_len
|
out_len
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn ioctl_set_u32(&mut self, cmd: u32, iface: u32, val: u32) {
|
async fn ioctl_set_u32(&mut self, cmd: Ioctl, iface: u32, val: u32) {
|
||||||
let mut buf = val.to_le_bytes();
|
let mut buf = val.to_le_bytes();
|
||||||
self.ioctl(IoctlType::Set, cmd, iface, &mut buf).await;
|
self.ioctl(IoctlType::Set, cmd, iface, &mut buf).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn ioctl(&mut self, kind: IoctlType, cmd: u32, iface: u32, buf: &mut [u8]) -> usize {
|
async fn ioctl(&mut self, kind: IoctlType, cmd: Ioctl, iface: u32, buf: &mut [u8]) -> usize {
|
||||||
|
if kind == IoctlType::Set {
|
||||||
|
debug!("ioctl set {:?} iface {} = {:02x}", cmd, iface, Bytes(buf));
|
||||||
|
}
|
||||||
|
let n = self.ioctl_inner(kind, cmd, iface, buf).await;
|
||||||
|
n
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn ioctl_inner(&mut self, kind: IoctlType, cmd: Ioctl, iface: u32, buf: &mut [u8]) -> usize {
|
||||||
struct CancelOnDrop<'a>(&'a IoctlState);
|
struct CancelOnDrop<'a>(&'a IoctlState);
|
||||||
|
|
||||||
impl CancelOnDrop<'_> {
|
impl CancelOnDrop<'_> {
|
||||||
@ -615,7 +698,7 @@ impl<'a> Control<'a> {
|
|||||||
}
|
}
|
||||||
/// Leave the wifi, with which we are currently associated.
|
/// Leave the wifi, with which we are currently associated.
|
||||||
pub async fn leave(&mut self) {
|
pub async fn leave(&mut self) {
|
||||||
self.ioctl(IoctlType::Set, IOCTL_CMD_DISASSOC, 0, &mut []).await;
|
self.ioctl(IoctlType::Set, Ioctl::Disassoc, 0, &mut []).await;
|
||||||
info!("Disassociated")
|
info!("Disassociated")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,9 +4,10 @@ use core::task::{Poll, Waker};
|
|||||||
|
|
||||||
use embassy_sync::waitqueue::WakerRegistration;
|
use embassy_sync::waitqueue::WakerRegistration;
|
||||||
|
|
||||||
|
use crate::consts::Ioctl;
|
||||||
use crate::fmt::Bytes;
|
use crate::fmt::Bytes;
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum IoctlType {
|
pub enum IoctlType {
|
||||||
Get = 0,
|
Get = 0,
|
||||||
Set = 2,
|
Set = 2,
|
||||||
@ -16,7 +17,7 @@ pub enum IoctlType {
|
|||||||
pub struct PendingIoctl {
|
pub struct PendingIoctl {
|
||||||
pub buf: *mut [u8],
|
pub buf: *mut [u8],
|
||||||
pub kind: IoctlType,
|
pub kind: IoctlType,
|
||||||
pub cmd: u32,
|
pub cmd: Ioctl,
|
||||||
pub iface: u32,
|
pub iface: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,7 +102,7 @@ impl IoctlState {
|
|||||||
self.state.set(IoctlStateInner::Done { resp_len: 0 });
|
self.state.set(IoctlStateInner::Done { resp_len: 0 });
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn do_ioctl(&self, kind: IoctlType, cmd: u32, iface: u32, buf: &mut [u8]) -> usize {
|
pub async fn do_ioctl(&self, kind: IoctlType, cmd: Ioctl, iface: u32, buf: &mut [u8]) -> usize {
|
||||||
self.state
|
self.state
|
||||||
.set(IoctlStateInner::Pending(PendingIoctl { buf, kind, cmd, iface }));
|
.set(IoctlStateInner::Pending(PendingIoctl { buf, kind, cmd, iface }));
|
||||||
self.wake_runner();
|
self.wake_runner();
|
||||||
|
@ -28,7 +28,9 @@ use ioctl::IoctlState;
|
|||||||
|
|
||||||
use crate::bus::Bus;
|
use crate::bus::Bus;
|
||||||
pub use crate::bus::SpiBusCyw43;
|
pub use crate::bus::SpiBusCyw43;
|
||||||
pub use crate::control::{AddMulticastAddressError, Control, Error as ControlError, ScanOptions, Scanner};
|
pub use crate::control::{
|
||||||
|
AddMulticastAddressError, Control, Error as ControlError, JoinAuth, JoinOptions, ScanOptions, Scanner,
|
||||||
|
};
|
||||||
pub use crate::runner::Runner;
|
pub use crate::runner::Runner;
|
||||||
pub use crate::structs::BssInfo;
|
pub use crate::structs::BssInfo;
|
||||||
|
|
||||||
|
@ -560,7 +560,7 @@ where
|
|||||||
self.sdpcm_seq != self.sdpcm_seq_max && self.sdpcm_seq_max.wrapping_sub(self.sdpcm_seq) & 0x80 == 0
|
self.sdpcm_seq != self.sdpcm_seq_max && self.sdpcm_seq_max.wrapping_sub(self.sdpcm_seq) & 0x80 == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn send_ioctl(&mut self, kind: IoctlType, cmd: u32, iface: u32, data: &[u8], buf: &mut [u32; 512]) {
|
async fn send_ioctl(&mut self, kind: IoctlType, cmd: Ioctl, iface: u32, data: &[u8], buf: &mut [u32; 512]) {
|
||||||
let buf8 = slice8_mut(buf);
|
let buf8 = slice8_mut(buf);
|
||||||
|
|
||||||
let total_len = SdpcmHeader::SIZE + CdcHeader::SIZE + data.len();
|
let total_len = SdpcmHeader::SIZE + CdcHeader::SIZE + data.len();
|
||||||
@ -582,7 +582,7 @@ where
|
|||||||
};
|
};
|
||||||
|
|
||||||
let cdc_header = CdcHeader {
|
let cdc_header = CdcHeader {
|
||||||
cmd: cmd,
|
cmd: cmd as u32,
|
||||||
len: data.len() as _,
|
len: data.len() as _,
|
||||||
flags: kind as u16 | (iface as u16) << 12,
|
flags: kind as u16 | (iface as u16) << 12,
|
||||||
id: self.ioctl_id,
|
id: self.ioctl_id,
|
||||||
|
@ -394,6 +394,15 @@ pub struct PassphraseInfo {
|
|||||||
}
|
}
|
||||||
impl_bytes!(PassphraseInfo);
|
impl_bytes!(PassphraseInfo);
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct SaePassphraseInfo {
|
||||||
|
pub len: u16,
|
||||||
|
pub passphrase: [u8; 128],
|
||||||
|
}
|
||||||
|
impl_bytes!(SaePassphraseInfo);
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
use core::str::from_utf8;
|
use core::str::from_utf8;
|
||||||
|
|
||||||
|
use cyw43::JoinOptions;
|
||||||
use cyw43_pio::PioSpi;
|
use cyw43_pio::PioSpi;
|
||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
@ -95,8 +96,10 @@ async fn main(spawner: Spawner) {
|
|||||||
unwrap!(spawner.spawn(net_task(stack)));
|
unwrap!(spawner.spawn(net_task(stack)));
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
//control.join_open(WIFI_NETWORK).await;
|
match control
|
||||||
match control.join_wpa2(WIFI_NETWORK, WIFI_PASSWORD).await {
|
.join(WIFI_NETWORK, JoinOptions::new(WIFI_PASSWORD.as_bytes()))
|
||||||
|
.await
|
||||||
|
{
|
||||||
Ok(_) => break,
|
Ok(_) => break,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
info!("join failed with status={}", err.status);
|
info!("join failed with status={}", err.status);
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
use core::str::from_utf8;
|
use core::str::from_utf8;
|
||||||
|
|
||||||
|
use cyw43::JoinOptions;
|
||||||
use cyw43_pio::PioSpi;
|
use cyw43_pio::PioSpi;
|
||||||
use defmt::*;
|
use defmt::*;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
@ -98,8 +99,10 @@ async fn main(spawner: Spawner) {
|
|||||||
unwrap!(spawner.spawn(net_task(stack)));
|
unwrap!(spawner.spawn(net_task(stack)));
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
//match control.join_open(WIFI_NETWORK).await { // for open networks
|
match control
|
||||||
match control.join_wpa2(WIFI_NETWORK, WIFI_PASSWORD).await {
|
.join(WIFI_NETWORK, JoinOptions::new(WIFI_PASSWORD.as_bytes()))
|
||||||
|
.await
|
||||||
|
{
|
||||||
Ok(_) => break,
|
Ok(_) => break,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
info!("join failed with status={}", err.status);
|
info!("join failed with status={}", err.status);
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#![no_main]
|
#![no_main]
|
||||||
teleprobe_meta::target!(b"rpi-pico");
|
teleprobe_meta::target!(b"rpi-pico");
|
||||||
|
|
||||||
|
use cyw43::JoinOptions;
|
||||||
use cyw43_pio::PioSpi;
|
use cyw43_pio::PioSpi;
|
||||||
use defmt::{panic, *};
|
use defmt::{panic, *};
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
@ -81,7 +82,10 @@ async fn main(spawner: Spawner) {
|
|||||||
unwrap!(spawner.spawn(net_task(stack)));
|
unwrap!(spawner.spawn(net_task(stack)));
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match control.join_wpa2(WIFI_NETWORK, WIFI_PASSWORD).await {
|
match control
|
||||||
|
.join(WIFI_NETWORK, JoinOptions::new(WIFI_PASSWORD.as_bytes()))
|
||||||
|
.await
|
||||||
|
{
|
||||||
Ok(_) => break,
|
Ok(_) => break,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
panic!("join failed with status={}", err.status);
|
panic!("join failed with status={}", err.status);
|
||||||
|
Loading…
Reference in New Issue
Block a user