aboutsummaryrefslogtreecommitdiff
path: root/cyw43
diff options
context:
space:
mode:
authorSamuel Čavoj <[email protected]>2023-11-14 01:44:42 +0000
committerSamuel Čavoj <[email protected]>2023-11-16 00:05:13 +0000
commite3ee24017d35834648ac07b2c6df446ee71a49bb (patch)
tree4da89d3c679107bf86d553a4c29e587f047db162 /cyw43
parent467b53076c3251e12f6f91ae022be9655567385d (diff)
cyw43: Add Control method to add multicast HW address
Diffstat (limited to 'cyw43')
-rw-r--r--cyw43/src/control.rs55
-rw-r--r--cyw43/src/lib.rs2
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 @@
1use core::cmp::{max, min}; 1use core::cmp::{max, min};
2use core::iter::zip;
2 3
3use embassy_net_driver_channel as ch; 4use embassy_net_driver_channel as ch;
4use embassy_net_driver_channel::driver::{HardwareAddress, LinkState}; 5use 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)]
21pub enum AddMulticastAddressError {
22 NotMulticast,
23 NoFreeSlots,
24}
25
19pub struct Control<'a> { 26pub 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
28use crate::bus::Bus; 28use crate::bus::Bus;
29pub use crate::bus::SpiBusCyw43; 29pub use crate::bus::SpiBusCyw43;
30pub use crate::control::{Control, Error as ControlError, Scanner}; 30pub use crate::control::{AddMulticastAddressError, Control, Error as ControlError, Scanner};
31pub use crate::runner::Runner; 31pub use crate::runner::Runner;
32pub use crate::structs::BssInfo; 32pub use crate::structs::BssInfo;
33 33