diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/events.rs | 1 | ||||
| -rw-r--r-- | src/lib.rs | 53 | ||||
| -rw-r--r-- | src/structs.rs | 56 |
3 files changed, 99 insertions, 11 deletions
diff --git a/src/events.rs b/src/events.rs index b35b12faa..a828eec98 100644 --- a/src/events.rs +++ b/src/events.rs | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | #![allow(unused)] | 1 | #![allow(unused)] |
| 2 | #![allow(non_camel_case_types)] | ||
| 2 | 3 | ||
| 3 | use core::num; | 4 | use core::num; |
| 4 | 5 | ||
diff --git a/src/lib.rs b/src/lib.rs index 133ce3161..3d08370c7 100644 --- a/src/lib.rs +++ b/src/lib.rs | |||
| @@ -815,20 +815,55 @@ where | |||
| 815 | trace!(" {:?}", bcd_header); | 815 | trace!(" {:?}", bcd_header); |
| 816 | 816 | ||
| 817 | let packet_start = BcdHeader::SIZE + 4 * bcd_header.data_offset as usize; | 817 | let packet_start = BcdHeader::SIZE + 4 * bcd_header.data_offset as usize; |
| 818 | if packet_start > payload.len() { | 818 | |
| 819 | warn!("packet start out of range."); | 819 | if packet_start + EventPacket::SIZE > payload.len() { |
| 820 | warn!("BCD event, incomplete header"); | ||
| 821 | return; | ||
| 822 | } | ||
| 823 | let bcd_packet = &payload[packet_start..]; | ||
| 824 | trace!(" {:02x}", &bcd_packet[..(bcd_packet.len() as usize).min(36)]); | ||
| 825 | |||
| 826 | let mut event_packet = EventPacket::from_bytes(&bcd_packet[..EventPacket::SIZE].try_into().unwrap()); | ||
| 827 | event_packet.byteswap(); | ||
| 828 | |||
| 829 | const ETH_P_LINK_CTL: u16 = 0x886c; // HPNA, wlan link local tunnel, according to linux if_ether.h | ||
| 830 | if event_packet.eth.ether_type != ETH_P_LINK_CTL { | ||
| 831 | warn!( | ||
| 832 | "unexpected ethernet type 0x{:04x}, expected Broadcom ether type 0x{:04x}", | ||
| 833 | event_packet.eth.ether_type, ETH_P_LINK_CTL | ||
| 834 | ); | ||
| 835 | return; | ||
| 836 | } | ||
| 837 | const BROADCOM_OUI: &[u8] = &[0x00, 0x10, 0x18]; | ||
| 838 | if event_packet.hdr.oui != BROADCOM_OUI { | ||
| 839 | warn!( | ||
| 840 | "unexpected ethernet OUI {:02x}, expected Broadcom OUI {:02x}", | ||
| 841 | event_packet.hdr.oui, BROADCOM_OUI | ||
| 842 | ); | ||
| 843 | return; | ||
| 844 | } | ||
| 845 | const BCMILCP_SUBTYPE_VENDOR_LONG: u16 = 32769; | ||
| 846 | if event_packet.hdr.subtype != BCMILCP_SUBTYPE_VENDOR_LONG { | ||
| 847 | warn!("unexpected subtype {}", event_packet.hdr.subtype); | ||
| 848 | return; | ||
| 849 | } | ||
| 850 | |||
| 851 | const BCMILCP_BCM_SUBTYPE_EVENT: u16 = 1; | ||
| 852 | if event_packet.hdr.user_subtype != BCMILCP_BCM_SUBTYPE_EVENT { | ||
| 853 | warn!("unexpected user_subtype {}", event_packet.hdr.subtype); | ||
| 854 | return; | ||
| 855 | } | ||
| 856 | |||
| 857 | if event_packet.msg.datalen as usize >= (bcd_packet.len() - EventMessage::SIZE) { | ||
| 858 | warn!("BCD event, incomplete data"); | ||
| 820 | return; | 859 | return; |
| 821 | } | 860 | } |
| 822 | let packet = &payload[packet_start..]; | ||
| 823 | trace!(" {:02x}", &packet[..(packet.len() as usize).min(36)]); | ||
| 824 | 861 | ||
| 825 | let mut evt = EventHeader::from_bytes(&packet[24..][..EventHeader::SIZE].try_into().unwrap()); | 862 | let evt_data = &bcd_packet[EventMessage::SIZE..][..event_packet.msg.datalen as usize]; |
| 826 | evt.byteswap(); | ||
| 827 | let evt_data = &packet[24 + EventHeader::SIZE..][..evt.datalen as usize]; | ||
| 828 | debug!( | 863 | debug!( |
| 829 | "=== EVENT {}: {} {:02x}", | 864 | "=== EVENT {}: {} {:02x}", |
| 830 | events::Event::from(evt.event_type as u8), | 865 | events::Event::from(event_packet.msg.event_type as u8), |
| 831 | evt, | 866 | event_packet.msg, |
| 832 | evt_data | 867 | evt_data |
| 833 | ); | 868 | ); |
| 834 | } | 869 | } |
diff --git a/src/structs.rs b/src/structs.rs index 060c2b060..7a7c25b26 100644 --- a/src/structs.rs +++ b/src/structs.rs | |||
| @@ -67,7 +67,41 @@ impl_bytes!(BcdHeader); | |||
| 67 | #[derive(Clone, Copy)] | 67 | #[derive(Clone, Copy)] |
| 68 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 68 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 69 | #[repr(C)] | 69 | #[repr(C)] |
| 70 | pub struct EthernetHeader { | ||
| 71 | pub destination_mac: [u8; 6], | ||
| 72 | pub source_mac: [u8; 6], | ||
| 73 | pub ether_type: u16, | ||
| 74 | } | ||
| 75 | |||
| 76 | impl EthernetHeader { | ||
| 77 | pub fn byteswap(&mut self) { | ||
| 78 | self.ether_type = self.ether_type.to_be(); | ||
| 79 | } | ||
| 80 | } | ||
| 81 | |||
| 82 | #[derive(Clone, Copy)] | ||
| 83 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 84 | #[repr(C)] | ||
| 70 | pub struct EventHeader { | 85 | pub struct EventHeader { |
| 86 | pub subtype: u16, | ||
| 87 | pub length: u16, | ||
| 88 | pub version: u8, | ||
| 89 | pub oui: [u8; 3], | ||
| 90 | pub user_subtype: u16, | ||
| 91 | } | ||
| 92 | |||
| 93 | impl EventHeader { | ||
| 94 | pub fn byteswap(&mut self) { | ||
| 95 | self.subtype = self.subtype.to_be(); | ||
| 96 | self.length = self.length.to_be(); | ||
| 97 | self.user_subtype = self.user_subtype.to_be(); | ||
| 98 | } | ||
| 99 | } | ||
| 100 | |||
| 101 | #[derive(Clone, Copy)] | ||
| 102 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 103 | #[repr(C)] | ||
| 104 | pub struct EventMessage { | ||
| 71 | /// version | 105 | /// version |
| 72 | pub version: u16, | 106 | pub version: u16, |
| 73 | /// see flags below | 107 | /// see flags below |
| @@ -91,9 +125,9 @@ pub struct EventHeader { | |||
| 91 | /// source bsscfg index | 125 | /// source bsscfg index |
| 92 | pub bsscfgidx: u8, | 126 | pub bsscfgidx: u8, |
| 93 | } | 127 | } |
| 94 | impl_bytes!(EventHeader); | 128 | impl_bytes!(EventMessage); |
| 95 | 129 | ||
| 96 | impl EventHeader { | 130 | impl EventMessage { |
| 97 | pub fn byteswap(&mut self) { | 131 | pub fn byteswap(&mut self) { |
| 98 | self.version = self.version.to_be(); | 132 | self.version = self.version.to_be(); |
| 99 | self.flags = self.flags.to_be(); | 133 | self.flags = self.flags.to_be(); |
| @@ -106,6 +140,24 @@ impl EventHeader { | |||
| 106 | } | 140 | } |
| 107 | 141 | ||
| 108 | #[derive(Clone, Copy)] | 142 | #[derive(Clone, Copy)] |
| 143 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 144 | #[repr(C)] | ||
| 145 | pub struct EventPacket { | ||
| 146 | pub eth: EthernetHeader, | ||
| 147 | pub hdr: EventHeader, | ||
| 148 | pub msg: EventMessage, | ||
| 149 | } | ||
| 150 | impl_bytes!(EventPacket); | ||
| 151 | |||
| 152 | impl EventPacket { | ||
| 153 | pub fn byteswap(&mut self) { | ||
| 154 | self.eth.byteswap(); | ||
| 155 | self.hdr.byteswap(); | ||
| 156 | self.msg.byteswap(); | ||
| 157 | } | ||
| 158 | } | ||
| 159 | |||
| 160 | #[derive(Clone, Copy)] | ||
| 109 | #[repr(C)] | 161 | #[repr(C)] |
| 110 | pub struct DownloadHeader { | 162 | pub struct DownloadHeader { |
| 111 | pub flag: u16, // | 163 | pub flag: u16, // |
