pub use bacnet_types::constructed::{
AuditPropertyReference, BACnetAuditLogDatum, BACnetAuditLogQueryParameters,
BACnetAuditLogRecord, BACnetAuditLogRecordResult, BACnetAuditNotification,
};
use bacnet_types::error::Error;
use bacnet_types::primitives::ObjectIdentifier;
use bytes::BytesMut;
use crate::common::PropertyReference;
#[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;
#[derive(Debug, Clone, PartialEq)]
pub struct AuditNotificationRequest {
pub notifications: Vec<BACnetAuditNotification>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct AuditLogQueryAck {
pub audit_log: ObjectIdentifier,
pub records: Vec<BACnetAuditLogRecordResult>,
pub no_more_items: bool,
}
impl From<PropertyReference> for AuditPropertyReference {
fn from(value: PropertyReference) -> Self {
Self {
property_identifier: value.property_identifier,
property_array_index: value.property_array_index.map(u64::from),
}
}
}
impl TryFrom<AuditPropertyReference> for PropertyReference {
type Error = Error;
fn try_from(value: AuditPropertyReference) -> Result<Self, Self::Error> {
Ok(Self {
property_identifier: value.property_identifier,
property_array_index: value
.property_array_index
.map(u32::try_from)
.transpose()
.map_err(|_| {
Error::OutOfRange(
"Audit property-array-index exceeds shared PropertyReference u32 limit"
.into(),
)
})?,
})
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AuditLogQueryRequest {
pub audit_log: ObjectIdentifier,
pub query_parameters: BACnetAuditLogQueryParameters,
pub start_at_sequence_number: Option<u32>,
pub requested_count: u16,
}
fn decode_canonical_unsigned(data: &[u8], offset: usize, field: &str) -> Result<u64, Error> {
if data.len() > 1 && data.first() == Some(&0) {
return Err(Error::decoding(
offset,
format!("{field} must use the shortest Unsigned/Enumerated encoding"),
));
}
bacnet_encoding::primitives::decode_unsigned(data)
}
impl AuditNotificationRequest {
pub fn try_encode(&self, buf: &mut BytesMut) -> Result<(), Error> {
notification_codec::encode(self, buf)
}
pub fn encode(&self, buf: &mut BytesMut) -> Result<(), Error> {
self.try_encode(buf)
}
pub fn decode(data: &[u8]) -> Result<Self, Error> {
notification_codec::decode(data)
}
}
impl AuditLogQueryRequest {
pub fn try_encode(&self, buf: &mut BytesMut) -> Result<(), Error> {
query_codec::encode(self, buf)
}
pub fn encode(&self, buf: &mut BytesMut) -> Result<(), Error> {
self.try_encode(buf)
}
pub fn decode(data: &[u8]) -> Result<Self, Error> {
query_codec::decode(data)
}
}
impl AuditLogQueryAck {
pub fn try_encode(&self, buf: &mut BytesMut) -> Result<(), Error> {
query_ack_codec::encode(self, buf)
}
pub fn encode(&self, buf: &mut BytesMut) -> Result<(), Error> {
self.try_encode(buf)
}
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;