diff options
Diffstat (limited to 'src/structs.rs')
| -rw-r--r-- | src/structs.rs | 149 |
1 files changed, 142 insertions, 7 deletions
diff --git a/src/structs.rs b/src/structs.rs index e16808f30..6d5d31b06 100644 --- a/src/structs.rs +++ b/src/structs.rs | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | use crate::events::Event; | 1 | use crate::events::Event; |
| 2 | use crate::fmt::Bytes; | ||
| 2 | 3 | ||
| 3 | macro_rules! impl_bytes { | 4 | macro_rules! impl_bytes { |
| 4 | ($t:ident) => { | 5 | ($t:ident) => { |
| @@ -11,8 +12,28 @@ macro_rules! impl_bytes { | |||
| 11 | } | 12 | } |
| 12 | 13 | ||
| 13 | #[allow(unused)] | 14 | #[allow(unused)] |
| 14 | pub fn from_bytes(bytes: &[u8; Self::SIZE]) -> Self { | 15 | pub fn from_bytes(bytes: &[u8; Self::SIZE]) -> &Self { |
| 15 | unsafe { core::mem::transmute(*bytes) } | 16 | let alignment = core::mem::align_of::<Self>(); |
| 17 | assert_eq!( | ||
| 18 | bytes.as_ptr().align_offset(alignment), | ||
| 19 | 0, | ||
| 20 | "{} is not aligned", | ||
| 21 | core::any::type_name::<Self>() | ||
| 22 | ); | ||
| 23 | unsafe { core::mem::transmute(bytes) } | ||
| 24 | } | ||
| 25 | |||
| 26 | #[allow(unused)] | ||
| 27 | pub fn from_bytes_mut(bytes: &mut [u8; Self::SIZE]) -> &mut Self { | ||
| 28 | let alignment = core::mem::align_of::<Self>(); | ||
| 29 | assert_eq!( | ||
| 30 | bytes.as_ptr().align_offset(alignment), | ||
| 31 | 0, | ||
| 32 | "{} is not aligned", | ||
| 33 | core::any::type_name::<Self>() | ||
| 34 | ); | ||
| 35 | |||
| 36 | unsafe { core::mem::transmute(bytes) } | ||
| 16 | } | 37 | } |
| 17 | } | 38 | } |
| 18 | }; | 39 | }; |
| @@ -67,9 +88,35 @@ pub struct SdpcmHeader { | |||
| 67 | } | 88 | } |
| 68 | impl_bytes!(SdpcmHeader); | 89 | impl_bytes!(SdpcmHeader); |
| 69 | 90 | ||
| 91 | impl SdpcmHeader { | ||
| 92 | pub fn parse(packet: &mut [u8]) -> Option<(&mut Self, &mut [u8])> { | ||
| 93 | let packet_len = packet.len(); | ||
| 94 | if packet_len < Self::SIZE { | ||
| 95 | warn!("packet too short, len={}", packet.len()); | ||
| 96 | return None; | ||
| 97 | } | ||
| 98 | let (sdpcm_header, sdpcm_packet) = packet.split_at_mut(Self::SIZE); | ||
| 99 | let sdpcm_header = Self::from_bytes_mut(sdpcm_header.try_into().unwrap()); | ||
| 100 | trace!("rx {:?}", sdpcm_header); | ||
| 101 | |||
| 102 | if sdpcm_header.len != !sdpcm_header.len_inv { | ||
| 103 | warn!("len inv mismatch"); | ||
| 104 | return None; | ||
| 105 | } | ||
| 106 | |||
| 107 | if sdpcm_header.len as usize != packet_len { | ||
| 108 | warn!("len from header doesn't match len from spi"); | ||
| 109 | return None; | ||
| 110 | } | ||
| 111 | |||
| 112 | let sdpcm_packet = &mut sdpcm_packet[(sdpcm_header.header_length as usize - Self::SIZE)..]; | ||
| 113 | Some((sdpcm_header, sdpcm_packet)) | ||
| 114 | } | ||
| 115 | } | ||
| 116 | |||
| 70 | #[derive(Debug, Clone, Copy)] | 117 | #[derive(Debug, Clone, Copy)] |
| 71 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 118 | // #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 72 | #[repr(C)] | 119 | #[repr(C, packed(2))] |
| 73 | pub struct CdcHeader { | 120 | pub struct CdcHeader { |
| 74 | pub cmd: u32, | 121 | pub cmd: u32, |
| 75 | pub len: u32, | 122 | pub len: u32, |
| @@ -79,6 +126,21 @@ pub struct CdcHeader { | |||
| 79 | } | 126 | } |
| 80 | impl_bytes!(CdcHeader); | 127 | impl_bytes!(CdcHeader); |
| 81 | 128 | ||
| 129 | impl CdcHeader { | ||
| 130 | pub fn parse(packet: &mut [u8]) -> Option<(&mut Self, &mut [u8])> { | ||
| 131 | if packet.len() < Self::SIZE { | ||
| 132 | warn!("payload too short, len={}", packet.len()); | ||
| 133 | return None; | ||
| 134 | } | ||
| 135 | |||
| 136 | let (cdc_header, payload) = packet.split_at_mut(Self::SIZE); | ||
| 137 | let cdc_header = Self::from_bytes_mut(cdc_header.try_into().unwrap()); | ||
| 138 | |||
| 139 | let payload = &mut payload[..cdc_header.len as usize]; | ||
| 140 | Some((cdc_header, payload)) | ||
| 141 | } | ||
| 142 | } | ||
| 143 | |||
| 82 | pub const BDC_VERSION: u8 = 2; | 144 | pub const BDC_VERSION: u8 = 2; |
| 83 | pub const BDC_VERSION_SHIFT: u8 = 4; | 145 | pub const BDC_VERSION_SHIFT: u8 = 4; |
| 84 | 146 | ||
| @@ -95,6 +157,25 @@ pub struct BcdHeader { | |||
| 95 | } | 157 | } |
| 96 | impl_bytes!(BcdHeader); | 158 | impl_bytes!(BcdHeader); |
| 97 | 159 | ||
| 160 | impl BcdHeader { | ||
| 161 | pub fn parse(packet: &mut [u8]) -> Option<(&mut Self, &mut [u8])> { | ||
| 162 | if packet.len() < Self::SIZE { | ||
| 163 | return None; | ||
| 164 | } | ||
| 165 | |||
| 166 | let (bcd_header, bcd_packet) = packet.split_at_mut(Self::SIZE); | ||
| 167 | let bcd_header = Self::from_bytes_mut(bcd_header.try_into().unwrap()); | ||
| 168 | trace!(" {:?}", bcd_header); | ||
| 169 | |||
| 170 | let packet_start = 4 * bcd_header.data_offset as usize; | ||
| 171 | |||
| 172 | let bcd_packet = bcd_packet.get_mut(packet_start..)?; | ||
| 173 | trace!(" {:02x}", Bytes(&bcd_packet[..bcd_packet.len().min(36)])); | ||
| 174 | |||
| 175 | Some((bcd_header, bcd_packet)) | ||
| 176 | } | ||
| 177 | } | ||
| 178 | |||
| 98 | #[derive(Clone, Copy)] | 179 | #[derive(Clone, Copy)] |
| 99 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 180 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 100 | #[repr(C)] | 181 | #[repr(C)] |
| @@ -130,8 +211,8 @@ impl EventHeader { | |||
| 130 | } | 211 | } |
| 131 | 212 | ||
| 132 | #[derive(Debug, Clone, Copy)] | 213 | #[derive(Debug, Clone, Copy)] |
| 133 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 214 | // #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 134 | #[repr(C)] | 215 | #[repr(C, packed(2))] |
| 135 | pub struct EventMessage { | 216 | pub struct EventMessage { |
| 136 | /// version | 217 | /// version |
| 137 | pub version: u16, | 218 | pub version: u16, |
| @@ -158,6 +239,45 @@ pub struct EventMessage { | |||
| 158 | } | 239 | } |
| 159 | impl_bytes!(EventMessage); | 240 | impl_bytes!(EventMessage); |
| 160 | 241 | ||
| 242 | #[cfg(feature = "defmt")] | ||
| 243 | impl defmt::Format for EventMessage { | ||
| 244 | fn format(&self, fmt: defmt::Formatter) { | ||
| 245 | let event_type = self.event_type; | ||
| 246 | let status = self.status; | ||
| 247 | let reason = self.reason; | ||
| 248 | let auth_type = self.auth_type; | ||
| 249 | let datalen = self.datalen; | ||
| 250 | |||
| 251 | defmt::write!( | ||
| 252 | fmt, | ||
| 253 | "EventMessage {{ \ | ||
| 254 | version: {=u16}, \ | ||
| 255 | flags: {=u16}, \ | ||
| 256 | event_type: {=u32}, \ | ||
| 257 | status: {=u32}, \ | ||
| 258 | reason: {=u32}, \ | ||
| 259 | auth_type: {=u32}, \ | ||
| 260 | datalen: {=u32}, \ | ||
| 261 | addr: {=[u8; 6]:x}, \ | ||
| 262 | ifname: {=[u8; 16]:x}, \ | ||
| 263 | ifidx: {=u8}, \ | ||
| 264 | bsscfgidx: {=u8}, \ | ||
| 265 | }} ", | ||
| 266 | self.version, | ||
| 267 | self.flags, | ||
| 268 | event_type, | ||
| 269 | status, | ||
| 270 | reason, | ||
| 271 | auth_type, | ||
| 272 | datalen, | ||
| 273 | self.addr, | ||
| 274 | self.ifname, | ||
| 275 | self.ifidx, | ||
| 276 | self.bsscfgidx | ||
| 277 | ); | ||
| 278 | } | ||
| 279 | } | ||
| 280 | |||
| 161 | impl EventMessage { | 281 | impl EventMessage { |
| 162 | pub fn byteswap(&mut self) { | 282 | pub fn byteswap(&mut self) { |
| 163 | self.version = self.version.to_be(); | 283 | self.version = self.version.to_be(); |
| @@ -172,7 +292,7 @@ impl EventMessage { | |||
| 172 | 292 | ||
| 173 | #[derive(Clone, Copy)] | 293 | #[derive(Clone, Copy)] |
| 174 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 294 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 175 | #[repr(C)] | 295 | #[repr(C, packed(2))] |
| 176 | pub struct EventPacket { | 296 | pub struct EventPacket { |
| 177 | pub eth: EthernetHeader, | 297 | pub eth: EthernetHeader, |
| 178 | pub hdr: EventHeader, | 298 | pub hdr: EventHeader, |
| @@ -181,6 +301,21 @@ pub struct EventPacket { | |||
| 181 | impl_bytes!(EventPacket); | 301 | impl_bytes!(EventPacket); |
| 182 | 302 | ||
| 183 | impl EventPacket { | 303 | impl EventPacket { |
| 304 | pub fn parse(packet: &mut [u8]) -> Option<(&mut Self, &mut [u8])> { | ||
| 305 | if packet.len() < Self::SIZE { | ||
| 306 | return None; | ||
| 307 | } | ||
| 308 | |||
| 309 | let (event_header, event_packet) = packet.split_at_mut(Self::SIZE); | ||
| 310 | let event_header = Self::from_bytes_mut(event_header.try_into().unwrap()); | ||
| 311 | // warn!("event_header {:x}", event_header as *const _); | ||
| 312 | event_header.byteswap(); | ||
| 313 | |||
| 314 | let event_packet = event_packet.get_mut(..event_header.msg.datalen as usize)?; | ||
| 315 | |||
| 316 | Some((event_header, event_packet)) | ||
| 317 | } | ||
| 318 | |||
| 184 | pub fn byteswap(&mut self) { | 319 | pub fn byteswap(&mut self) { |
| 185 | self.eth.byteswap(); | 320 | self.eth.byteswap(); |
| 186 | self.hdr.byteswap(); | 321 | self.hdr.byteswap(); |
