bacnet_objects/access_control/input.rs
1//! The inputs an application reports for its access-control objects while
2//! the server holds them (#1132).
3//!
4//! An Access Point's access events, a Credential Data Input's reads and an
5//! Access Door's hardware state come from outside BACnet: the application's
6//! access logic, its card readers, its door contacts and lock monitors. None
7//! of them takes a network write in service. Each object takes its own
8//! record through [`BACnetObject::report_access_input_internal`], whose
9//! values change together. The server's `report_access_event_local`,
10//! `report_credential_read_local` and `report_door_state_local` hand the
11//! record over as one local write, so the COV report and the event pass
12//! follow it as they follow any other.
13//!
14//! While Out_Of_Service is TRUE each object stands apart from what it
15//! represents (Clauses 12.26.9, 12.31.8 and 12.36.8), and the route follows
16//! the object's own rule for that time:
17//!
18//! - The Access Point performs no authentication or authorization, so an
19//! access event then has no meaning: the route refuses it with
20//! WRITE_ACCESS_DENIED and changes nothing. It does the same while its
21//! Reliability isn't NO_FAULT_DETECTED (Clause 12.31.7).
22//! - An Access Door or Credential Data Input keeps the device's values to one
23//! side while a client may simulate the served ones (#1131, #1168). A
24//! report replaces the values put aside, not the ones served, so it sends
25//! no COV report and moves no event algorithm; the return to service
26//! serves the latest values reported. The objects' setters follow the
27//! same rule.
28//!
29//! [`BACnetObject::report_access_input_internal`]: crate::traits::BACnetObject::report_access_input_internal
30
31use bacnet_types::constructed::{BACnetAuthenticationFactor, BACnetDeviceObjectReference};
32use bacnet_types::enums::{AccessEvent, DoorAlarmState, DoorStatus, LockStatus};
33use bacnet_types::primitives::BACnetTimeStamp;
34
35/// An input for one access-control object, as the application reports it.
36#[derive(Debug, Clone, PartialEq)]
37pub enum AccessControlInput {
38 /// A new access event, for an Access Point.
39 AccessEvent(AccessEventReport),
40 /// A factor a reader has read, for a Credential Data Input.
41 CredentialRead(CredentialReadReport),
42 /// What the door's hardware reports, for an Access Door.
43 DoorState(DoorStateReport),
44}
45
46/// One access event at an Access Point: the values of Access_Event,
47/// Access_Event_Tag, Access_Event_Time, Access_Event_Credential and
48/// Access_Event_Authentication_Factor, which change together for each event
49/// (Clause 12.31.27.1).
50#[derive(Debug, Clone, PartialEq)]
51pub struct AccessEventReport {
52 /// The event, a standard BACnetAccessEvent or a proprietary one.
53 pub event: AccessEvent,
54 /// The access transaction the event belongs to. The application moves
55 /// it on for each new transaction and repeats it for further events of
56 /// the same one (Clause 12.31.28).
57 pub tag: u64,
58 /// When the event happened; `None` stamps it strictly after the time
59 /// the point serves, from the Device clock or, without a usable clock,
60 /// the next sequence number, as the point's Out_Of_Service edges are
61 /// stamped, so each event moves Access_Event_Time.
62 pub time: Option<BACnetTimeStamp>,
63 /// The Access Credential behind the event; `None` stores the
64 /// no-credential reference (Clause 12.31.30).
65 pub credential: Option<BACnetDeviceObjectReference>,
66 /// The factor presented; `None` stores the UNDEFINED factor, for an
67 /// event no factor belongs to or one the device keeps back (Clause
68 /// 12.31.31).
69 pub authentication_factor: Option<BACnetAuthenticationFactor>,
70}
71
72impl AccessEventReport {
73 /// `event` in transaction `tag`, stamped now, with no credential and no
74 /// factor.
75 pub fn new(event: AccessEvent, tag: u64) -> Self {
76 Self {
77 event,
78 tag,
79 time: None,
80 credential: None,
81 authentication_factor: None,
82 }
83 }
84}
85
86/// A factor a Credential Data Input's reader has read: its Present_Value and
87/// Update_Time, which move together (Clause 12.36.11).
88#[derive(Debug, Clone, PartialEq)]
89pub struct CredentialReadReport {
90 /// The factor read, in one of the reader's declared formats, or the
91 /// UNDEFINED or ERROR factor.
92 pub factor: BACnetAuthenticationFactor,
93 /// When it was read; `None` stamps it from the Device clock, or the
94 /// object's next sequence number without a usable clock.
95 pub update_time: Option<BACnetTimeStamp>,
96}
97
98impl CredentialReadReport {
99 /// `factor`, read now.
100 pub fn new(factor: BACnetAuthenticationFactor) -> Self {
101 Self {
102 factor,
103 update_time: None,
104 }
105 }
106}
107
108/// What an Access Door's hardware and door logic report: any of
109/// Door_Status, Lock_Status and Door_Alarm_State. A field left `None` keeps
110/// the value the door holds.
111#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
112pub struct DoorStateReport {
113 /// The open or closed state the door contact reports.
114 pub door_status: Option<DoorStatus>,
115 /// The state the lock monitor reports.
116 pub lock_status: Option<LockStatus>,
117 /// The alarm condition the application's door logic works out.
118 pub door_alarm_state: Option<DoorAlarmState>,
119}