bacnet_objects/audit/
reporter_object.rs1use super::*;
4
5impl BACnetObject for AuditReporterObject {
6 fn audit_reporter_internal(&self) -> Option<&AuditReporterObject> {
7 Some(self)
8 }
9
10 fn configure_audit_reporter_internal(
11 &mut self,
12 level: AuditLevel,
13 operations: AuditOperationFlags,
14 confirmed: bool,
15 selectors: Option<Vec<BACnetObjectSelector>>,
16 priorities: BACnetPriorityFilter,
17 maximum_send_delay: Option<crate::audit::AuditSendDelay>,
18 ) -> Result<(), Error> {
19 let mut next = self.configuration_internal();
20 next.audit_level = level;
21 next.auditable_operations = operations;
22 next.confirmed = confirmed;
23 next.monitored_objects = selectors;
24 next.audit_priority_filter = priorities;
25 next.maximum_send_delay = maximum_send_delay;
26 self.change_configuration(next, None)
27 }
28
29 fn audit_reporter_authority_internal(&mut self) -> Option<AuditReporterAuthority<'_>> {
30 Some(AuditReporterAuthority(self))
31 }
32 fn bind_clock_internal(&mut self, clock: Option<Arc<dyn ClockReader>>) {
33 self.clock = clock;
34 }
35
36 fn object_identifier(&self) -> ObjectIdentifier {
37 self.oid
38 }
39
40 fn object_name(&self) -> &str {
41 &self.name
42 }
43
44 fn property_metadata(&self) -> Cow<'_, [PropertyMetadata]> {
45 reporter_metadata::effective_properties(
46 self.configuration_internal().monitored_objects.is_some(),
47 self.configuration_internal().maximum_send_delay.is_some(),
48 )
49 }
50
51 fn read_property(
52 &self,
53 property: PropertyIdentifier,
54 array_index: Option<u32>,
55 ) -> Result<PropertyValue, Error> {
56 let configuration = self.configuration_internal();
57 match property {
58 p if p == PropertyIdentifier::OBJECT_IDENTIFIER => {
59 Ok(PropertyValue::ObjectIdentifier(self.oid))
60 }
61 p if p == PropertyIdentifier::OBJECT_NAME => {
62 Ok(PropertyValue::CharacterString(self.name.clone()))
63 }
64 p if p == PropertyIdentifier::DESCRIPTION => Ok(PropertyValue::CharacterString(
65 configuration.description.clone(),
66 )),
67 p if p == PropertyIdentifier::OBJECT_TYPE => Ok(PropertyValue::Enumerated(
68 ObjectType::AUDIT_REPORTER.to_raw(),
69 )),
70 p if p == PropertyIdentifier::STATUS_FLAGS => Ok(PropertyValue::BitString {
71 unused_bits: 4,
72 data: vec![if self.reliability() == Reliability::NO_FAULT_DETECTED {
73 0
74 } else {
75 0x40
76 }],
77 }),
78 p if p == PropertyIdentifier::RELIABILITY => {
79 Ok(PropertyValue::Enumerated(self.reliability().to_raw()))
80 }
81 p if p == PropertyIdentifier::EVENT_STATE => {
82 Ok(PropertyValue::Enumerated(EventState::NORMAL.to_raw()))
83 }
84 p if p == PropertyIdentifier::AUDIT_LEVEL => Ok(PropertyValue::Enumerated(
85 configuration.audit_level.to_raw(),
86 )),
87 p if p == PropertyIdentifier::AUDIT_SOURCE_REPORTER => {
88 Ok(PropertyValue::Boolean(false))
89 }
90 p if p == PropertyIdentifier::AUDITABLE_OPERATIONS => {
91 let (unused_bits, data) = configuration.auditable_operations.to_bacnet();
92 Ok(PropertyValue::BitString { unused_bits, data })
93 }
94 p if p == PropertyIdentifier::AUDIT_PRIORITY_FILTER => {
95 let (unused_bits, data) = configuration.audit_priority_filter.to_bacnet();
96 Ok(PropertyValue::BitString { unused_bits, data })
97 }
98 p if p == PropertyIdentifier::ISSUE_CONFIRMED_NOTIFICATIONS => {
99 Ok(PropertyValue::Boolean(self.status.confirmed()))
100 }
101 p if p == PropertyIdentifier::MONITORED_OBJECTS
102 && configuration.monitored_objects.is_some() =>
103 {
104 let selectors = configuration
105 .monitored_objects
106 .as_ref()
107 .expect("presence checked");
108 match array_index {
109 None => Ok(PropertyValue::List(
110 selectors
111 .iter()
112 .map(BACnetObjectSelector::encode_property_value)
113 .collect(),
114 )),
115 Some(0) => Ok(PropertyValue::Unsigned(selectors.len() as u64)),
116 Some(index) => selectors
117 .get((index - 1) as usize)
118 .map(BACnetObjectSelector::encode_property_value)
119 .ok_or_else(crate::common::invalid_array_index_error),
120 }
121 }
122 p if matches!(
123 p,
124 PropertyIdentifier::MAXIMUM_SEND_DELAY | PropertyIdentifier::SEND_NOW
125 ) && configuration.maximum_send_delay.is_some() =>
126 {
127 if array_index.is_some() {
128 return Err(crate::common::property_is_not_an_array_error());
129 }
130 if p == PropertyIdentifier::SEND_NOW {
131 Ok(PropertyValue::Boolean(self.status.send_now()))
132 } else {
133 Ok(PropertyValue::Unsigned(u64::from(
134 configuration.maximum_send_delay.unwrap().seconds(),
135 )))
136 }
137 }
138 p if p == PropertyIdentifier::PROPERTY_LIST => {
139 read_property_list_property(&self.property_list(), array_index)
140 }
141 _ => Err(Error::Protocol {
142 class: ErrorClass::PROPERTY.to_raw() as u32,
143 code: ErrorCode::UNKNOWN_PROPERTY.to_raw() as u32,
144 }),
145 }
146 }
147
148 fn write_property(
149 &mut self,
150 property: PropertyIdentifier,
151 array_index: Option<u32>,
152 value: PropertyValue,
153 _priority: Option<u8>,
154 ) -> Result<(), Error> {
155 if matches!(
156 property,
157 PropertyIdentifier::DESCRIPTION
158 | PropertyIdentifier::MAXIMUM_SEND_DELAY
159 | PropertyIdentifier::SEND_NOW
160 ) {
161 return AuditReporterAuthority(self).write_property(property, value, array_index, None);
162 }
163 Err(crate::common::unhandled_write_error(
164 self.property_metadata().as_ref(),
165 property,
166 array_index,
167 ))
168 }
169
170 fn property_list(&self) -> Cow<'static, [PropertyIdentifier]> {
171 crate::property_metadata::property_list_from_metadata(&self.property_metadata())
172 }
173}
174
175#[cfg(test)]
176#[path = "source_reporter_tests.rs"]
177mod source_reporter_tests;