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}