1use super::{
2 error::Error,
3 helper::decode_unsigned,
4 io::{Reader, Writer},
5 spec::{BACNET_INSTANCE_BITS, BACNET_MAX_INSTANCE, BACNET_MAX_OBJECT},
6};
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
10#[cfg_attr(feature = "defmt", derive(defmt::Format))]
11#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
12pub struct ObjectId {
13 pub object_type: ObjectType,
14 pub id: u32,
15}
16
17impl ObjectId {
18 pub const LEN: u32 = 4; pub fn new(object_type: ObjectType, id: u32) -> Self {
21 Self { object_type, id }
22 }
23
24 pub fn encode(&self, writer: &mut Writer) {
25 let value = ((self.object_type as u32 & BACNET_MAX_OBJECT) << BACNET_INSTANCE_BITS)
26 | (self.id & BACNET_MAX_INSTANCE);
27 writer.extend_from_slice(&value.to_be_bytes());
28 }
29
30 pub fn decode(size: u32, reader: &mut Reader, buf: &[u8]) -> Result<Self, Error> {
31 let value = decode_unsigned(size, reader, buf)? as u32;
32 let object_type = value >> BACNET_INSTANCE_BITS & BACNET_MAX_OBJECT;
33 let object_type = ObjectType::try_from(object_type)
34 .map_err(|x| Error::InvalidVariant(("ObjectId decode ObjectType", x)))?;
35 let id = value & BACNET_MAX_INSTANCE;
36 let object_id = ObjectId { object_type, id };
37 Ok(object_id)
38 }
39}
40
41#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
43#[cfg_attr(feature = "defmt", derive(defmt::Format))]
44#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
45#[repr(u32)]
46pub enum ObjectType {
47 ObjectAnalogInput = 0,
48 ObjectAnalogOutput = 1,
49 ObjectAnalogValue = 2,
50 ObjectBinaryInput = 3,
51 ObjectBinaryOutput = 4,
52 ObjectBinaryValue = 5,
53 ObjectCalendar = 6,
54 ObjectCommand = 7,
55 ObjectDevice = 8,
56 ObjectEventEnrollment = 9,
57 ObjectFile = 10,
58 ObjectGroup = 11,
59 ObjectLoop = 12,
60 ObjectMultiStateInput = 13,
61 ObjectMultiStateOutput = 14,
62 ObjectNotificationClass = 15,
63 ObjectProgram = 16,
64 ObjectSchedule = 17,
65 ObjectAveraging = 18,
66 ObjectMultiStateValue = 19,
67 ObjectTrendlog = 20,
68 ObjectLifeSafetyPoint = 21,
69 ObjectLifeSafetyZone = 22,
70 ObjectAccumulator = 23,
71 ObjectPulseConverter = 24,
72 ObjectEventLog = 25,
73 ObjectGlobalGroup = 26,
74 ObjectTrendLogMultiple = 27,
75 ObjectLoadControl = 28,
76 ObjectStructuredView = 29,
77 ObjectAccessDoor = 30,
78 ObjectTimer = 31,
79 ObjectAccessCredential = 32, ObjectAccessPoint = 33,
81 ObjectAccessRights = 34,
82 ObjectAccessUser = 35,
83 ObjectAccessZone = 36,
84 ObjectCredentialDataInput = 37, ObjectNetworkSecurity = 38, ObjectBitstringValue = 39, ObjectCharacterstringValue = 40, ObjectDatePatternValue = 41, ObjectDateValue = 42, ObjectDatetimePatternValue = 43, ObjectDatetimeValue = 44, ObjectIntegerValue = 45, ObjectLargeAnalogValue = 46, ObjectOctetstringValue = 47, ObjectPositiveIntegerValue = 48, ObjectTimePatternValue = 49, ObjectTimeValue = 50, ObjectNotificationForwarder = 51, ObjectAlertEnrollment = 52, ObjectChannel = 53, ObjectLightingOutput = 54, ObjectBinaryLightingOutput = 55, ObjectNetworkPort = 56, Reserved = 57,
111 Proprietary = 128,
112 Invalid = 1024,
113}
114
115impl TryFrom<u32> for ObjectType {
116 type Error = u32;
117
118 fn try_from(value: u32) -> Result<Self, u32> {
119 match value {
120 0 => Ok(Self::ObjectAnalogInput),
121 1 => Ok(Self::ObjectAnalogOutput),
122 2 => Ok(Self::ObjectAnalogValue),
123 3 => Ok(Self::ObjectBinaryInput),
124 4 => Ok(Self::ObjectBinaryOutput),
125 5 => Ok(Self::ObjectBinaryValue),
126 6 => Ok(Self::ObjectCalendar),
127 7 => Ok(Self::ObjectCommand),
128 8 => Ok(Self::ObjectDevice),
129 9 => Ok(Self::ObjectEventEnrollment),
130 10 => Ok(Self::ObjectFile),
131 11 => Ok(Self::ObjectGroup),
132 12 => Ok(Self::ObjectLoop),
133 13 => Ok(Self::ObjectMultiStateInput),
134 14 => Ok(Self::ObjectMultiStateOutput),
135 15 => Ok(Self::ObjectNotificationClass),
136 16 => Ok(Self::ObjectProgram),
137 17 => Ok(Self::ObjectSchedule),
138 18 => Ok(Self::ObjectAveraging),
139 19 => Ok(Self::ObjectMultiStateValue),
140 20 => Ok(Self::ObjectTrendlog),
141 21 => Ok(Self::ObjectLifeSafetyPoint),
142 22 => Ok(Self::ObjectLifeSafetyZone),
143 23 => Ok(Self::ObjectAccumulator),
144 24 => Ok(Self::ObjectPulseConverter),
145 25 => Ok(Self::ObjectEventLog),
146 26 => Ok(Self::ObjectGlobalGroup),
147 27 => Ok(Self::ObjectTrendLogMultiple),
148 28 => Ok(Self::ObjectLoadControl),
149 29 => Ok(Self::ObjectStructuredView),
150 30 => Ok(Self::ObjectAccessDoor),
151 31 => Ok(Self::ObjectTimer),
152 32 => Ok(Self::ObjectAccessCredential),
153 33 => Ok(Self::ObjectAccessPoint),
154 34 => Ok(Self::ObjectAccessRights),
155 35 => Ok(Self::ObjectAccessUser),
156 36 => Ok(Self::ObjectAccessZone),
157 37 => Ok(Self::ObjectCredentialDataInput),
158 38 => Ok(Self::ObjectNetworkSecurity),
159 39 => Ok(Self::ObjectBitstringValue),
160 40 => Ok(Self::ObjectCharacterstringValue),
161 41 => Ok(Self::ObjectDatePatternValue),
162 42 => Ok(Self::ObjectDateValue),
163 43 => Ok(Self::ObjectDatetimePatternValue),
164 44 => Ok(Self::ObjectDatetimeValue),
165 45 => Ok(Self::ObjectIntegerValue),
166 46 => Ok(Self::ObjectLargeAnalogValue),
167 47 => Ok(Self::ObjectOctetstringValue),
168 48 => Ok(Self::ObjectPositiveIntegerValue),
169 49 => Ok(Self::ObjectTimePatternValue),
170 50 => Ok(Self::ObjectTimeValue),
171 51 => Ok(Self::ObjectNotificationForwarder),
172 52 => Ok(Self::ObjectAlertEnrollment),
173 53 => Ok(Self::ObjectChannel),
174 54 => Ok(Self::ObjectLightingOutput),
175 55 => Ok(Self::ObjectBinaryLightingOutput),
176 56 => Ok(Self::ObjectNetworkPort),
177 57..=127 => Ok(Self::Reserved),
178 128..=1023 => Ok(Self::Proprietary),
179 x => Err(x),
180 }
181 }
182}