diff options
| author | Samuel Čavoj <[email protected]> | 2023-11-14 01:44:42 +0000 |
|---|---|---|
| committer | Samuel Čavoj <[email protected]> | 2023-11-16 00:05:13 +0000 |
| commit | e3ee24017d35834648ac07b2c6df446ee71a49bb (patch) | |
| tree | 4da89d3c679107bf86d553a4c29e587f047db162 /cyw43 | |
| parent | 467b53076c3251e12f6f91ae022be9655567385d (diff) | |
cyw43: Add Control method to add multicast HW address
Diffstat (limited to 'cyw43')
| -rw-r--r-- | cyw43/src/control.rs | 55 | ||||
| -rw-r--r-- | cyw43/src/lib.rs | 2 |
2 files changed, 56 insertions, 1 deletions
diff --git a/cyw43/src/control.rs b/cyw43/src/control.rs index ffcf2d9b1..826edfe1a 100644 --- a/cyw43/src/control.rs +++ b/cyw43/src/control.rs | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | use core::cmp::{max, min}; | 1 | use core::cmp::{max, min}; |
| 2 | use core::iter::zip; | ||
| 2 | 3 | ||
| 3 | use embassy_net_driver_channel as ch; | 4 | use embassy_net_driver_channel as ch; |
| 4 | use embassy_net_driver_channel::driver::{HardwareAddress, LinkState}; | 5 | use embassy_net_driver_channel::driver::{HardwareAddress, LinkState}; |
| @@ -16,6 +17,12 @@ pub struct Error { | |||
| 16 | pub status: u32, | 17 | pub status: u32, |
| 17 | } | 18 | } |
| 18 | 19 | ||
| 20 | #[derive(Debug)] | ||
| 21 | pub enum AddMulticastAddressError { | ||
| 22 | NotMulticast, | ||
| 23 | NoFreeSlots, | ||
| 24 | } | ||
| 25 | |||
| 19 | pub struct Control<'a> { | 26 | pub struct Control<'a> { |
| 20 | state_ch: ch::StateRunner<'a>, | 27 | state_ch: ch::StateRunner<'a>, |
| 21 | events: &'a Events, | 28 | events: &'a Events, |
| @@ -316,6 +323,54 @@ impl<'a> Control<'a> { | |||
| 316 | self.set_iovar_u32x2("bss", 0, 1).await; // bss = BSS_UP | 323 | self.set_iovar_u32x2("bss", 0, 1).await; // bss = BSS_UP |
| 317 | } | 324 | } |
| 318 | 325 | ||
| 326 | /// Add specified address to the list of hardware addresses the device | ||
| 327 | /// listens on. The address must be a Group address (I/G bit set). Up | ||
| 328 | /// to 10 addresses are supported by the firmware. Returns the number of | ||
| 329 | /// address slots filled after adding, or an error. | ||
| 330 | pub async fn add_multicast_address(&mut self, address: [u8; 6]) -> Result<usize, AddMulticastAddressError> { | ||
| 331 | // The firmware seems to ignore non-multicast addresses, so let's | ||
| 332 | // prevent the user from adding them and wasting space. | ||
| 333 | if address[0] & 0x01 != 1 { | ||
| 334 | return Err(AddMulticastAddressError::NotMulticast); | ||
| 335 | } | ||
| 336 | |||
| 337 | let mut buf = [0; 64]; | ||
| 338 | self.get_iovar("mcast_list", &mut buf).await; | ||
| 339 | |||
| 340 | let n = u32::from_le_bytes(buf[..4].try_into().unwrap()) as usize; | ||
| 341 | let (used, free) = buf[4..].split_at_mut(n * 6); | ||
| 342 | |||
| 343 | if used.chunks(6).any(|a| a == address) { | ||
| 344 | return Ok(n); | ||
| 345 | } | ||
| 346 | |||
| 347 | if free.len() < 6 { | ||
| 348 | return Err(AddMulticastAddressError::NoFreeSlots); | ||
| 349 | } | ||
| 350 | |||
| 351 | free[..6].copy_from_slice(&address); | ||
| 352 | let n = n + 1; | ||
| 353 | buf[..4].copy_from_slice(&(n as u32).to_le_bytes()); | ||
| 354 | |||
| 355 | self.set_iovar_v::<80>("mcast_list", &buf).await; | ||
| 356 | Ok(n) | ||
| 357 | } | ||
| 358 | |||
| 359 | /// Retrieve the list of configured multicast hardware addresses. | ||
| 360 | pub async fn list_mulistcast_addresses(&mut self, result: &mut [[u8; 6]; 10]) -> usize { | ||
| 361 | let mut buf = [0; 64]; | ||
| 362 | self.get_iovar("mcast_list", &mut buf).await; | ||
| 363 | |||
| 364 | let n = u32::from_le_bytes(buf[..4].try_into().unwrap()) as usize; | ||
| 365 | let used = &buf[4..][..n * 6]; | ||
| 366 | |||
| 367 | for (addr, output) in zip(used.chunks(6), result.iter_mut()) { | ||
| 368 | output.copy_from_slice(addr) | ||
| 369 | } | ||
| 370 | |||
| 371 | n | ||
| 372 | } | ||
| 373 | |||
| 319 | async fn set_iovar_u32x2(&mut self, name: &str, val1: u32, val2: u32) { | 374 | async fn set_iovar_u32x2(&mut self, name: &str, val1: u32, val2: u32) { |
| 320 | let mut buf = [0; 8]; | 375 | let mut buf = [0; 8]; |
| 321 | buf[0..4].copy_from_slice(&val1.to_le_bytes()); | 376 | buf[0..4].copy_from_slice(&val1.to_le_bytes()); |
diff --git a/cyw43/src/lib.rs b/cyw43/src/lib.rs index e60f87d0a..04847bfa5 100644 --- a/cyw43/src/lib.rs +++ b/cyw43/src/lib.rs | |||
| @@ -27,7 +27,7 @@ use ioctl::IoctlState; | |||
| 27 | 27 | ||
| 28 | use crate::bus::Bus; | 28 | use crate::bus::Bus; |
| 29 | pub use crate::bus::SpiBusCyw43; | 29 | pub use crate::bus::SpiBusCyw43; |
| 30 | pub use crate::control::{Control, Error as ControlError, Scanner}; | 30 | pub use crate::control::{AddMulticastAddressError, Control, Error as ControlError, Scanner}; |
| 31 | pub use crate::runner::Runner; | 31 | pub use crate::runner::Runner; |
| 32 | pub use crate::structs::BssInfo; | 32 | pub use crate::structs::BssInfo; |
| 33 | 33 | ||
