1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
//! Present_Value and Reliability of a Credential Data Input while
//! Out_Of_Service is TRUE (Clauses 12.36.4, 12.36.7 and 12.36.8, Table 12-43
//! footnote 1, #1168).
//!
//! Footnote 1 of Table 12-43 marks these two rows, so a client can stand in
//! for the reader by writing them. The object takes WriteProperty and
//! WritePropertyMultiple of either one only while Out_Of_Service is TRUE; in
//! service both are refused with WRITE_ACCESS_DENIED. A refused write changes
//! nothing.
//!
//! A Present_Value write is checked in three steps:
//!
//! - Its bytes have to decode as exactly one BACnetAuthenticationFactor:
//! format type, format class and value under context tags 0, 1 and 2, with
//! nothing after them. Any other form is INVALID_DATA_TYPE, the error Load
//! Control gives a malformed shed level (#1133).
//! - The format type has to be a named BACnetAuthenticationFactorType. That
//! production is closed, so any other number is VALUE_OUT_OF_RANGE.
//! - Clause 12.36.4 ties a factor to the formats this reader declares, so the
//! pair of format type and format class has to match a Supported_Formats
//! element and the Supported_Format_Classes element at the same position.
//! Two types need no declaration: UNDEFINED (no factor read) and ERROR (a
//! read the reader can't decode), each with format class 0. Any other pair
//! is VALUE_OUT_OF_RANGE. `set_present_value` applies the same rule
//! (`credential_data_input_formats`). The value octets aren't checked
//! against the Annex P layout of the format.
//!
//! A Reliability write has to be an Enumerated that passes
//! `common::is_reliability_value_valid`: another number is VALUE_OUT_OF_RANGE
//! and another datatype INVALID_DATA_TYPE.
//!
//! Update_Time moves with each Present_Value update (Clause 12.36.11), and
//! Clause 12.36.8 asks the rest of the device to treat a simulated value as a
//! real read. So an accepted Present_Value write stamps Update_Time from the
//! Device clock, as the Pulse Converter stamps a new Count. With no usable
//! clock it takes the object's next sequence number instead (`UpdateClock`),
//! so each simulated read still moves it. Writing the same factor again
//! stamps it again. A Reliability write leaves Update_Time alone.
//!
//! Out of service the three values stop following the reader, so the object
//! keeps the reader's own values to one side:
//!
//! - On the FALSE-to-TRUE edge it puts aside the Present_Value, Update_Time
//! and Reliability it serves (`common::write_out_of_service_with_restore`).
//! - Meanwhile a read the application reports (`set_present_value`) replaces
//! the Present_Value and Update_Time put aside, not those served. A
//! Reliability it works out (`set_reliability_internal`) is refused, as on
//! the other Reliability carriers.
//! - On the TRUE-to-FALSE edge all three go back to the values put aside, so
//! the reader's state is served again at once and the simulation is gone.
//!
//! COV: the server compares the values of the Credential Data Input row of
//! Table 13-1 (#1061), Present_Value and Update_Time among them, around every
//! committed write. A simulated Present_Value reports, a simulated Reliability
//! that leaves or returns to NO_FAULT_DETECTED flips the FAULT flag and
//! reports, and the return to service reports when it changes any of them.
use decode_authentication_factor;
use BACnetAuthenticationFactor;
use ;
use Error;
use ;
use ;
use ;
use cratecommon;
/// The values a client can simulate while Out_Of_Service is TRUE, plus the
/// Update_Time that moves with Present_Value.
pub
/// Decode a client's Present_Value write and check it against `formats`.
/// The factor a write carries, or `None` when its bytes aren't one
/// BACnetAuthenticationFactor.
///
/// The server hands a context-tagged value over as `ApplicationData`, one
/// chunk per tag, so a whole factor arrives as a `List` of three chunks. They
/// are joined back into the bytes the client sent before decoding, as
/// `reference::decode_reference_write` does for a framed reference.