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
//! Audit notification and query wire models.
//!
//! These codecs follow the corrected 2020 baseline: ANSI/ASHRAE 135-2020 plus
//! the Errata Summary 2024-04-29 (v1), visually verified from the rendered
//! errata page 3 under its page-1 convention (strikeout = removed, italics =
//! added) and recorded by RB-01. Item 7 (Clause 21.6, printed p. 886)
//! corrects the by-target/by-source `successful-actions-only` fields from
//! BOOLEAN to `BACnetSuccessFilter` at unchanged tags \[7\]/\[4\]; item 8
//! (Clause 21.2.3, printed p. 865) corrects `start-at-sequence-number` from
//! Unsigned32 to Unsigned64 at unchanged optional tag \[2\]. Unsigned values
//! use the library's `u64` implementation limit (1-8 octet canonical forms).
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
pub use bacnet_types::constructed::{
AuditPropertyReference, BACnetAuditLogDatum, BACnetAuditLogQueryParameters,
BACnetAuditLogRecord, BACnetAuditLogRecordResult, BACnetAuditNotification,
};
use bacnet_types::error::Error;
use bacnet_types::primitives::ObjectIdentifier;
use bytes::BytesMut;
#[path = "audit/notification_codec.rs"]
mod notification_codec;
#[path = "audit/query_ack_codec.rs"]
mod query_ack_codec;
#[path = "audit/query_codec.rs"]
mod query_codec;
/// Parameters shared by confirmed and unconfirmed AuditNotification.
#[derive(Debug, Clone, PartialEq)]
pub struct AuditNotificationRequest {
/// One or more notifications, encoded under context tag `[0]`.
pub notifications: Vec<BACnetAuditNotification>,
}
/// AuditLogQuery-ACK service parameters.
///
/// This wire model does not perform storage queries or infer record ordering,
/// continuity, filtering, or the truth of `no_more_items`.
#[derive(Debug, Clone, PartialEq)]
pub struct AuditLogQueryAck {
/// Audit Log object whose records were queried.
pub audit_log: ObjectIdentifier,
/// Zero or more adjacent record results encoded under context tag `[1]`.
pub records: Vec<BACnetAuditLogRecordResult>,
/// `true` when no records remain beyond those returned; the codec does not verify it.
pub no_more_items: bool,
}
/// AuditLogQuery-Request service parameters.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AuditLogQueryRequest {
/// Audit Log object to query.
pub audit_log: ObjectIdentifier,
/// Filter selecting which records to return.
pub query_parameters: BACnetAuditLogQueryParameters,
/// Corrected-baseline `Unsigned64` cursor (Errata 2024-04-29 item 8).
pub start_at_sequence_number: Option<u64>,
/// Maximum number of records the requester wants returned.
pub requested_count: u16,
}
impl AuditNotificationRequest {
/// Encode after validation, leaving `buf` unchanged on failure.
pub fn try_encode(&self, buf: &mut BytesMut) -> Result<(), Error> {
notification_codec::encode(self, buf)
}
/// Encode the request into `buf`; same as `try_encode`.
pub fn encode(&self, buf: &mut BytesMut) -> Result<(), Error> {
self.try_encode(buf)
}
/// Decode a complete payload; trailing bytes are rejected.
pub fn decode(data: &[u8]) -> Result<Self, Error> {
notification_codec::decode(data)
}
}
impl AuditLogQueryRequest {
/// Encode after validation, leaving `buf` unchanged on failure.
pub fn try_encode(&self, buf: &mut BytesMut) -> Result<(), Error> {
query_codec::encode(self, buf)
}
/// Encode the request into `buf`; same as `try_encode`.
pub fn encode(&self, buf: &mut BytesMut) -> Result<(), Error> {
self.try_encode(buf)
}
/// Decode a complete payload; trailing bytes are rejected.
pub fn decode(data: &[u8]) -> Result<Self, Error> {
query_codec::decode(data)
}
}
impl AuditLogQueryAck {
/// Encode after validation, leaving `buf` unchanged on failure.
pub fn try_encode(&self, buf: &mut BytesMut) -> Result<(), Error> {
query_ack_codec::encode(self, buf)
}
/// Encode the ACK into `buf`; same as `try_encode`.
pub fn encode(&self, buf: &mut BytesMut) -> Result<(), Error> {
self.try_encode(buf)
}
/// Decode a complete payload; trailing bytes are rejected.
pub fn decode(data: &[u8]) -> Result<Self, Error> {
query_ack_codec::decode(data)
}
}
#[cfg(test)]
#[path = "audit/tests.rs"]
mod tests;
#[cfg(test)]
#[path = "audit/malformed_tests.rs"]
mod malformed_tests;
#[cfg(test)]
#[path = "audit/empty_value_tests.rs"]
mod empty_value_tests;
#[cfg(test)]
#[path = "audit/address_bound_tests.rs"]
mod address_bound_tests;