Skip to main content

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}