embedded_bacnet/application_protocol/
application_pdu.rs1use 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#[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 }
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#[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, }
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, }
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}