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