Skip to main content

rsiot/components_config/modbus_frame/
rtu_response.rs

1use bytes::{Buf, Bytes, BytesMut};
2
3use super::{CRC_ALG, Error};
4
5/// Извлечение данных из ответа Modbus RTU
6pub struct RTUResponse {
7    /// Предполагаемый адрес устройства
8    pub address: u8,
9
10    /// Данные ответа
11    pub data: Bytes,
12}
13
14impl RTUResponse {
15    /// Извлечь данные из ответа Modbus RTU
16    pub fn parse(self) -> Result<BytesMut, Error> {
17        let mut frame: BytesMut = self.data.into();
18
19        let mut crc_packet = frame.split_off(frame.len() - 2);
20        let crc_packet: u16 = crc_packet.get_u16_le();
21        let crc_calculated = CRC_ALG.checksum(&frame);
22        if crc_packet != crc_calculated {
23            return Err(Error::CRCMismatch);
24        }
25
26        let address = frame.try_get_u8()?;
27        if address != self.address {
28            return Err(Error::AddressMismatch {
29                address_in_packet: address,
30                expected_address: self.address,
31            });
32        }
33
34        let _func_code = frame.try_get_u8()?;
35
36        let length = frame.try_get_u8()? as usize;
37        if length != frame.len() {
38            return Err(Error::LengthMismatch {
39                length_in_packet: length,
40                expected_length: frame.len(),
41            });
42        }
43
44        Ok(frame)
45    }
46}
47
48#[cfg(test)]
49mod tests {
50    use super::*;
51
52    use pretty_assertions::assert_eq;
53
54    #[test]
55    fn test() -> anyhow::Result<()> {
56        let data = vec![
57            0x01, 0x03, 0x16, 0x03, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
58            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x01, 0x39, 0x42, 0x38,
59        ];
60
61        let correct = Bytes::from(data[3..25].to_vec());
62
63        let test = RTUResponse {
64            address: 1,
65            data: Bytes::from_owner(data),
66        }
67        .parse()?;
68
69        assert_eq!(test, correct);
70
71        Ok(())
72    }
73}