bacnet_objects/access_control/
mod.rs1use crate::prelude::*;
21use alloc::borrow::Cow;
22use alloc::sync::Arc;
23use bacnet_encoding::primitives::encode_timestamp_choice;
24use bacnet_types::constructed::BACnetDeviceObjectReference;
25use bacnet_types::enums::{
26 AccessEvent, AccessUserType, AuthenticationStatus, BinaryPV, DoorAlarmState, DoorSecuredStatus,
27 DoorStatus, DoorValue, EventState, LockStatus, ObjectType, PropertyIdentifier, Reliability,
28};
29use bacnet_types::error::Error;
30use bacnet_types::primitives::{
31 BACnetTimeStamp, Date, ObjectIdentifier, PropertyValue, StatusFlags, Time,
32};
33use bytes::BytesMut;
34
35use crate::clock::{ClockReader, current_datetime};
36use crate::common::{self, read_common_properties};
37use crate::traits::BACnetObject;
38
39fn never_updated() -> BACnetTimeStamp {
43 BACnetTimeStamp::DateTime {
44 date: Date {
45 year: Date::UNSPECIFIED,
46 month: Date::UNSPECIFIED,
47 day: Date::UNSPECIFIED,
48 day_of_week: Date::UNSPECIFIED,
49 },
50 time: Time {
51 hour: Time::UNSPECIFIED,
52 minute: Time::UNSPECIFIED,
53 second: Time::UNSPECIFIED,
54 hundredths: Time::UNSPECIFIED,
55 },
56 }
57}
58
59fn timestamp_value(stamp: &BACnetTimeStamp) -> Result<PropertyValue, Error> {
61 let mut buf = BytesMut::new();
62 encode_timestamp_choice(&mut buf, stamp)?;
63 Ok(PropertyValue::ApplicationData(buf.to_vec()))
64}
65
66fn update_stamp(
76 clock: Option<&dyn ClockReader>,
77 sequence: impl FnOnce() -> u16,
78) -> BACnetTimeStamp {
79 match current_datetime(clock) {
80 Some((date, time)) => BACnetTimeStamp::DateTime { date, time },
81 None => BACnetTimeStamp::SequenceNumber(sequence()),
82 }
83}
84
85fn next_sequence(previous: u16) -> u16 {
90 if previous == u16::MAX {
91 1
92 } else {
93 previous + 1
94 }
95}
96
97#[derive(Default)]
101struct UpdateClock {
102 clock: Option<Arc<dyn ClockReader>>,
103 sequence: u16,
105}
106
107impl UpdateClock {
108 fn stamp(&mut self) -> BACnetTimeStamp {
110 let sequence = &mut self.sequence;
111 update_stamp(self.clock.as_deref(), || {
112 *sequence = next_sequence(*sequence);
113 *sequence
114 })
115 }
116}
117
118fn simulated_reliability(value: &PropertyValue) -> Result<Reliability, Error> {
122 let PropertyValue::Enumerated(raw) = value else {
123 return Err(common::invalid_data_type_error());
124 };
125 checked_reliability(Reliability::from_raw(*raw))
126}
127
128fn checked_reliability(reliability: Reliability) -> Result<Reliability, Error> {
131 if common::is_reliability_value_valid(reliability) {
132 Ok(reliability)
133 } else {
134 Err(common::value_out_of_range_error())
135 }
136}
137
138fn references_to(
144 object_type: ObjectType,
145 references: impl IntoIterator<Item = impl Into<BACnetDeviceObjectReference>>,
146) -> Result<Vec<BACnetDeviceObjectReference>, Error> {
147 let references: Vec<BACnetDeviceObjectReference> =
148 references.into_iter().map(Into::into).collect();
149 for reference in &references {
150 crate::device_reference::check_device_member(reference.device_identifier)?;
151 if reference.object_identifier.object_type() != object_type {
152 return Err(common::value_out_of_range_error());
153 }
154 }
155 Ok(references)
156}
157
158mod accompaniment;
161mod accompaniment_types;
162mod authorization;
163mod authorization_context;
164mod authorization_types;
165mod credential;
166mod credential_data_input;
167mod credential_data_input_formats;
168mod credential_data_input_out_of_service;
169mod credential_rules;
170mod door;
171mod door_alarm;
172mod door_out_of_service;
173mod input;
174mod metadata_identity;
175mod metadata_topology;
176mod point;
177mod point_authorization;
178mod point_event_time;
179mod rights;
180mod rights_evaluation;
181mod rights_writes;
182mod user;
183mod zone;
184mod zone_occupancy;
185mod zone_out_of_service;
186pub use accompaniment::*;
187pub use accompaniment_types::*;
188pub use authorization::*;
189pub use authorization_context::*;
190pub use authorization_types::*;
191pub use credential::*;
192pub use credential_data_input::*;
193pub use door::*;
194pub use input::*;
195pub use point::*;
196pub use rights::*;
197pub use rights_evaluation::*;
198pub use user::*;
199pub use zone::*;
200
201#[cfg(test)]
202mod array_tests;
203#[cfg(test)]
204mod constructed_value_tests;
205#[cfg(test)]
206mod credential_data_input_format_tests;
207#[cfg(test)]
208mod credential_data_input_out_of_service_tests;
209#[cfg(test)]
210mod credential_exemption_tests;
211#[cfg(test)]
212mod credential_tests;
213#[cfg(test)]
214mod device_reference_tests;
215#[cfg(test)]
216mod door_alarm_tests;
217#[cfg(test)]
218mod door_out_of_service_tests;
219#[cfg(test)]
220mod door_pulse_tests;
221#[cfg(test)]
222mod input_tests;
223#[cfg(test)]
224mod point_authorization_tests;
225#[cfg(test)]
226mod point_out_of_service_tests;
227#[cfg(test)]
228mod point_policy_tests;
229#[cfg(test)]
230mod point_status_tests;
231#[cfg(test)]
232mod tests;
233#[cfg(test)]
234mod typed_value_tests;
235#[cfg(test)]
236mod user_references_tests;
237#[cfg(test)]
238mod zone_event_tests;
239#[cfg(test)]
240mod zone_occupancy_tests;
241#[cfg(test)]
242mod zone_out_of_service_tests;
243#[cfg(test)]
244mod zone_points_tests;
245
246#[cfg(test)]
247mod accompaniment_tests;
248
249#[cfg(test)]
250mod accompaniment_test_support;
251
252#[cfg(test)]
253mod accompaniment_chain_tests;
254#[cfg(test)]
255mod accompaniment_resolution_tests;
256#[cfg(test)]
257mod accompaniment_timing_tests;
258
259#[cfg(test)]
260mod authorization_credential_tests;
261#[cfg(test)]
262mod authorization_test_support;
263
264#[cfg(test)]
265mod authorization_checks_tests;
266#[cfg(test)]
267mod authorization_occupancy_tests;
268#[cfg(test)]
269mod authorization_passback_tests;
270
271#[cfg(test)]
272mod authorization_phase_tests;
273
274#[cfg(test)]
275mod authorization_companion_tests;
276#[cfg(test)]
277mod authorization_rights_tests;
278
279#[cfg(test)]
280mod authorization_passback_reporting_tests;