diff options
| author | Dario Nieuwenhuis <[email protected]> | 2024-09-09 00:37:17 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-09-09 00:37:17 +0000 |
| commit | 0ef06cc19b61c8196fea941514ec313a0f15d145 (patch) | |
| tree | 22a2f15923726f1d51ab96a71a95c2b8d8223fb0 | |
| parent | 74e724f96869680da4893ad7024676bef1c57334 (diff) | |
| parent | b9a1aaea5b89bd5689796bdfa4227353ee8a452b (diff) | |
Merge pull request #3323 from embassy-rs/cyw43-wpa3
cyw43: add support for WPA3 and more extensive security options.
| -rw-r--r-- | cyw43/src/consts.rs | 314 | ||||
| -rw-r--r-- | cyw43/src/control.rs | 237 | ||||
| -rw-r--r-- | cyw43/src/ioctl.rs | 7 | ||||
| -rw-r--r-- | cyw43/src/lib.rs | 4 | ||||
| -rw-r--r-- | cyw43/src/runner.rs | 4 | ||||
| -rw-r--r-- | cyw43/src/structs.rs | 9 | ||||
| -rw-r--r-- | examples/rp/src/bin/wifi_tcp_server.rs | 7 | ||||
| -rw-r--r-- | examples/rp/src/bin/wifi_webrequest.rs | 7 | ||||
| -rw-r--r-- | tests/rp/src/bin/cyw43-perf.rs | 6 |
9 files changed, 496 insertions, 99 deletions
diff --git a/cyw43/src/consts.rs b/cyw43/src/consts.rs index b6e22e61d..c3f0dbfd8 100644 --- a/cyw43/src/consts.rs +++ b/cyw43/src/consts.rs | |||
| @@ -113,17 +113,6 @@ pub(crate) const IRQ_F1_INTR: u16 = 0x2000; | |||
| 113 | pub(crate) const IRQ_F2_INTR: u16 = 0x4000; | 113 | pub(crate) const IRQ_F2_INTR: u16 = 0x4000; |
| 114 | pub(crate) const IRQ_F3_INTR: u16 = 0x8000; | 114 | pub(crate) const IRQ_F3_INTR: u16 = 0x8000; |
| 115 | 115 | ||
| 116 | pub(crate) const IOCTL_CMD_UP: u32 = 2; | ||
| 117 | pub(crate) const IOCTL_CMD_DOWN: u32 = 3; | ||
| 118 | pub(crate) const IOCTL_CMD_SET_SSID: u32 = 26; | ||
| 119 | pub(crate) const IOCTL_CMD_SET_CHANNEL: u32 = 30; | ||
| 120 | pub(crate) const IOCTL_CMD_DISASSOC: u32 = 52; | ||
| 121 | pub(crate) const IOCTL_CMD_ANTDIV: u32 = 64; | ||
| 122 | pub(crate) const IOCTL_CMD_SET_AP: u32 = 118; | ||
| 123 | pub(crate) const IOCTL_CMD_SET_VAR: u32 = 263; | ||
| 124 | pub(crate) const IOCTL_CMD_GET_VAR: u32 = 262; | ||
| 125 | pub(crate) const IOCTL_CMD_SET_PASSPHRASE: u32 = 268; | ||
| 126 | |||
| 127 | pub(crate) const CHANNEL_TYPE_CONTROL: u8 = 0; | 116 | pub(crate) const CHANNEL_TYPE_CONTROL: u8 = 0; |
| 128 | pub(crate) const CHANNEL_TYPE_EVENT: u8 = 1; | 117 | pub(crate) const CHANNEL_TYPE_EVENT: u8 = 1; |
| 129 | pub(crate) const CHANNEL_TYPE_DATA: u8 = 2; | 118 | pub(crate) const CHANNEL_TYPE_DATA: u8 = 2; |
| @@ -376,3 +365,306 @@ impl core::fmt::Display for FormatInterrupt { | |||
| 376 | core::fmt::Debug::fmt(self, f) | 365 | core::fmt::Debug::fmt(self, f) |
| 377 | } | 366 | } |
| 378 | } | 367 | } |
| 368 | |||
| 369 | #[derive(Copy, Clone, Debug)] | ||
| 370 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 371 | #[repr(u32)] | ||
| 372 | pub(crate) enum Ioctl { | ||
| 373 | GetMagic = 0, | ||
| 374 | GetVersion = 1, | ||
| 375 | Up = 2, | ||
| 376 | Down = 3, | ||
| 377 | GetLoop = 4, | ||
| 378 | SetLoop = 5, | ||
| 379 | Dump = 6, | ||
| 380 | GetMsglevel = 7, | ||
| 381 | SetMsglevel = 8, | ||
| 382 | GetPromisc = 9, | ||
| 383 | SetPromisc = 10, | ||
| 384 | GetRate = 12, | ||
| 385 | GetInstance = 14, | ||
| 386 | GetInfra = 19, | ||
| 387 | SetInfra = 20, | ||
| 388 | GetAuth = 21, | ||
| 389 | SetAuth = 22, | ||
| 390 | GetBssid = 23, | ||
| 391 | SetBssid = 24, | ||
| 392 | GetSsid = 25, | ||
| 393 | SetSsid = 26, | ||
| 394 | Restart = 27, | ||
| 395 | GetChannel = 29, | ||
| 396 | SetChannel = 30, | ||
| 397 | GetSrl = 31, | ||
| 398 | SetSrl = 32, | ||
| 399 | GetLrl = 33, | ||
| 400 | SetLrl = 34, | ||
| 401 | GetPlcphdr = 35, | ||
| 402 | SetPlcphdr = 36, | ||
| 403 | GetRadio = 37, | ||
| 404 | SetRadio = 38, | ||
| 405 | GetPhytype = 39, | ||
| 406 | DumpRate = 40, | ||
| 407 | SetRateParams = 41, | ||
| 408 | GetKey = 44, | ||
| 409 | SetKey = 45, | ||
| 410 | GetRegulatory = 46, | ||
| 411 | SetRegulatory = 47, | ||
| 412 | GetPassiveScan = 48, | ||
| 413 | SetPassiveScan = 49, | ||
| 414 | Scan = 50, | ||
| 415 | ScanResults = 51, | ||
| 416 | Disassoc = 52, | ||
| 417 | Reassoc = 53, | ||
| 418 | GetRoamTrigger = 54, | ||
| 419 | SetRoamTrigger = 55, | ||
| 420 | GetRoamDelta = 56, | ||
| 421 | SetRoamDelta = 57, | ||
| 422 | GetRoamScanPeriod = 58, | ||
| 423 | SetRoamScanPeriod = 59, | ||
| 424 | Evm = 60, | ||
| 425 | GetTxant = 61, | ||
| 426 | SetTxant = 62, | ||
| 427 | GetAntdiv = 63, | ||
| 428 | SetAntdiv = 64, | ||
| 429 | GetClosed = 67, | ||
| 430 | SetClosed = 68, | ||
| 431 | GetMaclist = 69, | ||
| 432 | SetMaclist = 70, | ||
| 433 | GetRateset = 71, | ||
| 434 | SetRateset = 72, | ||
| 435 | Longtrain = 74, | ||
| 436 | GetBcnprd = 75, | ||
| 437 | SetBcnprd = 76, | ||
| 438 | GetDtimprd = 77, | ||
| 439 | SetDtimprd = 78, | ||
| 440 | GetSrom = 79, | ||
| 441 | SetSrom = 80, | ||
| 442 | GetWepRestrict = 81, | ||
| 443 | SetWepRestrict = 82, | ||
| 444 | GetCountry = 83, | ||
| 445 | SetCountry = 84, | ||
| 446 | GetPm = 85, | ||
| 447 | SetPm = 86, | ||
| 448 | GetWake = 87, | ||
| 449 | SetWake = 88, | ||
| 450 | GetForcelink = 90, | ||
| 451 | SetForcelink = 91, | ||
| 452 | FreqAccuracy = 92, | ||
| 453 | CarrierSuppress = 93, | ||
| 454 | GetPhyreg = 94, | ||
| 455 | SetPhyreg = 95, | ||
| 456 | GetRadioreg = 96, | ||
| 457 | SetRadioreg = 97, | ||
| 458 | GetRevinfo = 98, | ||
| 459 | GetUcantdiv = 99, | ||
| 460 | SetUcantdiv = 100, | ||
| 461 | RReg = 101, | ||
| 462 | WReg = 102, | ||
| 463 | GetMacmode = 105, | ||
| 464 | SetMacmode = 106, | ||
| 465 | GetMonitor = 107, | ||
| 466 | SetMonitor = 108, | ||
| 467 | GetGmode = 109, | ||
| 468 | SetGmode = 110, | ||
| 469 | GetLegacyErp = 111, | ||
| 470 | SetLegacyErp = 112, | ||
| 471 | GetRxAnt = 113, | ||
| 472 | GetCurrRateset = 114, | ||
| 473 | GetScansuppress = 115, | ||
| 474 | SetScansuppress = 116, | ||
| 475 | GetAp = 117, | ||
| 476 | SetAp = 118, | ||
| 477 | GetEapRestrict = 119, | ||
| 478 | SetEapRestrict = 120, | ||
| 479 | ScbAuthorize = 121, | ||
| 480 | ScbDeauthorize = 122, | ||
| 481 | GetWdslist = 123, | ||
| 482 | SetWdslist = 124, | ||
| 483 | GetAtim = 125, | ||
| 484 | SetAtim = 126, | ||
| 485 | GetRssi = 127, | ||
| 486 | GetPhyantdiv = 128, | ||
| 487 | SetPhyantdiv = 129, | ||
| 488 | ApRxOnly = 130, | ||
| 489 | GetTxPathPwr = 131, | ||
| 490 | SetTxPathPwr = 132, | ||
| 491 | GetWsec = 133, | ||
| 492 | SetWsec = 134, | ||
| 493 | GetPhyNoise = 135, | ||
| 494 | GetBssInfo = 136, | ||
| 495 | GetPktcnts = 137, | ||
| 496 | GetLazywds = 138, | ||
| 497 | SetLazywds = 139, | ||
| 498 | GetBandlist = 140, | ||
| 499 | GetBand = 141, | ||
| 500 | SetBand = 142, | ||
| 501 | ScbDeauthenticate = 143, | ||
| 502 | GetShortslot = 144, | ||
| 503 | GetShortslotOverride = 145, | ||
| 504 | SetShortslotOverride = 146, | ||
| 505 | GetShortslotRestrict = 147, | ||
| 506 | SetShortslotRestrict = 148, | ||
| 507 | GetGmodeProtection = 149, | ||
| 508 | GetGmodeProtectionOverride = 150, | ||
| 509 | SetGmodeProtectionOverride = 151, | ||
| 510 | Upgrade = 152, | ||
| 511 | GetIgnoreBcns = 155, | ||
| 512 | SetIgnoreBcns = 156, | ||
| 513 | GetScbTimeout = 157, | ||
| 514 | SetScbTimeout = 158, | ||
| 515 | GetAssoclist = 159, | ||
| 516 | GetClk = 160, | ||
| 517 | SetClk = 161, | ||
| 518 | GetUp = 162, | ||
| 519 | Out = 163, | ||
| 520 | GetWpaAuth = 164, | ||
| 521 | SetWpaAuth = 165, | ||
| 522 | GetUcflags = 166, | ||
| 523 | SetUcflags = 167, | ||
| 524 | GetPwridx = 168, | ||
| 525 | SetPwridx = 169, | ||
| 526 | GetTssi = 170, | ||
| 527 | GetSupRatesetOverride = 171, | ||
| 528 | SetSupRatesetOverride = 172, | ||
| 529 | GetProtectionControl = 178, | ||
| 530 | SetProtectionControl = 179, | ||
| 531 | GetPhylist = 180, | ||
| 532 | EncryptStrength = 181, | ||
| 533 | DecryptStatus = 182, | ||
| 534 | GetKeySeq = 183, | ||
| 535 | GetScanChannelTime = 184, | ||
| 536 | SetScanChannelTime = 185, | ||
| 537 | GetScanUnassocTime = 186, | ||
| 538 | SetScanUnassocTime = 187, | ||
| 539 | GetScanHomeTime = 188, | ||
| 540 | SetScanHomeTime = 189, | ||
| 541 | GetScanNprobes = 190, | ||
| 542 | SetScanNprobes = 191, | ||
| 543 | GetPrbRespTimeout = 192, | ||
| 544 | SetPrbRespTimeout = 193, | ||
| 545 | GetAtten = 194, | ||
| 546 | SetAtten = 195, | ||
| 547 | GetShmem = 196, | ||
| 548 | SetShmem = 197, | ||
| 549 | SetWsecTest = 200, | ||
| 550 | ScbDeauthenticateForReason = 201, | ||
| 551 | TkipCountermeasures = 202, | ||
| 552 | GetPiomode = 203, | ||
| 553 | SetPiomode = 204, | ||
| 554 | SetAssocPrefer = 205, | ||
| 555 | GetAssocPrefer = 206, | ||
| 556 | SetRoamPrefer = 207, | ||
| 557 | GetRoamPrefer = 208, | ||
| 558 | SetLed = 209, | ||
| 559 | GetLed = 210, | ||
| 560 | GetInterferenceMode = 211, | ||
| 561 | SetInterferenceMode = 212, | ||
| 562 | GetChannelQa = 213, | ||
| 563 | StartChannelQa = 214, | ||
| 564 | GetChannelSel = 215, | ||
| 565 | StartChannelSel = 216, | ||
| 566 | GetValidChannels = 217, | ||
| 567 | GetFakefrag = 218, | ||
| 568 | SetFakefrag = 219, | ||
| 569 | GetPwroutPercentage = 220, | ||
| 570 | SetPwroutPercentage = 221, | ||
| 571 | SetBadFramePreempt = 222, | ||
| 572 | GetBadFramePreempt = 223, | ||
| 573 | SetLeapList = 224, | ||
| 574 | GetLeapList = 225, | ||
| 575 | GetCwmin = 226, | ||
| 576 | SetCwmin = 227, | ||
| 577 | GetCwmax = 228, | ||
| 578 | SetCwmax = 229, | ||
| 579 | GetWet = 230, | ||
| 580 | SetWet = 231, | ||
| 581 | GetPub = 232, | ||
| 582 | GetKeyPrimary = 235, | ||
| 583 | SetKeyPrimary = 236, | ||
| 584 | GetAciArgs = 238, | ||
| 585 | SetAciArgs = 239, | ||
| 586 | UnsetCallback = 240, | ||
| 587 | SetCallback = 241, | ||
| 588 | GetRadar = 242, | ||
| 589 | SetRadar = 243, | ||
| 590 | SetSpectManagment = 244, | ||
| 591 | GetSpectManagment = 245, | ||
| 592 | WdsGetRemoteHwaddr = 246, | ||
| 593 | WdsGetWpaSup = 247, | ||
| 594 | SetCsScanTimer = 248, | ||
| 595 | GetCsScanTimer = 249, | ||
| 596 | MeasureRequest = 250, | ||
| 597 | Init = 251, | ||
| 598 | SendQuiet = 252, | ||
| 599 | Keepalive = 253, | ||
| 600 | SendPwrConstraint = 254, | ||
| 601 | UpgradeStatus = 255, | ||
| 602 | CurrentPwr = 256, | ||
| 603 | GetScanPassiveTime = 257, | ||
| 604 | SetScanPassiveTime = 258, | ||
| 605 | LegacyLinkBehavior = 259, | ||
| 606 | GetChannelsInCountry = 260, | ||
| 607 | GetCountryList = 261, | ||
| 608 | GetVar = 262, | ||
| 609 | SetVar = 263, | ||
| 610 | NvramGet = 264, | ||
| 611 | NvramSet = 265, | ||
| 612 | NvramDump = 266, | ||
| 613 | Reboot = 267, | ||
| 614 | SetWsecPmk = 268, | ||
| 615 | GetAuthMode = 269, | ||
| 616 | SetAuthMode = 270, | ||
| 617 | GetWakeentry = 271, | ||
| 618 | SetWakeentry = 272, | ||
| 619 | NdconfigItem = 273, | ||
| 620 | Nvotpw = 274, | ||
| 621 | Otpw = 275, | ||
| 622 | IovBlockGet = 276, | ||
| 623 | IovModulesGet = 277, | ||
| 624 | SoftReset = 278, | ||
| 625 | GetAllowMode = 279, | ||
| 626 | SetAllowMode = 280, | ||
| 627 | GetDesiredBssid = 281, | ||
| 628 | SetDesiredBssid = 282, | ||
| 629 | DisassocMyap = 283, | ||
| 630 | GetNbands = 284, | ||
| 631 | GetBandstates = 285, | ||
| 632 | GetWlcBssInfo = 286, | ||
| 633 | GetAssocInfo = 287, | ||
| 634 | GetOidPhy = 288, | ||
| 635 | SetOidPhy = 289, | ||
| 636 | SetAssocTime = 290, | ||
| 637 | GetDesiredSsid = 291, | ||
| 638 | GetChanspec = 292, | ||
| 639 | GetAssocState = 293, | ||
| 640 | SetPhyState = 294, | ||
| 641 | GetScanPending = 295, | ||
| 642 | GetScanreqPending = 296, | ||
| 643 | GetPrevRoamReason = 297, | ||
| 644 | SetPrevRoamReason = 298, | ||
| 645 | GetBandstatesPi = 299, | ||
| 646 | GetPhyState = 300, | ||
| 647 | GetBssWpaRsn = 301, | ||
| 648 | GetBssWpa2Rsn = 302, | ||
| 649 | GetBssBcnTs = 303, | ||
| 650 | GetIntDisassoc = 304, | ||
| 651 | SetNumPeers = 305, | ||
| 652 | GetNumBss = 306, | ||
| 653 | GetWsecPmk = 318, | ||
| 654 | GetRandomBytes = 319, | ||
| 655 | } | ||
| 656 | |||
| 657 | pub(crate) const WSEC_TKIP: u32 = 0x02; | ||
| 658 | pub(crate) const WSEC_AES: u32 = 0x04; | ||
| 659 | |||
| 660 | pub(crate) const AUTH_OPEN: u32 = 0x00; | ||
| 661 | pub(crate) const AUTH_SAE: u32 = 0x03; | ||
| 662 | |||
| 663 | pub(crate) const MFP_NONE: u32 = 0; | ||
| 664 | pub(crate) const MFP_CAPABLE: u32 = 1; | ||
| 665 | pub(crate) const MFP_REQUIRED: u32 = 2; | ||
| 666 | |||
| 667 | pub(crate) const WPA_AUTH_DISABLED: u32 = 0x0000; | ||
| 668 | pub(crate) const WPA_AUTH_WPA_PSK: u32 = 0x0004; | ||
| 669 | pub(crate) const WPA_AUTH_WPA2_PSK: u32 = 0x0080; | ||
| 670 | pub(crate) const WPA_AUTH_WPA3_SAE_PSK: u32 = 0x40000; | ||
diff --git a/cyw43/src/control.rs b/cyw43/src/control.rs index 22c52bd96..071ba88e4 100644 --- a/cyw43/src/control.rs +++ b/cyw43/src/control.rs | |||
| @@ -35,7 +35,7 @@ pub struct Control<'a> { | |||
| 35 | ioctl_state: &'a IoctlState, | 35 | ioctl_state: &'a IoctlState, |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | #[derive(Copy, Clone)] | 38 | #[derive(Copy, Clone, Debug)] |
| 39 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 39 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 40 | pub enum ScanType { | 40 | pub enum ScanType { |
| 41 | Active, | 41 | Active, |
| @@ -43,8 +43,9 @@ pub enum ScanType { | |||
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | /// Scan options. | 45 | /// Scan options. |
| 46 | #[derive(Clone)] | 46 | #[derive(Clone, Debug)] |
| 47 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 47 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 48 | #[non_exhaustive] | ||
| 48 | pub struct ScanOptions { | 49 | pub struct ScanOptions { |
| 49 | /// SSID to scan for. | 50 | /// SSID to scan for. |
| 50 | pub ssid: Option<heapless::String<32>>, | 51 | pub ssid: Option<heapless::String<32>>, |
| @@ -74,6 +75,79 @@ impl Default for ScanOptions { | |||
| 74 | } | 75 | } |
| 75 | } | 76 | } |
| 76 | 77 | ||
| 78 | /// Authentication type, used in [`JoinOptions::auth`]. | ||
| 79 | #[derive(Copy, Clone, Debug, PartialEq, Eq)] | ||
| 80 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 81 | pub enum JoinAuth { | ||
| 82 | /// Open network | ||
| 83 | Open, | ||
| 84 | /// WPA only | ||
| 85 | Wpa, | ||
| 86 | /// WPA2 only | ||
| 87 | Wpa2, | ||
| 88 | /// WPA3 only | ||
| 89 | Wpa3, | ||
| 90 | /// WPA2 + WPA3 | ||
| 91 | Wpa2Wpa3, | ||
| 92 | } | ||
| 93 | |||
| 94 | /// Options for [`Control::join`]. | ||
| 95 | #[derive(Clone, Debug)] | ||
| 96 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 97 | #[non_exhaustive] | ||
| 98 | pub struct JoinOptions<'a> { | ||
| 99 | /// Authentication type. Default `Wpa2Wpa3`. | ||
| 100 | pub auth: JoinAuth, | ||
| 101 | /// Enable TKIP encryption. Default false. | ||
| 102 | pub cipher_tkip: bool, | ||
| 103 | /// Enable AES encryption. Default true. | ||
| 104 | pub cipher_aes: bool, | ||
| 105 | /// Passphrase. Default empty. | ||
| 106 | pub passphrase: &'a [u8], | ||
| 107 | /// If false, `passphrase` is the human-readable passphrase string. | ||
| 108 | /// If true, `passphrase` is the result of applying the PBKDF2 hash to the | ||
| 109 | /// passphrase string. This makes it possible to avoid storing unhashed passwords. | ||
| 110 | /// | ||
| 111 | /// This is not compatible with WPA3. | ||
| 112 | /// Default false. | ||
| 113 | pub passphrase_is_prehashed: bool, | ||
| 114 | } | ||
| 115 | |||
| 116 | impl<'a> JoinOptions<'a> { | ||
| 117 | /// Create a new `JoinOptions` for joining open networks. | ||
| 118 | pub fn new_open() -> Self { | ||
| 119 | Self { | ||
| 120 | auth: JoinAuth::Open, | ||
| 121 | cipher_tkip: false, | ||
| 122 | cipher_aes: false, | ||
| 123 | passphrase: &[], | ||
| 124 | passphrase_is_prehashed: false, | ||
| 125 | } | ||
| 126 | } | ||
| 127 | |||
| 128 | /// Create a new `JoinOptions` for joining encrypted networks. | ||
| 129 | /// | ||
| 130 | /// Defaults to supporting WPA2+WPA3 with AES only, you may edit | ||
| 131 | /// the returned options to change this. | ||
| 132 | pub fn new(passphrase: &'a [u8]) -> Self { | ||
| 133 | let mut this = Self::default(); | ||
| 134 | this.passphrase = passphrase; | ||
| 135 | this | ||
| 136 | } | ||
| 137 | } | ||
| 138 | |||
| 139 | impl<'a> Default for JoinOptions<'a> { | ||
| 140 | fn default() -> Self { | ||
| 141 | Self { | ||
| 142 | auth: JoinAuth::Wpa2Wpa3, | ||
| 143 | cipher_tkip: false, | ||
| 144 | cipher_aes: true, | ||
| 145 | passphrase: &[], | ||
| 146 | passphrase_is_prehashed: false, | ||
| 147 | } | ||
| 148 | } | ||
| 149 | } | ||
| 150 | |||
| 77 | impl<'a> Control<'a> { | 151 | impl<'a> Control<'a> { |
| 78 | pub(crate) fn new(state_ch: ch::StateRunner<'a>, event_sub: &'a Events, ioctl_state: &'a IoctlState) -> Self { | 152 | pub(crate) fn new(state_ch: ch::StateRunner<'a>, event_sub: &'a Events, ioctl_state: &'a IoctlState) -> Self { |
| 79 | Self { | 153 | Self { |
| @@ -109,7 +183,7 @@ impl<'a> Control<'a> { | |||
| 109 | buf[0..8].copy_from_slice(b"clmload\x00"); | 183 | buf[0..8].copy_from_slice(b"clmload\x00"); |
| 110 | buf[8..20].copy_from_slice(&header.to_bytes()); | 184 | buf[8..20].copy_from_slice(&header.to_bytes()); |
| 111 | buf[20..][..chunk.len()].copy_from_slice(&chunk); | 185 | buf[20..][..chunk.len()].copy_from_slice(&chunk); |
| 112 | self.ioctl(IoctlType::Set, IOCTL_CMD_SET_VAR, 0, &mut buf[..8 + 12 + chunk.len()]) | 186 | self.ioctl(IoctlType::Set, Ioctl::SetVar, 0, &mut buf[..8 + 12 + chunk.len()]) |
| 113 | .await; | 187 | .await; |
| 114 | } | 188 | } |
| 115 | 189 | ||
| @@ -145,7 +219,7 @@ impl<'a> Control<'a> { | |||
| 145 | Timer::after_millis(100).await; | 219 | Timer::after_millis(100).await; |
| 146 | 220 | ||
| 147 | // Set antenna to chip antenna | 221 | // Set antenna to chip antenna |
| 148 | self.ioctl_set_u32(IOCTL_CMD_ANTDIV, 0, 0).await; | 222 | self.ioctl_set_u32(Ioctl::SetAntdiv, 0, 0).await; |
| 149 | 223 | ||
| 150 | self.set_iovar_u32("bus:txglom", 0).await; | 224 | self.set_iovar_u32("bus:txglom", 0).await; |
| 151 | Timer::after_millis(100).await; | 225 | Timer::after_millis(100).await; |
| @@ -183,8 +257,8 @@ impl<'a> Control<'a> { | |||
| 183 | 257 | ||
| 184 | Timer::after_millis(100).await; | 258 | Timer::after_millis(100).await; |
| 185 | 259 | ||
| 186 | self.ioctl_set_u32(110, 0, 1).await; // SET_GMODE = auto | 260 | self.ioctl_set_u32(Ioctl::SetGmode, 0, 1).await; // SET_GMODE = auto |
| 187 | self.ioctl_set_u32(142, 0, 0).await; // SET_BAND = any | 261 | self.ioctl_set_u32(Ioctl::SetBand, 0, 0).await; // SET_BAND = any |
| 188 | 262 | ||
| 189 | Timer::after_millis(100).await; | 263 | Timer::after_millis(100).await; |
| 190 | 264 | ||
| @@ -195,12 +269,12 @@ impl<'a> Control<'a> { | |||
| 195 | 269 | ||
| 196 | /// Set the WiFi interface up. | 270 | /// Set the WiFi interface up. |
| 197 | async fn up(&mut self) { | 271 | async fn up(&mut self) { |
| 198 | self.ioctl(IoctlType::Set, IOCTL_CMD_UP, 0, &mut []).await; | 272 | self.ioctl(IoctlType::Set, Ioctl::Up, 0, &mut []).await; |
| 199 | } | 273 | } |
| 200 | 274 | ||
| 201 | /// Set the interface down. | 275 | /// Set the interface down. |
| 202 | async fn down(&mut self) { | 276 | async fn down(&mut self) { |
| 203 | self.ioctl(IoctlType::Set, IOCTL_CMD_DOWN, 0, &mut []).await; | 277 | self.ioctl(IoctlType::Set, Ioctl::Down, 0, &mut []).await; |
| 204 | } | 278 | } |
| 205 | 279 | ||
| 206 | /// Set power management mode. | 280 | /// Set power management mode. |
| @@ -213,49 +287,74 @@ impl<'a> Control<'a> { | |||
| 213 | self.set_iovar_u32("bcn_li_dtim", mode.dtim_period() as u32).await; | 287 | self.set_iovar_u32("bcn_li_dtim", mode.dtim_period() as u32).await; |
| 214 | self.set_iovar_u32("assoc_listen", mode.assoc() as u32).await; | 288 | self.set_iovar_u32("assoc_listen", mode.assoc() as u32).await; |
| 215 | } | 289 | } |
| 216 | self.ioctl_set_u32(86, 0, mode_num).await; | 290 | self.ioctl_set_u32(Ioctl::SetPm, 0, mode_num).await; |
| 217 | } | 291 | } |
| 218 | 292 | ||
| 219 | /// Join an unprotected network with the provided ssid. | 293 | /// Join an unprotected network with the provided ssid. |
| 220 | pub async fn join_open(&mut self, ssid: &str) -> Result<(), Error> { | 294 | pub async fn join(&mut self, ssid: &str, options: JoinOptions<'_>) -> Result<(), Error> { |
| 221 | self.set_iovar_u32("ampdu_ba_wsize", 8).await; | 295 | self.set_iovar_u32("ampdu_ba_wsize", 8).await; |
| 222 | 296 | ||
| 223 | self.ioctl_set_u32(134, 0, 0).await; // wsec = open | 297 | if options.auth == JoinAuth::Open { |
| 224 | self.set_iovar_u32x2("bsscfg:sup_wpa", 0, 0).await; | 298 | self.ioctl_set_u32(Ioctl::SetWsec, 0, 0).await; |
| 225 | self.ioctl_set_u32(20, 0, 1).await; // set_infra = 1 | 299 | self.set_iovar_u32x2("bsscfg:sup_wpa", 0, 0).await; |
| 226 | self.ioctl_set_u32(22, 0, 0).await; // set_auth = open (0) | 300 | self.ioctl_set_u32(Ioctl::SetInfra, 0, 1).await; |
| 227 | 301 | self.ioctl_set_u32(Ioctl::SetAuth, 0, 0).await; | |
| 228 | let mut i = SsidInfo { | 302 | self.ioctl_set_u32(Ioctl::SetWpaAuth, 0, WPA_AUTH_DISABLED).await; |
| 229 | len: ssid.len() as _, | 303 | } else { |
| 230 | ssid: [0; 32], | 304 | let mut wsec = 0; |
| 231 | }; | 305 | if options.cipher_aes { |
| 232 | i.ssid[..ssid.len()].copy_from_slice(ssid.as_bytes()); | 306 | wsec |= WSEC_AES; |
| 307 | } | ||
| 308 | if options.cipher_tkip { | ||
| 309 | wsec |= WSEC_TKIP; | ||
| 310 | } | ||
| 311 | self.ioctl_set_u32(Ioctl::SetWsec, 0, wsec).await; | ||
| 233 | 312 | ||
| 234 | self.wait_for_join(i).await | 313 | self.set_iovar_u32x2("bsscfg:sup_wpa", 0, 1).await; |
| 235 | } | 314 | self.set_iovar_u32x2("bsscfg:sup_wpa2_eapver", 0, 0xFFFF_FFFF).await; |
| 315 | self.set_iovar_u32x2("bsscfg:sup_wpa_tmo", 0, 2500).await; | ||
| 236 | 316 | ||
| 237 | /// Join a protected network with the provided ssid and [`PassphraseInfo`]. | 317 | Timer::after_millis(100).await; |
| 238 | async fn join_wpa2_passphrase_info(&mut self, ssid: &str, passphrase_info: &PassphraseInfo) -> Result<(), Error> { | ||
| 239 | self.set_iovar_u32("ampdu_ba_wsize", 8).await; | ||
| 240 | 318 | ||
| 241 | self.ioctl_set_u32(134, 0, 4).await; // wsec = wpa2 | 319 | let (wpa12, wpa3, auth, mfp, wpa_auth) = match options.auth { |
| 242 | self.set_iovar_u32x2("bsscfg:sup_wpa", 0, 1).await; | 320 | JoinAuth::Open => unreachable!(), |
| 243 | self.set_iovar_u32x2("bsscfg:sup_wpa2_eapver", 0, 0xFFFF_FFFF).await; | 321 | JoinAuth::Wpa => (true, false, AUTH_OPEN, MFP_NONE, WPA_AUTH_WPA_PSK), |
| 244 | self.set_iovar_u32x2("bsscfg:sup_wpa_tmo", 0, 2500).await; | 322 | JoinAuth::Wpa2 => (true, false, AUTH_OPEN, MFP_CAPABLE, WPA_AUTH_WPA2_PSK), |
| 323 | JoinAuth::Wpa3 => (false, true, AUTH_SAE, MFP_REQUIRED, WPA_AUTH_WPA3_SAE_PSK), | ||
| 324 | JoinAuth::Wpa2Wpa3 => (true, true, AUTH_SAE, MFP_CAPABLE, WPA_AUTH_WPA3_SAE_PSK), | ||
| 325 | }; | ||
| 245 | 326 | ||
| 246 | Timer::after_millis(100).await; | 327 | if wpa12 { |
| 328 | let mut flags = 0; | ||
| 329 | if !options.passphrase_is_prehashed { | ||
| 330 | flags |= 1; | ||
| 331 | } | ||
| 332 | let mut pfi = PassphraseInfo { | ||
| 333 | len: options.passphrase.len() as _, | ||
| 334 | flags, | ||
| 335 | passphrase: [0; 64], | ||
| 336 | }; | ||
| 337 | pfi.passphrase[..options.passphrase.len()].copy_from_slice(options.passphrase); | ||
| 338 | Timer::after_millis(3).await; | ||
| 339 | self.ioctl(IoctlType::Set, Ioctl::SetWsecPmk, 0, &mut pfi.to_bytes()) | ||
| 340 | .await; | ||
| 341 | } | ||
| 247 | 342 | ||
| 248 | self.ioctl( | 343 | if wpa3 { |
| 249 | IoctlType::Set, | 344 | let mut pfi = SaePassphraseInfo { |
| 250 | IOCTL_CMD_SET_PASSPHRASE, | 345 | len: options.passphrase.len() as _, |
| 251 | 0, | 346 | passphrase: [0; 128], |
| 252 | &mut passphrase_info.to_bytes(), | 347 | }; |
| 253 | ) | 348 | pfi.passphrase[..options.passphrase.len()].copy_from_slice(options.passphrase); |
| 254 | .await; // WLC_SET_WSEC_PMK | 349 | Timer::after_millis(3).await; |
| 350 | self.set_iovar("sae_password", &pfi.to_bytes()).await; | ||
| 351 | } | ||
| 255 | 352 | ||
| 256 | self.ioctl_set_u32(20, 0, 1).await; // set_infra = 1 | 353 | self.ioctl_set_u32(Ioctl::SetInfra, 0, 1).await; |
| 257 | self.ioctl_set_u32(22, 0, 0).await; // set_auth = 0 (open) | 354 | self.ioctl_set_u32(Ioctl::SetAuth, 0, auth).await; |
| 258 | self.ioctl_set_u32(165, 0, 0x80).await; // set_wpa_auth | 355 | self.set_iovar_u32("mfp", mfp).await; |
| 356 | self.ioctl_set_u32(Ioctl::SetWpaAuth, 0, wpa_auth).await; | ||
| 357 | } | ||
| 259 | 358 | ||
| 260 | let mut i = SsidInfo { | 359 | let mut i = SsidInfo { |
| 261 | len: ssid.len() as _, | 360 | len: ssid.len() as _, |
| @@ -266,37 +365,13 @@ impl<'a> Control<'a> { | |||
| 266 | self.wait_for_join(i).await | 365 | self.wait_for_join(i).await |
| 267 | } | 366 | } |
| 268 | 367 | ||
| 269 | /// Join a protected network with the provided ssid and passphrase. | ||
| 270 | pub async fn join_wpa2(&mut self, ssid: &str, passphrase: &str) -> Result<(), Error> { | ||
| 271 | let mut pfi = PassphraseInfo { | ||
| 272 | len: passphrase.len() as _, | ||
| 273 | flags: 1, | ||
| 274 | passphrase: [0; 64], | ||
| 275 | }; | ||
| 276 | pfi.passphrase[..passphrase.len()].copy_from_slice(passphrase.as_bytes()); | ||
| 277 | self.join_wpa2_passphrase_info(ssid, &pfi).await | ||
| 278 | } | ||
| 279 | |||
| 280 | /// Join a protected network with the provided ssid and precomputed PSK. | ||
| 281 | pub async fn join_wpa2_psk(&mut self, ssid: &str, psk: &[u8; 32]) -> Result<(), Error> { | ||
| 282 | let mut pfi = PassphraseInfo { | ||
| 283 | len: psk.len() as _, | ||
| 284 | flags: 0, | ||
| 285 | passphrase: [0; 64], | ||
| 286 | }; | ||
| 287 | pfi.passphrase[..psk.len()].copy_from_slice(psk); | ||
| 288 | self.join_wpa2_passphrase_info(ssid, &pfi).await | ||
| 289 | } | ||
| 290 | |||
| 291 | async fn wait_for_join(&mut self, i: SsidInfo) -> Result<(), Error> { | 368 | async fn wait_for_join(&mut self, i: SsidInfo) -> Result<(), Error> { |
| 292 | self.events.mask.enable(&[Event::SET_SSID, Event::AUTH]); | 369 | self.events.mask.enable(&[Event::SET_SSID, Event::AUTH]); |
| 293 | let mut subscriber = self.events.queue.subscriber().unwrap(); | 370 | let mut subscriber = self.events.queue.subscriber().unwrap(); |
| 294 | // the actual join operation starts here | 371 | // the actual join operation starts here |
| 295 | // we make sure to enable events before so we don't miss any | 372 | // we make sure to enable events before so we don't miss any |
| 296 | 373 | ||
| 297 | // set_ssid | 374 | self.ioctl(IoctlType::Set, Ioctl::SetSsid, 0, &mut i.to_bytes()).await; |
| 298 | self.ioctl(IoctlType::Set, IOCTL_CMD_SET_SSID, 0, &mut i.to_bytes()) | ||
| 299 | .await; | ||
| 300 | 375 | ||
| 301 | // to complete the join, we wait for a SET_SSID event | 376 | // to complete the join, we wait for a SET_SSID event |
| 302 | // we also save the AUTH status for the user, it may be interesting | 377 | // we also save the AUTH status for the user, it may be interesting |
| @@ -357,7 +432,7 @@ impl<'a> Control<'a> { | |||
| 357 | self.up().await; | 432 | self.up().await; |
| 358 | 433 | ||
| 359 | // Turn on AP mode | 434 | // Turn on AP mode |
| 360 | self.ioctl_set_u32(IOCTL_CMD_SET_AP, 0, 1).await; | 435 | self.ioctl_set_u32(Ioctl::SetAp, 0, 1).await; |
| 361 | 436 | ||
| 362 | // Set SSID | 437 | // Set SSID |
| 363 | let mut i = SsidInfoWithIndex { | 438 | let mut i = SsidInfoWithIndex { |
| @@ -371,7 +446,7 @@ impl<'a> Control<'a> { | |||
| 371 | self.set_iovar("bsscfg:ssid", &i.to_bytes()).await; | 446 | self.set_iovar("bsscfg:ssid", &i.to_bytes()).await; |
| 372 | 447 | ||
| 373 | // Set channel number | 448 | // Set channel number |
| 374 | self.ioctl_set_u32(IOCTL_CMD_SET_CHANNEL, 0, channel as u32).await; | 449 | self.ioctl_set_u32(Ioctl::SetChannel, 0, channel as u32).await; |
| 375 | 450 | ||
| 376 | // Set security | 451 | // Set security |
| 377 | self.set_iovar_u32x2("bsscfg:wsec", 0, (security as u32) & 0xFF).await; | 452 | self.set_iovar_u32x2("bsscfg:wsec", 0, (security as u32) & 0xFF).await; |
| @@ -388,7 +463,7 @@ impl<'a> Control<'a> { | |||
| 388 | passphrase: [0; 64], | 463 | passphrase: [0; 64], |
| 389 | }; | 464 | }; |
| 390 | pfi.passphrase[..passphrase.as_bytes().len()].copy_from_slice(passphrase.as_bytes()); | 465 | pfi.passphrase[..passphrase.as_bytes().len()].copy_from_slice(passphrase.as_bytes()); |
| 391 | self.ioctl(IoctlType::Set, IOCTL_CMD_SET_PASSPHRASE, 0, &mut pfi.to_bytes()) | 466 | self.ioctl(IoctlType::Set, Ioctl::SetWsecPmk, 0, &mut pfi.to_bytes()) |
| 392 | .await; | 467 | .await; |
| 393 | } | 468 | } |
| 394 | 469 | ||
| @@ -405,7 +480,7 @@ impl<'a> Control<'a> { | |||
| 405 | self.set_iovar_u32x2("bss", 0, 0).await; // bss = BSS_DOWN | 480 | self.set_iovar_u32x2("bss", 0, 0).await; // bss = BSS_DOWN |
| 406 | 481 | ||
| 407 | // Turn off AP mode | 482 | // Turn off AP mode |
| 408 | self.ioctl_set_u32(IOCTL_CMD_SET_AP, 0, 0).await; | 483 | self.ioctl_set_u32(Ioctl::SetAp, 0, 0).await; |
| 409 | 484 | ||
| 410 | // Temporarily set wifi down | 485 | // Temporarily set wifi down |
| 411 | self.down().await; | 486 | self.down().await; |
| @@ -484,11 +559,11 @@ impl<'a> Control<'a> { | |||
| 484 | } | 559 | } |
| 485 | 560 | ||
| 486 | async fn set_iovar(&mut self, name: &str, val: &[u8]) { | 561 | async fn set_iovar(&mut self, name: &str, val: &[u8]) { |
| 487 | self.set_iovar_v::<64>(name, val).await | 562 | self.set_iovar_v::<196>(name, val).await |
| 488 | } | 563 | } |
| 489 | 564 | ||
| 490 | async fn set_iovar_v<const BUFSIZE: usize>(&mut self, name: &str, val: &[u8]) { | 565 | async fn set_iovar_v<const BUFSIZE: usize>(&mut self, name: &str, val: &[u8]) { |
| 491 | debug!("set {} = {:02x}", name, Bytes(val)); | 566 | debug!("iovar set {} = {:02x}", name, Bytes(val)); |
| 492 | 567 | ||
| 493 | let mut buf = [0; BUFSIZE]; | 568 | let mut buf = [0; BUFSIZE]; |
| 494 | buf[..name.len()].copy_from_slice(name.as_bytes()); | 569 | buf[..name.len()].copy_from_slice(name.as_bytes()); |
| @@ -496,13 +571,13 @@ impl<'a> Control<'a> { | |||
| 496 | buf[name.len() + 1..][..val.len()].copy_from_slice(val); | 571 | buf[name.len() + 1..][..val.len()].copy_from_slice(val); |
| 497 | 572 | ||
| 498 | let total_len = name.len() + 1 + val.len(); | 573 | let total_len = name.len() + 1 + val.len(); |
| 499 | self.ioctl(IoctlType::Set, IOCTL_CMD_SET_VAR, 0, &mut buf[..total_len]) | 574 | self.ioctl_inner(IoctlType::Set, Ioctl::SetVar, 0, &mut buf[..total_len]) |
| 500 | .await; | 575 | .await; |
| 501 | } | 576 | } |
| 502 | 577 | ||
| 503 | // TODO this is not really working, it always returns all zeros. | 578 | // TODO this is not really working, it always returns all zeros. |
| 504 | async fn get_iovar(&mut self, name: &str, res: &mut [u8]) -> usize { | 579 | async fn get_iovar(&mut self, name: &str, res: &mut [u8]) -> usize { |
| 505 | debug!("get {}", name); | 580 | debug!("iovar get {}", name); |
| 506 | 581 | ||
| 507 | let mut buf = [0; 64]; | 582 | let mut buf = [0; 64]; |
| 508 | buf[..name.len()].copy_from_slice(name.as_bytes()); | 583 | buf[..name.len()].copy_from_slice(name.as_bytes()); |
| @@ -510,7 +585,7 @@ impl<'a> Control<'a> { | |||
| 510 | 585 | ||
| 511 | let total_len = max(name.len() + 1, res.len()); | 586 | let total_len = max(name.len() + 1, res.len()); |
| 512 | let res_len = self | 587 | let res_len = self |
| 513 | .ioctl(IoctlType::Get, IOCTL_CMD_GET_VAR, 0, &mut buf[..total_len]) | 588 | .ioctl_inner(IoctlType::Get, Ioctl::GetVar, 0, &mut buf[..total_len]) |
| 514 | .await; | 589 | .await; |
| 515 | 590 | ||
| 516 | let out_len = min(res.len(), res_len); | 591 | let out_len = min(res.len(), res_len); |
| @@ -518,12 +593,20 @@ impl<'a> Control<'a> { | |||
| 518 | out_len | 593 | out_len |
| 519 | } | 594 | } |
| 520 | 595 | ||
| 521 | async fn ioctl_set_u32(&mut self, cmd: u32, iface: u32, val: u32) { | 596 | async fn ioctl_set_u32(&mut self, cmd: Ioctl, iface: u32, val: u32) { |
| 522 | let mut buf = val.to_le_bytes(); | 597 | let mut buf = val.to_le_bytes(); |
| 523 | self.ioctl(IoctlType::Set, cmd, iface, &mut buf).await; | 598 | self.ioctl(IoctlType::Set, cmd, iface, &mut buf).await; |
| 524 | } | 599 | } |
| 525 | 600 | ||
| 526 | async fn ioctl(&mut self, kind: IoctlType, cmd: u32, iface: u32, buf: &mut [u8]) -> usize { | 601 | async fn ioctl(&mut self, kind: IoctlType, cmd: Ioctl, iface: u32, buf: &mut [u8]) -> usize { |
| 602 | if kind == IoctlType::Set { | ||
| 603 | debug!("ioctl set {:?} iface {} = {:02x}", cmd, iface, Bytes(buf)); | ||
| 604 | } | ||
| 605 | let n = self.ioctl_inner(kind, cmd, iface, buf).await; | ||
| 606 | n | ||
| 607 | } | ||
| 608 | |||
| 609 | async fn ioctl_inner(&mut self, kind: IoctlType, cmd: Ioctl, iface: u32, buf: &mut [u8]) -> usize { | ||
| 527 | struct CancelOnDrop<'a>(&'a IoctlState); | 610 | struct CancelOnDrop<'a>(&'a IoctlState); |
| 528 | 611 | ||
| 529 | impl CancelOnDrop<'_> { | 612 | impl CancelOnDrop<'_> { |
| @@ -615,7 +698,7 @@ impl<'a> Control<'a> { | |||
| 615 | } | 698 | } |
| 616 | /// Leave the wifi, with which we are currently associated. | 699 | /// Leave the wifi, with which we are currently associated. |
| 617 | pub async fn leave(&mut self) { | 700 | pub async fn leave(&mut self) { |
| 618 | self.ioctl(IoctlType::Set, IOCTL_CMD_DISASSOC, 0, &mut []).await; | 701 | self.ioctl(IoctlType::Set, Ioctl::Disassoc, 0, &mut []).await; |
| 619 | info!("Disassociated") | 702 | info!("Disassociated") |
| 620 | } | 703 | } |
| 621 | 704 | ||
diff --git a/cyw43/src/ioctl.rs b/cyw43/src/ioctl.rs index 61524c274..f8b2d9aba 100644 --- a/cyw43/src/ioctl.rs +++ b/cyw43/src/ioctl.rs | |||
| @@ -4,9 +4,10 @@ use core::task::{Poll, Waker}; | |||
| 4 | 4 | ||
| 5 | use embassy_sync::waitqueue::WakerRegistration; | 5 | use embassy_sync::waitqueue::WakerRegistration; |
| 6 | 6 | ||
| 7 | use crate::consts::Ioctl; | ||
| 7 | use crate::fmt::Bytes; | 8 | use crate::fmt::Bytes; |
| 8 | 9 | ||
| 9 | #[derive(Clone, Copy)] | 10 | #[derive(Clone, Copy, PartialEq, Eq)] |
| 10 | pub enum IoctlType { | 11 | pub enum IoctlType { |
| 11 | Get = 0, | 12 | Get = 0, |
| 12 | Set = 2, | 13 | Set = 2, |
| @@ -16,7 +17,7 @@ pub enum IoctlType { | |||
| 16 | pub struct PendingIoctl { | 17 | pub struct PendingIoctl { |
| 17 | pub buf: *mut [u8], | 18 | pub buf: *mut [u8], |
| 18 | pub kind: IoctlType, | 19 | pub kind: IoctlType, |
| 19 | pub cmd: u32, | 20 | pub cmd: Ioctl, |
| 20 | pub iface: u32, | 21 | pub iface: u32, |
| 21 | } | 22 | } |
| 22 | 23 | ||
| @@ -101,7 +102,7 @@ impl IoctlState { | |||
| 101 | self.state.set(IoctlStateInner::Done { resp_len: 0 }); | 102 | self.state.set(IoctlStateInner::Done { resp_len: 0 }); |
| 102 | } | 103 | } |
| 103 | 104 | ||
| 104 | pub async fn do_ioctl(&self, kind: IoctlType, cmd: u32, iface: u32, buf: &mut [u8]) -> usize { | 105 | pub async fn do_ioctl(&self, kind: IoctlType, cmd: Ioctl, iface: u32, buf: &mut [u8]) -> usize { |
| 105 | self.state | 106 | self.state |
| 106 | .set(IoctlStateInner::Pending(PendingIoctl { buf, kind, cmd, iface })); | 107 | .set(IoctlStateInner::Pending(PendingIoctl { buf, kind, cmd, iface })); |
| 107 | self.wake_runner(); | 108 | self.wake_runner(); |
diff --git a/cyw43/src/lib.rs b/cyw43/src/lib.rs index efeb3f313..6b71c18e6 100644 --- a/cyw43/src/lib.rs +++ b/cyw43/src/lib.rs | |||
| @@ -28,7 +28,9 @@ use ioctl::IoctlState; | |||
| 28 | 28 | ||
| 29 | use crate::bus::Bus; | 29 | use crate::bus::Bus; |
| 30 | pub use crate::bus::SpiBusCyw43; | 30 | pub use crate::bus::SpiBusCyw43; |
| 31 | pub use crate::control::{AddMulticastAddressError, Control, Error as ControlError, ScanOptions, Scanner}; | 31 | pub use crate::control::{ |
| 32 | AddMulticastAddressError, Control, Error as ControlError, JoinAuth, JoinOptions, ScanOptions, Scanner, | ||
| 33 | }; | ||
| 32 | pub use crate::runner::Runner; | 34 | pub use crate::runner::Runner; |
| 33 | pub use crate::structs::BssInfo; | 35 | pub use crate::structs::BssInfo; |
| 34 | 36 | ||
diff --git a/cyw43/src/runner.rs b/cyw43/src/runner.rs index 959718341..77910b281 100644 --- a/cyw43/src/runner.rs +++ b/cyw43/src/runner.rs | |||
| @@ -560,7 +560,7 @@ where | |||
| 560 | self.sdpcm_seq != self.sdpcm_seq_max && self.sdpcm_seq_max.wrapping_sub(self.sdpcm_seq) & 0x80 == 0 | 560 | self.sdpcm_seq != self.sdpcm_seq_max && self.sdpcm_seq_max.wrapping_sub(self.sdpcm_seq) & 0x80 == 0 |
| 561 | } | 561 | } |
| 562 | 562 | ||
| 563 | async fn send_ioctl(&mut self, kind: IoctlType, cmd: u32, iface: u32, data: &[u8], buf: &mut [u32; 512]) { | 563 | async fn send_ioctl(&mut self, kind: IoctlType, cmd: Ioctl, iface: u32, data: &[u8], buf: &mut [u32; 512]) { |
| 564 | let buf8 = slice8_mut(buf); | 564 | let buf8 = slice8_mut(buf); |
| 565 | 565 | ||
| 566 | let total_len = SdpcmHeader::SIZE + CdcHeader::SIZE + data.len(); | 566 | let total_len = SdpcmHeader::SIZE + CdcHeader::SIZE + data.len(); |
| @@ -582,7 +582,7 @@ where | |||
| 582 | }; | 582 | }; |
| 583 | 583 | ||
| 584 | let cdc_header = CdcHeader { | 584 | let cdc_header = CdcHeader { |
| 585 | cmd: cmd, | 585 | cmd: cmd as u32, |
| 586 | len: data.len() as _, | 586 | len: data.len() as _, |
| 587 | flags: kind as u16 | (iface as u16) << 12, | 587 | flags: kind as u16 | (iface as u16) << 12, |
| 588 | id: self.ioctl_id, | 588 | id: self.ioctl_id, |
diff --git a/cyw43/src/structs.rs b/cyw43/src/structs.rs index ae7ef6038..81ae6a98d 100644 --- a/cyw43/src/structs.rs +++ b/cyw43/src/structs.rs | |||
| @@ -397,6 +397,15 @@ impl_bytes!(PassphraseInfo); | |||
| 397 | #[derive(Clone, Copy)] | 397 | #[derive(Clone, Copy)] |
| 398 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 398 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 399 | #[repr(C)] | 399 | #[repr(C)] |
| 400 | pub struct SaePassphraseInfo { | ||
| 401 | pub len: u16, | ||
| 402 | pub passphrase: [u8; 128], | ||
| 403 | } | ||
| 404 | impl_bytes!(SaePassphraseInfo); | ||
| 405 | |||
| 406 | #[derive(Clone, Copy)] | ||
| 407 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 408 | #[repr(C)] | ||
| 400 | pub struct SsidInfoWithIndex { | 409 | pub struct SsidInfoWithIndex { |
| 401 | pub index: u32, | 410 | pub index: u32, |
| 402 | pub ssid_info: SsidInfo, | 411 | pub ssid_info: SsidInfo, |
diff --git a/examples/rp/src/bin/wifi_tcp_server.rs b/examples/rp/src/bin/wifi_tcp_server.rs index 61eeb82f7..b2950d98a 100644 --- a/examples/rp/src/bin/wifi_tcp_server.rs +++ b/examples/rp/src/bin/wifi_tcp_server.rs | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | 7 | ||
| 8 | use core::str::from_utf8; | 8 | use core::str::from_utf8; |
| 9 | 9 | ||
| 10 | use cyw43::JoinOptions; | ||
| 10 | use cyw43_pio::PioSpi; | 11 | use cyw43_pio::PioSpi; |
| 11 | use defmt::*; | 12 | use defmt::*; |
| 12 | use embassy_executor::Spawner; | 13 | use embassy_executor::Spawner; |
| @@ -95,8 +96,10 @@ async fn main(spawner: Spawner) { | |||
| 95 | unwrap!(spawner.spawn(net_task(stack))); | 96 | unwrap!(spawner.spawn(net_task(stack))); |
| 96 | 97 | ||
| 97 | loop { | 98 | loop { |
| 98 | //control.join_open(WIFI_NETWORK).await; | 99 | match control |
| 99 | match control.join_wpa2(WIFI_NETWORK, WIFI_PASSWORD).await { | 100 | .join(WIFI_NETWORK, JoinOptions::new(WIFI_PASSWORD.as_bytes())) |
| 101 | .await | ||
| 102 | { | ||
| 100 | Ok(_) => break, | 103 | Ok(_) => break, |
| 101 | Err(err) => { | 104 | Err(err) => { |
| 102 | info!("join failed with status={}", err.status); | 105 | info!("join failed with status={}", err.status); |
diff --git a/examples/rp/src/bin/wifi_webrequest.rs b/examples/rp/src/bin/wifi_webrequest.rs index 889371241..b43be8905 100644 --- a/examples/rp/src/bin/wifi_webrequest.rs +++ b/examples/rp/src/bin/wifi_webrequest.rs | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | 7 | ||
| 8 | use core::str::from_utf8; | 8 | use core::str::from_utf8; |
| 9 | 9 | ||
| 10 | use cyw43::JoinOptions; | ||
| 10 | use cyw43_pio::PioSpi; | 11 | use cyw43_pio::PioSpi; |
| 11 | use defmt::*; | 12 | use defmt::*; |
| 12 | use embassy_executor::Spawner; | 13 | use embassy_executor::Spawner; |
| @@ -98,8 +99,10 @@ async fn main(spawner: Spawner) { | |||
| 98 | unwrap!(spawner.spawn(net_task(stack))); | 99 | unwrap!(spawner.spawn(net_task(stack))); |
| 99 | 100 | ||
| 100 | loop { | 101 | loop { |
| 101 | //match control.join_open(WIFI_NETWORK).await { // for open networks | 102 | match control |
| 102 | match control.join_wpa2(WIFI_NETWORK, WIFI_PASSWORD).await { | 103 | .join(WIFI_NETWORK, JoinOptions::new(WIFI_PASSWORD.as_bytes())) |
| 104 | .await | ||
| 105 | { | ||
| 103 | Ok(_) => break, | 106 | Ok(_) => break, |
| 104 | Err(err) => { | 107 | Err(err) => { |
| 105 | info!("join failed with status={}", err.status); | 108 | info!("join failed with status={}", err.status); |
diff --git a/tests/rp/src/bin/cyw43-perf.rs b/tests/rp/src/bin/cyw43-perf.rs index 38fbde7c1..11c8aa58c 100644 --- a/tests/rp/src/bin/cyw43-perf.rs +++ b/tests/rp/src/bin/cyw43-perf.rs | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | #![no_main] | 2 | #![no_main] |
| 3 | teleprobe_meta::target!(b"rpi-pico"); | 3 | teleprobe_meta::target!(b"rpi-pico"); |
| 4 | 4 | ||
| 5 | use cyw43::JoinOptions; | ||
| 5 | use cyw43_pio::PioSpi; | 6 | use cyw43_pio::PioSpi; |
| 6 | use defmt::{panic, *}; | 7 | use defmt::{panic, *}; |
| 7 | use embassy_executor::Spawner; | 8 | use embassy_executor::Spawner; |
| @@ -81,7 +82,10 @@ async fn main(spawner: Spawner) { | |||
| 81 | unwrap!(spawner.spawn(net_task(stack))); | 82 | unwrap!(spawner.spawn(net_task(stack))); |
| 82 | 83 | ||
| 83 | loop { | 84 | loop { |
| 84 | match control.join_wpa2(WIFI_NETWORK, WIFI_PASSWORD).await { | 85 | match control |
| 86 | .join(WIFI_NETWORK, JoinOptions::new(WIFI_PASSWORD.as_bytes())) | ||
| 87 | .await | ||
| 88 | { | ||
| 85 | Ok(_) => break, | 89 | Ok(_) => break, |
| 86 | Err(err) => { | 90 | Err(err) => { |
| 87 | panic!("join failed with status={}", err.status); | 91 | panic!("join failed with status={}", err.status); |
