embedded_bacnet/application_protocol/
application_pdu.rs

1use crate::common::{
2    error::{self, Error},
3    io::{Reader, Writer},
4};
5
6use super::{
7    confirmed::{BacnetError, ComplexAck, ConfirmedRequest, SimpleAck},
8    unconfirmed::UnconfirmedRequest,
9};
10
11// Application Layer Protocol Data Unit
12#[derive(Debug, Clone)]
13#[cfg_attr(feature = "defmt", derive(defmt::Format))]
14pub enum ApplicationPdu<'a> {
15    ConfirmedRequest(ConfirmedRequest<'a>),
16    UnconfirmedRequest(UnconfirmedRequest<'a>),
17    ComplexAck(ComplexAck<'a>),
18    SimpleAck(SimpleAck),
19    Error(BacnetError),
20    // add more here (see ApduType)
21}
22
23#[derive(Debug, Clone)]
24#[cfg_attr(feature = "defmt", derive(defmt::Format))]
25#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
26#[repr(u8)]
27pub enum ApduType {
28    ConfirmedServiceRequest = 0,
29    UnconfirmedServiceRequest = 1,
30    SimpleAck = 2,
31    ComplexAck = 3,
32    SegmentAck = 4,
33    Error = 5,
34    Reject = 6,
35    Abort = 7,
36}
37
38impl TryFrom<u8> for ApduType {
39    type Error = error::Error;
40
41    fn try_from(value: u8) -> Result<Self, Error> {
42        match value {
43            0 => Ok(Self::ConfirmedServiceRequest),
44            1 => Ok(Self::UnconfirmedServiceRequest),
45            2 => Ok(Self::SimpleAck),
46            3 => Ok(Self::ComplexAck),
47            4 => Ok(Self::SegmentAck),
48            5 => Ok(Self::Error),
49            6 => Ok(Self::Reject),
50            7 => Ok(Self::Abort),
51            x => Err(Error::InvalidVariant(("ApduType", x as u32))),
52        }
53    }
54}
55
56// preshifted by 4 bits
57#[derive(Debug, Clone)]
58#[cfg_attr(feature = "defmt", derive(defmt::Format))]
59#[repr(u8)]
60pub enum MaxSegments {
61    _0 = 0x00,
62    _2 = 0x10,
63    _4 = 0x20,
64    _8 = 0x30,
65    _16 = 0x40,
66    _32 = 0x50,
67    _64 = 0x60,
68    _65 = 0x70, // default
69}
70
71impl From<u8> for MaxSegments {
72    fn from(value: u8) -> Self {
73        match value {
74            0x00 => Self::_0,
75            0x10 => Self::_2,
76            0x20 => Self::_4,
77            0x30 => Self::_8,
78            0x40 => Self::_16,
79            0x50 => Self::_32,
80            0x60 => Self::_64,
81            0x70 => Self::_65,
82            _ => Self::_65,
83        }
84    }
85}
86
87#[derive(Debug, Clone)]
88#[cfg_attr(feature = "defmt", derive(defmt::Format))]
89#[repr(u8)]
90pub enum MaxAdpu {
91    _0 = 0x00,
92    _128 = 0x01,
93    _206 = 0x02,
94    _480 = 0x03,
95    _1024 = 0x04,
96    _1476 = 0x05, // default
97}
98
99impl From<u8> for MaxAdpu {
100    fn from(value: u8) -> Self {
101        match value {
102            0x00 => Self::_0,
103            0x01 => Self::_128,
104            0x02 => Self::_206,
105            0x03 => Self::_480,
106            0x04 => Self::_1024,
107            0x05 => Self::_1476,
108            _ => Self::_1476,
109        }
110    }
111}
112
113#[derive(Debug, Clone)]
114pub enum PduFlags {
115    Server = 0b0001,
116    SegmentedResponseAccepted = 0b0010,
117    MoreFollows = 0b0100,
118    SegmentedMessage = 0b1000,
119}
120
121impl<'a> ApplicationPdu<'a> {
122    pub fn encode(&self, writer: &mut Writer) {
123        match self {
124            Self::ConfirmedRequest(req) => req.encode(writer),
125            Self::UnconfirmedRequest(req) => req.encode(writer),
126            Self::ComplexAck(req) => req.encode(writer),
127            Self::SimpleAck(ack) => ack.encode(writer),
128            Self::Error(_) => todo!(),
129        };
130    }
131
132    pub fn decode(reader: &mut Reader, buf: &'a [u8]) -> Result<Self, Error> {
133        let byte0 = reader.read_byte(buf)?;
134        let pdu_type: ApduType = (byte0 >> 4).try_into()?;
135        let pdu_flags = byte0 & 0x0F;
136        let segmented_message = (pdu_flags & PduFlags::SegmentedMessage as u8) > 0;
137        let _more_follows = (pdu_flags & PduFlags::MoreFollows as u8) > 0;
138        let _segmented_response_accepted =
139            (pdu_flags & PduFlags::SegmentedResponseAccepted as u8) > 0;
140
141        if segmented_message {
142            return Err(Error::SegmentationNotSupported);
143        }
144
145        match pdu_type {
146            ApduType::ConfirmedServiceRequest => {
147                let apdu = ConfirmedRequest::decode(reader, buf)?;
148                Ok(Self::ConfirmedRequest(apdu))
149            }
150            ApduType::UnconfirmedServiceRequest => {
151                let apdu = UnconfirmedRequest::decode(reader, buf)?;
152                Ok(Self::UnconfirmedRequest(apdu))
153            }
154            ApduType::ComplexAck => {
155                let adpu = ComplexAck::decode(reader, buf)?;
156                Ok(Self::ComplexAck(adpu))
157            }
158            ApduType::SimpleAck => {
159                let adpu = SimpleAck::decode(reader, buf)?;
160                Ok(Self::SimpleAck(adpu))
161            }
162            ApduType::Error => {
163                let apdu = BacnetError::decode(reader, buf)?;
164                Ok(Self::Error(apdu))
165            }
166            apdu_type => Err(Error::ApduTypeNotSupported(apdu_type)),
167        }
168    }
169}