embedded_bacnet/application_protocol/
unconfirmed.rs1use crate::common::{
2 error::{Error, Unimplemented},
3 io::{Reader, Writer},
4};
5
6use super::{
7 application_pdu::ApduType,
8 services::{
9 change_of_value::CovNotification, i_am::IAm, time_synchronization::TimeSynchronization,
10 who_is::WhoIs,
11 },
12};
13
14#[derive(Debug, Clone)]
15#[cfg_attr(feature = "defmt", derive(defmt::Format))]
16pub enum UnconfirmedRequest<'a> {
17 WhoIs(WhoIs),
18 IAm(IAm),
19 CovNotification(CovNotification<'a>),
20 TimeSynchronization(TimeSynchronization),
21}
22
23impl<'a> UnconfirmedRequest<'a> {
24 pub fn encode(&self, writer: &mut Writer) {
25 writer.push((ApduType::UnconfirmedServiceRequest as u8) << 4);
26
27 match &self {
28 Self::IAm(payload) => payload.encode(writer),
29 Self::WhoIs(payload) => payload.encode(writer),
30 Self::CovNotification(_) => todo!(),
31 Self::TimeSynchronization(payload) => payload.encode(writer),
32 }
33 }
34 pub fn decode(reader: &mut Reader, buf: &'a [u8]) -> Result<Self, Error> {
35 let choice: UnconfirmedServiceChoice = reader
36 .read_byte(buf)?
37 .try_into()
38 .map_err(|x| Error::InvalidVariant(("UnconfirmedRequest choice", x as u32)))?;
39 match choice {
40 UnconfirmedServiceChoice::IAm => {
41 let apdu = IAm::decode(reader, buf)?;
42 Ok(Self::IAm(apdu))
43 }
44 UnconfirmedServiceChoice::WhoIs => {
45 let apdu = WhoIs::decode(reader, buf);
46 Ok(Self::WhoIs(apdu))
47 }
48 UnconfirmedServiceChoice::CovNotification => {
49 let apdu = CovNotification::decode(reader, buf)?;
50 Ok(Self::CovNotification(apdu))
51 }
52 x => Err(Error::Unimplemented(
53 Unimplemented::UnconfirmedServiceChoice(x),
54 )),
55 }
56 }
57}
58
59#[derive(Debug, Clone)]
60#[cfg_attr(feature = "defmt", derive(defmt::Format))]
61#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
62pub enum UnconfirmedServiceChoice {
63 IAm = 0,
64 IHave = 1,
65 CovNotification = 2,
66 EventNotification = 3,
67 PrivateTransfer = 4,
68 TextMessage = 5,
69 TimeSynchronization = 6,
70 WhoHas = 7,
71 WhoIs = 8,
72 UtcTimeSynchronization = 9,
73
74 WriteGroup = 10,
76
77 CovNotificationMultiple = 11,
79
80 AuditNotification = 12,
82
83 WhoAmI = 13,
85 YouAre = 14,
86
87 MaxBacnetUnconfirmedService = 15,
93}
94
95impl TryFrom<u8> for UnconfirmedServiceChoice {
96 type Error = u8;
97 fn try_from(value: u8) -> Result<Self, u8> {
98 match value {
99 0 => Ok(Self::IAm),
100 1 => Ok(Self::IHave),
101 2 => Ok(Self::CovNotification),
102 3 => Ok(Self::EventNotification),
103 4 => Ok(Self::PrivateTransfer),
104 5 => Ok(Self::TextMessage),
105 6 => Ok(Self::TimeSynchronization),
106 7 => Ok(Self::WhoHas),
107 8 => Ok(Self::WhoIs),
108 9 => Ok(Self::UtcTimeSynchronization),
109 10 => Ok(Self::WriteGroup),
110 11 => Ok(Self::CovNotificationMultiple),
111 12 => Ok(Self::AuditNotification),
112 13 => Ok(Self::WhoAmI),
113 14 => Ok(Self::YouAre),
114 15 => Ok(Self::MaxBacnetUnconfirmedService),
115 x => Err(x),
116 }
117 }
118}