m_bus_application_layer/
extended_link_layer.rs1use crate::ApplicationLayerError;
2
3#[derive(Debug, PartialEq)]
4#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5#[cfg_attr(feature = "defmt", derive(defmt::Format))]
6pub struct ExtendedLinkLayer {
7 pub communication_control: u8,
8 pub access_number: u8,
9 pub receiver_address: Option<ReceiverAddress>,
10 pub encryption: Option<EncryptionFields>,
11}
12
13#[derive(Debug, PartialEq)]
14#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
15#[cfg_attr(feature = "defmt", derive(defmt::Format))]
16pub struct ReceiverAddress {
17 pub manufacturer: u16,
18 pub address: [u8; 6],
19}
20
21#[derive(Debug, PartialEq)]
22#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
23#[cfg_attr(feature = "defmt", derive(defmt::Format))]
24pub struct EncryptionFields {
25 pub session_number: [u8; 4],
26 pub payload_crc: u16,
27}
28
29#[derive(Debug, Clone, Copy, PartialEq)]
30pub enum EllFormat {
31 FormatI,
33 FormatII,
35 FormatIII,
37}
38
39impl ExtendedLinkLayer {
40 pub fn parse(data: &[u8], format: EllFormat) -> Result<(Self, usize), ApplicationLayerError> {
42 match format {
43 EllFormat::FormatI => Self::parse_format_i(data),
44 EllFormat::FormatII => Self::parse_format_ii(data),
45 EllFormat::FormatIII => Self::parse_format_iii(data),
46 }
47 }
48
49 fn parse_format_i(data: &[u8]) -> Result<(Self, usize), ApplicationLayerError> {
50 if data.len() < 2 {
51 return Err(ApplicationLayerError::InsufficientData);
52 }
53
54 Ok((
55 ExtendedLinkLayer {
56 communication_control: data[0],
57 access_number: data[1],
58 receiver_address: None,
59 encryption: None,
60 },
61 2,
62 ))
63 }
64
65 fn parse_format_ii(data: &[u8]) -> Result<(Self, usize), ApplicationLayerError> {
66 if data.len() < 8 {
67 return Err(ApplicationLayerError::InsufficientData);
68 }
69
70 Ok((
71 ExtendedLinkLayer {
72 communication_control: data[0],
73 access_number: data[1],
74 receiver_address: None,
75 encryption: Some(EncryptionFields {
76 session_number: [data[2], data[3], data[4], data[5]],
77 payload_crc: u16::from_le_bytes([data[6], data[7]]),
78 }),
79 },
80 8,
81 ))
82 }
83
84 fn parse_format_iii(data: &[u8]) -> Result<(Self, usize), ApplicationLayerError> {
85 if data.len() < 16 {
86 return Err(ApplicationLayerError::InsufficientData);
87 }
88
89 Ok((
90 ExtendedLinkLayer {
91 communication_control: data[0],
92 access_number: data[1],
93 receiver_address: Some(ReceiverAddress {
94 manufacturer: u16::from_le_bytes([data[2], data[3]]),
95 address: [data[4], data[5], data[6], data[7], data[8], data[9]],
96 }),
97 encryption: Some(EncryptionFields {
98 session_number: [data[10], data[11], data[12], data[13]],
99 payload_crc: u16::from_le_bytes([data[14], data[15]]),
100 }),
101 },
102 16,
103 ))
104 }
105}