1use super::ids::*;
2use nom::{
3 error::ParseError, lib::std::ops::RangeFrom, number::streaming, IResult, InputIter,
4 InputLength, Slice,
5};
6
7const BASIC_CODEC_VERSION: u8 = 1;
8
9#[derive(Clone, Debug)]
11pub struct Header {
12 pub service: Service,
13 pub request: u8,
14 pub msg_type: MsgType,
15 pub sequence: u32, }
17
18impl Header {
19 pub fn as_bytes(&self) -> [u8; 8] {
21 let header: u32 = (BASIC_CODEC_VERSION as u32) << 24
22 | ((self.service as u32) << 16)
23 | ((self.request as u32) << 8)
24 | (self.msg_type as u32);
25 let header = header.to_le_bytes();
26
27 let seq = self.sequence.to_le_bytes();
28
29 [
30 header[0], header[1], header[2], header[3], seq[0], seq[1], seq[2], seq[3],
31 ]
32 }
33
34 pub fn parse<I, E: ParseError<I>>(i: I) -> IResult<I, Self, E>
36 where
37 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
38 {
39 let (i, header) = streaming::le_u32(i)?;
40 let (i, sequence) = streaming::le_u32(i)?;
41 Ok((
42 i,
43 Self {
44 service: (((header >> 16) & 0xff) as u8).into(),
45 request: ((header >> 8) & 0xff) as u8,
46 msg_type: ((header & 0xff) as u8).into(),
47 sequence,
48 },
49 ))
50 }
51}
52
53#[derive(Clone, Debug)]
55pub struct FrameHeader {
56 pub msg_length: u16,
57 pub crc16: u16,
58}
59
60impl FrameHeader {
61 pub fn new_from_msg(msg: &[u8]) -> Self {
63 Self {
64 msg_length: msg.len() as u16,
65 crc16: crc16(msg),
66 }
67 }
68
69 pub fn as_bytes(&self) -> [u8; 4] {
71 let (l, c) = (self.msg_length.to_le_bytes(), self.crc16.to_le_bytes());
72 [l[0], l[1], c[0], c[1]]
73 }
74
75 pub fn parse<I, E: ParseError<I>>(i: I) -> IResult<I, Self, E>
78 where
79 I: Slice<RangeFrom<usize>> + InputIter<Item = u8> + InputLength,
80 {
81 let (i, msg_length) = streaming::le_u16(i)?;
82 let (i, crc16) = streaming::le_u16(i)?;
83 Ok((i, Self { msg_length, crc16 }))
84 }
85
86 pub fn check_crc<I, E>(&self, data: I) -> Result<(), super::Err<E>>
88 where
89 I: InputIter<Item = u8>,
90 {
91 if crc16(data) == self.crc16 {
92 Ok(())
93 } else {
94 Err(super::Err::CRCMismatch)
95 }
96 }
97}
98
99pub(crate) fn crc16<I>(data: I) -> u16
101where
102 I: InputIter<Item = u8>,
103{
104 let mut crc: u32 = 0xEF4A;
105
106 for b in data.iter_elements() {
107 crc ^= (b as u32) << 8;
108 for _ in 0..8 {
109 let mut temp: u32 = crc << 1;
110 if (crc & 0x8000) != 0 {
111 temp ^= 0x1021;
112 }
113 crc = temp;
114 }
115 }
116
117 crc as u16
118}