Skip to main content

bacnet_types/constructed/
access.rs

1//! Constructed values served by the Access Point object (Clause 12.31), the
2//! Access Rights object (Clause 12.34), the Access Credential object (Clause
3//! 12.35) and the Credential Data Input object (Clause 12.36).
4
5#[cfg(not(feature = "std"))]
6use alloc::vec::Vec;
7
8use super::{BACnetDeviceObjectPropertyReference, BACnetDeviceObjectReference};
9use crate::enums::{
10    AccessAuthenticationFactorDisable, AccessRuleLocationSpecifier, AccessRuleTimeRangeSpecifier,
11    AuthenticationFactorType,
12};
13
14/// One element of an Access Rights object's Positive_Access_Rules or
15/// Negative_Access_Rules array (`BACnetAccessRule`, Clause 21; Clause
16/// 12.34.9.1).
17///
18/// The fields mirror the five wire members in order: the time-range
19/// specifier as a context `[0]` ENUMERATED, the time-range reference framed
20/// in context tag `[1]`, the location specifier as a context `[2]`
21/// ENUMERATED, the location reference framed in context tag `[3]` and the
22/// enable flag as a context `[4]` BOOLEAN. Both references are optional on
23/// the wire. The codec is `bacnet_encoding::constructed::{encode_access_rule,
24/// decode_access_rule}`; it keeps whatever specifier values it reads, and the
25/// Access Rights setters refuse the combinations Clause 12.34.9.1 rules out.
26#[derive(Debug, Clone, PartialEq, Eq)]
27pub struct BACnetAccessRule {
28    /// SPECIFIED when `time_range` decides when the rule applies, ALWAYS
29    /// when it applies at any time.
30    pub time_range_specifier: AccessRuleTimeRangeSpecifier,
31    /// The property, typically a Schedule's Present_Value, whose value says
32    /// whether the rule applies now. Needed with SPECIFIED; with ALWAYS it is
33    /// left out or unspecified (instance 4194303).
34    pub time_range: Option<BACnetDeviceObjectPropertyReference>,
35    /// SPECIFIED when `location` names the place the rule covers, ALL when
36    /// it covers every access point.
37    pub location_specifier: AccessRuleLocationSpecifier,
38    /// Where the rule holds: an Access Point or an Access Zone. Needed with
39    /// SPECIFIED; with ALL it is left out or unspecified.
40    pub location: Option<BACnetDeviceObjectReference>,
41    /// Whether the rule is in force.
42    pub enable: bool,
43}
44
45impl BACnetAccessRule {
46    /// A rule whose specifiers follow the references: SPECIFIED for each
47    /// one given, ALWAYS for a missing time range and ALL for a missing
48    /// location.
49    pub fn new(
50        time_range: Option<BACnetDeviceObjectPropertyReference>,
51        location: Option<BACnetDeviceObjectReference>,
52        enable: bool,
53    ) -> Self {
54        Self {
55            time_range_specifier: if time_range.is_some() {
56                AccessRuleTimeRangeSpecifier::SPECIFIED
57            } else {
58                AccessRuleTimeRangeSpecifier::ALWAYS
59            },
60            time_range,
61            location_specifier: if location.is_some() {
62                AccessRuleLocationSpecifier::SPECIFIED
63            } else {
64                AccessRuleLocationSpecifier::ALL
65            },
66            location,
67            enable,
68        }
69    }
70}
71
72/// One element of an Access Credential's Assigned_Access_Rights array
73/// (`BACnetAssignedAccessRights`, Clause 21).
74///
75/// On the wire the reference is framed in context tag `[0]` and the enable
76/// flag follows as a context `[1]` BOOLEAN; the codec is
77/// `bacnet_encoding::constructed::{encode_assigned_access_rights,
78/// decode_assigned_access_rights}`.
79#[derive(Debug, Clone, PartialEq, Eq)]
80pub struct BACnetAssignedAccessRights {
81    /// The Access Rights object granting these rights. Clause 12.35.18 marks
82    /// an unused element with instance 4194303.
83    pub assigned_access_rights: BACnetDeviceObjectReference,
84    /// Whether the credential currently holds these rights.
85    pub enable: bool,
86}
87
88/// An authentication factor value and its format (`BACnetAuthenticationFactor`,
89/// Clause 21).
90///
91/// The three members go out as context tags `[0]` (the format type, an
92/// ENUMERATED), `[1]` (the format class, an Unsigned) and `[2]` (the value
93/// bytes, laid out as Annex P describes for the format).
94#[derive(Debug, Clone, PartialEq, Eq)]
95pub struct BACnetAuthenticationFactor {
96    /// The format of `value`.
97    pub format_type: AuthenticationFactorType,
98    /// The format class (Annex P).
99    pub format_class: u32,
100    /// The encoded factor, such as a card number.
101    pub value: Vec<u8>,
102}
103
104/// One element of a Credential Data Input's Supported_Formats array
105/// (`BACnetAuthenticationFactorFormat`, Clause 21; Clause 12.36.9).
106///
107/// The format type goes out as a context `[0]` ENUMERATED, and the two
108/// vendor members, when present, as context `[1]` and `[2]` Unsigned16
109/// values. A CUSTOM format names its vendor and that vendor's format number
110/// in them; any other format leaves them out or sets them to zero.
111#[derive(Debug, Clone, Copy, PartialEq, Eq)]
112pub struct BACnetAuthenticationFactorFormat {
113    /// The format read.
114    pub format_type: AuthenticationFactorType,
115    /// For a CUSTOM format, the Vendor_Identifier of the company whose
116    /// format it is.
117    pub vendor_id: Option<u16>,
118    /// That vendor's number for the CUSTOM format.
119    pub vendor_format: Option<u16>,
120}
121
122impl BACnetAuthenticationFactorFormat {
123    /// A standard format, with neither vendor member.
124    pub const fn standard(format_type: AuthenticationFactorType) -> Self {
125        Self {
126            format_type,
127            vendor_id: None,
128            vendor_format: None,
129        }
130    }
131
132    /// A CUSTOM format defined by vendor `vendor_id` as its format
133    /// `vendor_format`.
134    pub const fn custom(vendor_id: u16, vendor_format: u16) -> Self {
135        Self {
136            format_type: AuthenticationFactorType::CUSTOM,
137            vendor_id: Some(vendor_id),
138            vendor_format: Some(vendor_format),
139        }
140    }
141}
142
143/// One element of an Access Credential's Authentication_Factors array
144/// (`BACnetCredentialAuthenticationFactor`, Clause 21).
145///
146/// The disable value goes out as a context `[0]` ENUMERATED; the factor
147/// follows framed in context tag `[1]`.
148#[derive(Debug, Clone, PartialEq, Eq)]
149pub struct BACnetCredentialAuthenticationFactor {
150    /// `NONE` when the factor may be used; any other value says why it
151    /// can't (Clause 12.35.10).
152    pub disable: AccessAuthenticationFactorDisable,
153    /// The factor itself.
154    pub authentication_factor: BACnetAuthenticationFactor,
155}
156
157/// One entry of an authentication policy (the policy member of
158/// `BACnetAuthenticationPolicy`, Clause 21; Clause 12.31.12): a Credential
159/// Data Input the Access Point reads a factor from, and the step of the
160/// authentication that factor belongs to.
161///
162/// On the wire the reference is framed in context tag `[0]` and the index
163/// follows as a context `[1]` Unsigned.
164#[derive(Debug, Clone, PartialEq, Eq)]
165pub struct BACnetAuthenticationPolicyEntry {
166    /// The Credential Data Input the factor is read from, in this device or
167    /// in the Device the reference names.
168    pub credential_data_input: BACnetDeviceObjectReference,
169    /// The step this factor serves: 1 for the first factor expected, 2 for
170    /// the next, and so on. Entries sharing an index are alternatives, any
171    /// one of which completes that step.
172    pub index: u32,
173}
174
175/// One element of an Access Point's Authentication_Policy_List array
176/// (`BACnetAuthenticationPolicy`, Clause 21; Clause 12.31.12).
177///
178/// On the wire the entries go out inside opening and closing tag `[0]`, each
179/// as its two members with no wrapper, then the order flag as a context
180/// `[1]` BOOLEAN and the timeout as a context `[2]` Unsigned. The codec is
181/// `bacnet_encoding::constructed::{encode_authentication_policy,
182/// decode_authentication_policy}`; it keeps whatever entries it reads, and
183/// the Access Point judges whether the policy is usable.
184///
185/// The default is the element Clause 12.31.12.2 gives an array that grows
186/// without a value for its new elements: no entries, the order not enforced
187/// and no timeout.
188#[derive(Debug, Clone, Default, PartialEq, Eq)]
189pub struct BACnetAuthenticationPolicy {
190    /// The factors the policy asks for.
191    pub policy: Vec<BACnetAuthenticationPolicyEntry>,
192    /// Whether the factors have to come in the order their indexes give.
193    pub order_enforced: bool,
194    /// The seconds allowed for presenting every factor; 0 for no limit.
195    pub timeout: u32,
196}