embedded_bacnet/common/
object_id.rs

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// NOTE: Copy is derived for usage convenience
9#[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; // 4 bytes
19
20    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// NOTE that copy is derived for usage convenience
42#[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, // addendum 2008-j
80    ObjectAccessPoint = 33,
81    ObjectAccessRights = 34,
82    ObjectAccessUser = 35,
83    ObjectAccessZone = 36,
84    ObjectCredentialDataInput = 37,   // authentication-factor-input
85    ObjectNetworkSecurity = 38,       // Addendum 2008-g
86    ObjectBitstringValue = 39,        // Addendum 2008-w
87    ObjectCharacterstringValue = 40,  // Addendum 2008-w
88    ObjectDatePatternValue = 41,      // Addendum 2008-w
89    ObjectDateValue = 42,             // Addendum 2008-w
90    ObjectDatetimePatternValue = 43,  // Addendum 2008-w
91    ObjectDatetimeValue = 44,         // Addendum 2008-w
92    ObjectIntegerValue = 45,          // Addendum 2008-w
93    ObjectLargeAnalogValue = 46,      // Addendum 2008-w
94    ObjectOctetstringValue = 47,      // Addendum 2008-w
95    ObjectPositiveIntegerValue = 48,  // Addendum 2008-w
96    ObjectTimePatternValue = 49,      // Addendum 2008-w
97    ObjectTimeValue = 50,             // Addendum 2008-w
98    ObjectNotificationForwarder = 51, // Addendum 2010-af
99    ObjectAlertEnrollment = 52,       // Addendum 2010-af
100    ObjectChannel = 53,               // Addendum 2010-aa
101    ObjectLightingOutput = 54,        // Addendum 2010-i
102    ObjectBinaryLightingOutput = 55,  // Addendum 135-2012az
103    ObjectNetworkPort = 56,           // Addendum 135-2012az
104    // Enumerated values 0-127 are reserved for definition by ASHRAE.
105    // Enumerated values 128-1023 may be used by others subject to
106    // the procedures and constraints described in Clause 23.
107    // do the max range inside of enum so that
108    // compilers will allocate adequate sized datatype for enum
109    // which is used to store decoding
110    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}