aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml1
-rw-r--r--examples/rpi-pico-w/Cargo.toml9
-rw-r--r--examples/rpi-pico-w/src/main.rs78
-rw-r--r--src/lib.rs168
-rw-r--r--src/structs.rs9
5 files changed, 255 insertions, 10 deletions
diff --git a/Cargo.toml b/Cargo.toml
index bd27a48b8..31a14f96f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -9,6 +9,7 @@ log = ["dep:log"]
9[dependencies] 9[dependencies]
10embassy = { version = "0.1.0" } 10embassy = { version = "0.1.0" }
11embassy-rp = { version = "0.1.0", features = ["unstable-traits", "nightly", "unstable-pac"] } 11embassy-rp = { version = "0.1.0", features = ["unstable-traits", "nightly", "unstable-pac"] }
12embassy-net = { version = "0.1.0" }
12atomic-polyfill = "0.1.5" 13atomic-polyfill = "0.1.5"
13 14
14defmt = { version = "0.3", optional = true } 15defmt = { version = "0.3", optional = true }
diff --git a/examples/rpi-pico-w/Cargo.toml b/examples/rpi-pico-w/Cargo.toml
index 8dbcb20d4..9e1d75470 100644
--- a/examples/rpi-pico-w/Cargo.toml
+++ b/examples/rpi-pico-w/Cargo.toml
@@ -8,6 +8,7 @@ edition = "2021"
8cyw43 = { path = "../../", features = ["defmt"]} 8cyw43 = { path = "../../", features = ["defmt"]}
9embassy = { version = "0.1.0", features = ["defmt", "defmt-timestamp-uptime"] } 9embassy = { version = "0.1.0", features = ["defmt", "defmt-timestamp-uptime"] }
10embassy-rp = { version = "0.1.0", features = ["defmt", "unstable-traits", "nightly", "unstable-pac"] } 10embassy-rp = { version = "0.1.0", features = ["defmt", "unstable-traits", "nightly", "unstable-pac"] }
11embassy-net = { version = "0.1.0", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "pool-16"] }
11atomic-polyfill = "0.1.5" 12atomic-polyfill = "0.1.5"
12 13
13defmt = "0.3" 14defmt = "0.3"
@@ -20,13 +21,21 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa
20 21
21embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.8" } 22embedded-hal-1 = { package = "embedded-hal", version = "1.0.0-alpha.8" }
22embedded-hal-async = { version = "0.1.0-alpha.1" } 23embedded-hal-async = { version = "0.1.0-alpha.1" }
24embedded-io = { version = "0.3.0", features = ["async", "defmt"] }
25heapless = "0.7.15"
23 26
24 27
25[patch.crates-io] 28[patch.crates-io]
26embassy = { git = "https://github.com/embassy-rs/embassy", rev = "5f43c1d37e9db847c7861fe0bd821db62edba9f6" } 29embassy = { git = "https://github.com/embassy-rs/embassy", rev = "5f43c1d37e9db847c7861fe0bd821db62edba9f6" }
27embassy-rp = { git = "https://github.com/embassy-rs/embassy", rev = "5f43c1d37e9db847c7861fe0bd821db62edba9f6" } 30embassy-rp = { git = "https://github.com/embassy-rs/embassy", rev = "5f43c1d37e9db847c7861fe0bd821db62edba9f6" }
31embassy-net = { git = "https://github.com/embassy-rs/embassy", rev = "5f43c1d37e9db847c7861fe0bd821db62edba9f6" }
28#embassy = { path = "/home/dirbaio/embassy/embassy/embassy" } 32#embassy = { path = "/home/dirbaio/embassy/embassy/embassy" }
29#embassy-rp = { path = "/home/dirbaio/embassy/embassy/embassy-rp" } 33#embassy-rp = { path = "/home/dirbaio/embassy/embassy/embassy-rp" }
34#embassy-net = { path = "/home/dirbaio/embassy/embassy/embassy-net" }
35#smoltcp = { path = "./smoltcp" }
36
37#[patch."https://github.com/smoltcp-rs/smoltcp"]
38#smoltcp = { path = "./smoltcp" }
30 39
31[profile.dev] 40[profile.dev]
32debug = 2 41debug = 2
diff --git a/examples/rpi-pico-w/src/main.rs b/examples/rpi-pico-w/src/main.rs
index 6d1614147..e08ee8e95 100644
--- a/examples/rpi-pico-w/src/main.rs
+++ b/examples/rpi-pico-w/src/main.rs
@@ -8,9 +8,13 @@ use defmt::{assert, assert_eq, panic, *};
8use embassy::executor::Spawner; 8use embassy::executor::Spawner;
9use embassy::time::{Duration, Timer}; 9use embassy::time::{Duration, Timer};
10use embassy::util::Forever; 10use embassy::util::Forever;
11use embassy_net::tcp::TcpSocket;
12use embassy_net::{Ipv4Address, Ipv4Cidr, Stack, StackResources};
11use embassy_rp::gpio::{Flex, Level, Output, Pin}; 13use embassy_rp::gpio::{Flex, Level, Output, Pin};
12use embassy_rp::peripherals::{PIN_23, PIN_24, PIN_25, PIN_29}; 14use embassy_rp::peripherals::{PIN_23, PIN_24, PIN_25, PIN_29};
13use embassy_rp::Peripherals; 15use embassy_rp::Peripherals;
16use embedded_io::asynch::{Read, Write};
17use heapless::Vec;
14use {defmt_rtt as _, panic_probe as _}; 18use {defmt_rtt as _, panic_probe as _};
15 19
16macro_rules! forever { 20macro_rules! forever {
@@ -26,6 +30,11 @@ async fn wifi_task(runner: cyw43::Runner<'static, PIN_23, PIN_25, PIN_29, PIN_24
26 runner.run().await 30 runner.run().await
27} 31}
28 32
33#[embassy::task]
34async fn net_task(stack: &'static Stack<cyw43::NetDevice<'static>>) -> ! {
35 stack.run().await
36}
37
29#[embassy::main] 38#[embassy::main]
30async fn main(spawner: Spawner, p: Peripherals) { 39async fn main(spawner: Spawner, p: Peripherals) {
31 info!("Hello World!"); 40 info!("Hello World!");
@@ -45,8 +54,71 @@ async fn main(spawner: Spawner, p: Peripherals) {
45 54
46 spawner.spawn(wifi_task(runner)).unwrap(); 55 spawner.spawn(wifi_task(runner)).unwrap();
47 56
48 control.init().await; 57 let net_device = control.init().await;
58
59 control.join_open("MikroTik-951589").await;
60 //control.join_wpa2("MikroTik-951589", "asdfasdfasdfasdf").await;
61
62 let config = embassy_net::ConfigStrategy::Dhcp;
63 //let config = embassy_net::ConfigStrategy::Static(embassy_net::Config {
64 // address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 69, 2), 24),
65 // dns_servers: Vec::new(),
66 // gateway: Some(Ipv4Address::new(192, 168, 69, 1)),
67 //});
68
69 // Generate random seed
70 let seed = 0x0123_4567_89ab_cdef; // chosen by fair dice roll. guarenteed to be random.
71
72 // Init network stack
73 let stack = &*forever!(Stack::new(
74 net_device,
75 config,
76 forever!(StackResources::<1, 2, 8>::new()),
77 seed
78 ));
79
80 unwrap!(spawner.spawn(net_task(stack)));
81
82 // And now we can use it!
83
84 let mut rx_buffer = [0; 4096];
85 let mut tx_buffer = [0; 4096];
86 let mut buf = [0; 4096];
87
88 loop {
89 let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
90 socket.set_timeout(Some(embassy_net::SmolDuration::from_secs(10)));
91
92 info!("Listening on TCP:1234...");
93 if let Err(e) = socket.accept(1234).await {
94 warn!("accept error: {:?}", e);
95 continue;
96 }
97
98 info!("Received connection from {:?}", socket.remote_endpoint());
99
100 loop {
101 let n = match socket.read(&mut buf).await {
102 Ok(0) => {
103 warn!("read EOF");
104 break;
105 }
106 Ok(n) => n,
107 Err(e) => {
108 warn!("read error: {:?}", e);
109 break;
110 }
111 };
112
113 info!("rxd {:02x}", &buf[..n]);
49 114
50 //control.join_open("MikroTik-951589").await; 115 match socket.write_all(&buf[..n]).await {
51 control.join_wpa2("MikroTik-951589", "fasdfasdfasdf").await; 116 Ok(()) => {}
117 Err(e) => {
118 warn!("write error: {:?}", e);
119 break;
120 }
121 };
122 }
123 }
52} 124}
diff --git a/src/lib.rs b/src/lib.rs
index e0c2c9312..dde9d9c34 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -12,12 +12,19 @@ mod structs;
12 12
13use core::cell::Cell; 13use core::cell::Cell;
14use core::slice; 14use core::slice;
15use core::sync::atomic::Ordering;
16use core::task::Waker;
15 17
18use atomic_polyfill::AtomicBool;
19use embassy::blocking_mutex::raw::NoopRawMutex;
20use embassy::channel::mpmc::Channel;
16use embassy::time::{block_for, Duration, Timer}; 21use embassy::time::{block_for, Duration, Timer};
17use embassy::util::yield_now; 22use embassy::util::yield_now;
23use embassy_net::{PacketBoxExt, PacketBuf};
18use embassy_rp::gpio::{Flex, Output, Pin}; 24use embassy_rp::gpio::{Flex, Output, Pin};
19 25
20use self::structs::*; 26use self::structs::*;
27use crate::events::Event;
21 28
22fn swap16(x: u32) -> u32 { 29fn swap16(x: u32) -> u32 {
23 (x & 0xFF00FF00) >> 8 | (x & 0x00FF00FF) << 8 30 (x & 0xFF00FF00) >> 8 | (x & 0x00FF00FF) << 8
@@ -197,6 +204,10 @@ enum IoctlState {
197pub struct State { 204pub struct State {
198 ioctl_id: Cell<u16>, 205 ioctl_id: Cell<u16>,
199 ioctl_state: Cell<IoctlState>, 206 ioctl_state: Cell<IoctlState>,
207
208 tx_channel: Channel<NoopRawMutex, PacketBuf, 8>,
209 rx_channel: Channel<NoopRawMutex, PacketBuf, 8>,
210 link_up: AtomicBool,
200} 211}
201 212
202impl State { 213impl State {
@@ -204,6 +215,10 @@ impl State {
204 Self { 215 Self {
205 ioctl_id: Cell::new(0), 216 ioctl_id: Cell::new(0),
206 ioctl_state: Cell::new(IoctlState::Idle), 217 ioctl_state: Cell::new(IoctlState::Idle),
218
219 tx_channel: Channel::new(),
220 rx_channel: Channel::new(),
221 link_up: AtomicBool::new(true), // TODO set up/down as we join/deassociate
207 } 222 }
208 } 223 }
209} 224}
@@ -213,7 +228,7 @@ pub struct Control<'a> {
213} 228}
214 229
215impl<'a> Control<'a> { 230impl<'a> Control<'a> {
216 pub async fn init(&mut self) { 231 pub async fn init(&mut self) -> NetDevice<'a> {
217 const CHUNK_SIZE: usize = 1024; 232 const CHUNK_SIZE: usize = 1024;
218 233
219 let clm = unsafe { slice::from_raw_parts(0x10140000 as *const u8, 4752) }; 234 let clm = unsafe { slice::from_raw_parts(0x10140000 as *const u8, 4752) };
@@ -253,6 +268,15 @@ impl<'a> Control<'a> {
253 self.set_iovar_u32("apsta", 1).await; 268 self.set_iovar_u32("apsta", 1).await;
254 //self.set_iovar("cur_etheraddr", &[02, 03, 04, 05, 06, 07]).await; 269 //self.set_iovar("cur_etheraddr", &[02, 03, 04, 05, 06, 07]).await;
255 270
271 // read MAC addr.
272 let mut mac_addr = [0; 6];
273 assert_eq!(self.get_iovar("cur_etheraddr", &mut mac_addr).await, 6);
274 info!("mac addr: {:02x}", mac_addr);
275
276 // TODO get_iovar is broken, it returns all zeros.
277 // Harcdode our own MAC for now.
278 let mac_addr = [0x28, 0xCD, 0xC1, 0x00, 0x3F, 0x05];
279
256 let country = countries::WORLD_WIDE_XX; 280 let country = countries::WORLD_WIDE_XX;
257 let country_info = CountryInfo { 281 let country_info = CountryInfo {
258 country_abbrev: [country.code[0], country.code[1], 0, 0], 282 country_abbrev: [country.code[0], country.code[1], 0, 0],
@@ -283,6 +307,15 @@ impl<'a> Control<'a> {
283 iface: 0, 307 iface: 0,
284 events: [0xFF; 24], 308 events: [0xFF; 24],
285 }; 309 };
310
311 // Disable spammy uninteresting events.
312 evts.unset(Event::RADIO);
313 evts.unset(Event::IF);
314 evts.unset(Event::PROBREQ_MSG);
315 evts.unset(Event::PROBREQ_MSG_RX);
316 evts.unset(Event::PROBRESP_MSG);
317 evts.unset(Event::PROBRESP_MSG);
318
286 self.set_iovar("bsscfg:event_msgs", &evts.to_bytes()).await; 319 self.set_iovar("bsscfg:event_msgs", &evts.to_bytes()).await;
287 320
288 Timer::after(Duration::from_millis(100)).await; 321 Timer::after(Duration::from_millis(100)).await;
@@ -305,6 +338,11 @@ impl<'a> Control<'a> {
305 Timer::after(Duration::from_millis(100)).await; 338 Timer::after(Duration::from_millis(100)).await;
306 339
307 info!("INIT DONE"); 340 info!("INIT DONE");
341
342 NetDevice {
343 state: self.state,
344 mac_addr,
345 }
308 } 346 }
309 347
310 pub async fn join_open(&mut self, ssid: &str) { 348 pub async fn join_open(&mut self, ssid: &str) {
@@ -387,6 +425,7 @@ impl<'a> Control<'a> {
387 self.ioctl(2, 263, 0, &mut buf).await; 425 self.ioctl(2, 263, 0, &mut buf).await;
388 } 426 }
389 427
428 // TODO this is not really working, it always returns all zeros.
390 async fn get_iovar(&mut self, name: &str, res: &mut [u8]) -> usize { 429 async fn get_iovar(&mut self, name: &str, res: &mut [u8]) -> usize {
391 info!("get {}", name); 430 info!("get {}", name);
392 431
@@ -395,7 +434,7 @@ impl<'a> Control<'a> {
395 buf[name.len()] = 0; 434 buf[name.len()] = 0;
396 435
397 let total_len = name.len() + 1 + res.len(); 436 let total_len = name.len() + 1 + res.len();
398 let res_len = self.ioctl(2, 262, 0, &mut buf[..total_len]).await - name.len() - 1; 437 let res_len = self.ioctl(0, 262, 0, &mut buf[..total_len]).await - name.len() - 1;
399 res[..res_len].copy_from_slice(&buf[name.len() + 1..][..res_len]); 438 res[..res_len].copy_from_slice(&buf[name.len() + 1..][..res_len]);
400 res_len 439 res_len
401 } 440 }
@@ -408,9 +447,6 @@ impl<'a> Control<'a> {
408 async fn ioctl(&mut self, kind: u32, cmd: u32, iface: u32, buf: &mut [u8]) -> usize { 447 async fn ioctl(&mut self, kind: u32, cmd: u32, iface: u32, buf: &mut [u8]) -> usize {
409 // TODO cancel ioctl on future drop. 448 // TODO cancel ioctl on future drop.
410 449
411 // snail mode 🐌
412 Timer::after(Duration::from_millis(100)).await;
413
414 while !matches!(self.state.ioctl_state.get(), IoctlState::Idle) { 450 while !matches!(self.state.ioctl_state.get(), IoctlState::Idle) {
415 yield_now().await; 451 yield_now().await;
416 } 452 }
@@ -434,6 +470,50 @@ impl<'a> Control<'a> {
434 } 470 }
435} 471}
436 472
473pub struct NetDevice<'a> {
474 state: &'a State,
475 mac_addr: [u8; 6],
476}
477
478impl<'a> embassy_net::Device for NetDevice<'a> {
479 fn register_waker(&mut self, waker: &Waker) {
480 // loopy loopy wakey wakey
481 waker.wake_by_ref()
482 }
483
484 fn link_state(&mut self) -> embassy_net::LinkState {
485 match self.state.link_up.load(Ordering::Relaxed) {
486 true => embassy_net::LinkState::Up,
487 false => embassy_net::LinkState::Down,
488 }
489 }
490
491 fn capabilities(&self) -> embassy_net::DeviceCapabilities {
492 let mut caps = embassy_net::DeviceCapabilities::default();
493 caps.max_transmission_unit = 1514; // 1500 IP + 14 ethernet header
494 caps.medium = embassy_net::Medium::Ethernet;
495 caps
496 }
497
498 fn is_transmit_ready(&mut self) -> bool {
499 true
500 }
501
502 fn transmit(&mut self, pkt: PacketBuf) {
503 if self.state.tx_channel.try_send(pkt).is_err() {
504 warn!("TX failed")
505 }
506 }
507
508 fn receive(&mut self) -> Option<PacketBuf> {
509 self.state.rx_channel.try_recv().ok()
510 }
511
512 fn ethernet_address(&self) -> [u8; 6] {
513 self.mac_addr
514 }
515}
516
437pub struct Runner<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> { 517pub struct Runner<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> {
438 state: &'a State, 518 state: &'a State,
439 519
@@ -576,7 +656,10 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> {
576 while self.read32(FUNC_BUS, REG_BUS_STATUS) & STATUS_F2_RX_READY == 0 {} 656 while self.read32(FUNC_BUS, REG_BUS_STATUS) & STATUS_F2_RX_READY == 0 {}
577 657
578 // Some random configs related to sleep. 658 // Some random configs related to sleep.
579 // I think they're not needed if we don't want sleep...??? 659 // These aren't needed if we don't want to sleep the bus.
660 // TODO do we need to sleep the bus to read the irq line, due to
661 // being on the same pin as MOSI/MISO?
662
580 /* 663 /*
581 let mut val = self.read8(FUNC_BACKPLANE, REG_BACKPLANE_WAKEUP_CTRL); 664 let mut val = self.read8(FUNC_BACKPLANE, REG_BACKPLANE_WAKEUP_CTRL);
582 val |= 0x02; // WAKE_TILL_HT_AVAIL 665 val |= 0x02; // WAKE_TILL_HT_AVAIL
@@ -606,11 +689,16 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> {
606 let mut buf = [0; 2048]; 689 let mut buf = [0; 2048];
607 loop { 690 loop {
608 // Send stuff 691 // Send stuff
692 // TODO flow control
609 if let IoctlState::Pending { kind, cmd, iface, buf } = self.state.ioctl_state.get() { 693 if let IoctlState::Pending { kind, cmd, iface, buf } = self.state.ioctl_state.get() {
610 self.send_ioctl(kind, cmd, iface, unsafe { &*buf }, self.state.ioctl_id.get()); 694 self.send_ioctl(kind, cmd, iface, unsafe { &*buf }, self.state.ioctl_id.get());
611 self.state.ioctl_state.set(IoctlState::Sent { buf }); 695 self.state.ioctl_state.set(IoctlState::Sent { buf });
612 } 696 }
613 697
698 if let Ok(p) = self.state.tx_channel.try_recv() {
699 self.send_packet(&p);
700 }
701
614 // Receive stuff 702 // Receive stuff
615 let irq = self.read16(FUNC_BUS, REG_BUS_INTERRUPT); 703 let irq = self.read16(FUNC_BUS, REG_BUS_INTERRUPT);
616 704
@@ -646,6 +734,52 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> {
646 } 734 }
647 } 735 }
648 736
737 fn send_packet(&mut self, packet: &[u8]) {
738 trace!("tx pkt {:02x}", &packet[..packet.len().min(48)]);
739
740 let mut buf = [0; 2048];
741
742 let total_len = SdpcmHeader::SIZE + BcdHeader::SIZE + packet.len();
743
744 let seq = self.ioctl_seq;
745 self.ioctl_seq = self.ioctl_seq.wrapping_add(1);
746
747 let sdpcm_header = SdpcmHeader {
748 len: total_len as u16, // TODO does this len need to be rounded up to u32?
749 len_inv: !total_len as u16,
750 sequence: seq,
751 channel_and_flags: 2, // data channel
752 next_length: 0,
753 header_length: SdpcmHeader::SIZE as _,
754 wireless_flow_control: 0,
755 bus_data_credit: 0,
756 reserved: [0, 0],
757 };
758
759 let bcd_header = BcdHeader {
760 flags: 0x20,
761 priority: 0,
762 flags2: 0,
763 data_offset: 0,
764 };
765 trace!("tx {:?}", sdpcm_header);
766 trace!(" {:?}", bcd_header);
767
768 buf[0..SdpcmHeader::SIZE].copy_from_slice(&sdpcm_header.to_bytes());
769 buf[SdpcmHeader::SIZE..][..BcdHeader::SIZE].copy_from_slice(&bcd_header.to_bytes());
770 buf[SdpcmHeader::SIZE + BcdHeader::SIZE..][..packet.len()].copy_from_slice(packet);
771
772 let total_len = (total_len + 3) & !3; // round up to 4byte
773
774 trace!(" {:02x}", &buf[..total_len.min(48)]);
775
776 let cmd = cmd_word(true, true, FUNC_WLAN, 0, total_len as _);
777 self.cs.set_low();
778 self.spi_write(&cmd.to_le_bytes());
779 self.spi_write(&buf[..total_len]);
780 self.cs.set_high();
781 }
782
649 fn rx(&mut self, packet: &[u8]) { 783 fn rx(&mut self, packet: &[u8]) {
650 if packet.len() < SdpcmHeader::SIZE { 784 if packet.len() < SdpcmHeader::SIZE {
651 warn!("packet too short, len={}", packet.len()); 785 warn!("packet too short, len={}", packet.len());
@@ -683,6 +817,8 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> {
683 assert_eq!(cdc_header.status, 0); // todo propagate error instead 817 assert_eq!(cdc_header.status, 0); // todo propagate error instead
684 818
685 let resp_len = cdc_header.len as usize; 819 let resp_len = cdc_header.len as usize;
820 info!("IOCTL Response: {:02x}", &payload[CdcHeader::SIZE..][..resp_len]);
821
686 (unsafe { &mut *buf }[..resp_len]).copy_from_slice(&payload[CdcHeader::SIZE..][..resp_len]); 822 (unsafe { &mut *buf }[..resp_len]).copy_from_slice(&payload[CdcHeader::SIZE..][..resp_len]);
687 self.state.ioctl_state.set(IoctlState::Done { resp_len }); 823 self.state.ioctl_state.set(IoctlState::Done { resp_len });
688 } 824 }
@@ -703,14 +839,32 @@ impl<'a, PWR: Pin, CS: Pin, CLK: Pin, DIO: Pin> Runner<'a, PWR, CS, CLK, DIO> {
703 let mut evt = EventHeader::from_bytes(&packet[24..][..EventHeader::SIZE].try_into().unwrap()); 839 let mut evt = EventHeader::from_bytes(&packet[24..][..EventHeader::SIZE].try_into().unwrap());
704 evt.byteswap(); 840 evt.byteswap();
705 let evt_data = &packet[24 + EventHeader::SIZE..][..evt.datalen as usize]; 841 let evt_data = &packet[24 + EventHeader::SIZE..][..evt.datalen as usize];
706 info!( 842 debug!(
707 "=== EVENT {}: {} {:02x}", 843 "=== EVENT {}: {} {:02x}",
708 events::Event::from(evt.event_type as u8), 844 events::Event::from(evt.event_type as u8),
709 evt, 845 evt,
710 evt_data 846 evt_data
711 ); 847 );
712 } 848 }
849 2 => {
850 let bcd_header = BcdHeader::from_bytes(&payload[..BcdHeader::SIZE].try_into().unwrap());
851 trace!(" {:?}", bcd_header);
713 852
853 let packet_start = BcdHeader::SIZE + 4 * bcd_header.data_offset as usize;
854 if packet_start > payload.len() {
855 warn!("packet start out of range.");
856 return;
857 }
858 let packet = &payload[packet_start..];
859 trace!("rx pkt {:02x}", &packet[..(packet.len() as usize).min(48)]);
860
861 let mut p = unwrap!(embassy_net::PacketBox::new(embassy_net::Packet::new()));
862 p[..packet.len()].copy_from_slice(packet);
863
864 if let Err(_) = self.state.rx_channel.try_send(p.slice(0..packet.len())) {
865 warn!("failed to push rxd packet to the channel.")
866 }
867 }
714 _ => {} 868 _ => {}
715 } 869 }
716 } 870 }
diff --git a/src/structs.rs b/src/structs.rs
index dd2c0cfe9..060c2b060 100644
--- a/src/structs.rs
+++ b/src/structs.rs
@@ -1,3 +1,5 @@
1use crate::events::Event;
2
1macro_rules! impl_bytes { 3macro_rules! impl_bytes {
2 ($t:ident) => { 4 ($t:ident) => {
3 impl $t { 5 impl $t {
@@ -157,3 +159,10 @@ pub struct EventMask {
157 pub events: [u8; 24], 159 pub events: [u8; 24],
158} 160}
159impl_bytes!(EventMask); 161impl_bytes!(EventMask);
162
163impl EventMask {
164 pub fn unset(&mut self, evt: Event) {
165 let evt = evt as u8 as usize;
166 self.events[evt / 8] &= !(1 << (evt % 8));
167 }
168}