Skip to main content

bacnet_objects/audit/
reporter_configuration.rs

1//! Fallible local setters share the complete object-owned change boundary.
2use super::*;
3impl AuditReporterObject {
4    /// Set Audit_Level; live admission failure leaves all state unchanged.
5    pub fn set_audit_level(&mut self, level: AuditLevel) -> Result<(), Error> {
6        let mut next = self.configuration_internal();
7        next.audit_level = level;
8        self.change_configuration(next, None)
9    }
10    /// Set Auditable_Operations atomically with any required notification.
11    pub fn set_auditable_operations(
12        &mut self,
13        operations: AuditOperationFlags,
14    ) -> Result<(), Error> {
15        let mut next = self.configuration_internal();
16        next.auditable_operations = operations;
17        self.change_configuration(next, None)
18    }
19    /// Set the command-priority filter atomically.
20    pub fn set_audit_priority_filter(&mut self, filter: BACnetPriorityFilter) -> Result<(), Error> {
21        let mut next = self.configuration_internal();
22        next.audit_priority_filter = filter;
23        self.change_configuration(next, None)
24    }
25    /// Set confirmed delivery mode atomically.
26    pub fn set_issue_confirmed_notifications(&mut self, confirmed: bool) -> Result<(), Error> {
27        let mut next = self.configuration_internal();
28        next.confirmed = confirmed;
29        self.change_configuration(next, None)
30    }
31    /// Set optional selectors: absent means catch-all; present empty means no nominal targets.
32    pub fn set_monitored_objects(
33        &mut self,
34        selectors: Option<Vec<BACnetObjectSelector>>,
35    ) -> Result<(), Error> {
36        let mut next = self.configuration_internal();
37        next.monitored_objects = selectors;
38        self.change_configuration(next, None)
39    }
40}
41
42#[cfg(test)]
43mod tests {
44    use super::*;
45    #[test]
46    fn audit_reporter_configuration_aba_invalidates_delivery_authority_and_failed_updates_do_not() {
47        let mut reporter = AuditReporterObject::new(1, "AR").unwrap();
48        reporter.set_audit_level(AuditLevel::AUDIT_ALL).unwrap();
49        let status = reporter.status_internal();
50        status.set_configured(true);
51        let original = status.begin_delivery();
52        assert!(reporter
53            .configure_audit_reporter_internal(
54                AuditLevel::DEFAULT,
55                AuditOperationFlags::empty(),
56                true,
57                Some(vec![]),
58                BACnetPriorityFilter::empty(),
59                None
60            )
61            .is_err());
62        assert_eq!(
63            status.begin_delivery(),
64            original,
65            "invalid full configuration is atomic"
66        );
67        reporter.set_issue_confirmed_notifications(true).unwrap();
68        reporter.set_issue_confirmed_notifications(false).unwrap();
69        let current = status.begin_delivery();
70        assert_ne!(original, current);
71        status.complete_delivery(original, false);
72        assert_eq!(reporter.reliability(), Reliability::NO_FAULT_DETECTED);
73        status.complete_delivery(current, false);
74        status.complete_delivery(original, true);
75        assert_eq!(reporter.reliability(), Reliability::COMMUNICATION_FAILURE);
76        status.complete_delivery(status.begin_delivery(), true);
77        assert_eq!(reporter.reliability(), Reliability::NO_FAULT_DETECTED);
78    }
79}