bacnet_server/handlers/alarm_event/
acknowledge_alarm.rs1use super::super::*;
7use bacnet_objects::event::EventStateChange;
8use bacnet_types::bitstring::EventTransitionBits;
9
10#[derive(Debug, Clone, PartialEq, Eq)]
12pub struct AcknowledgmentNotificationContext {
13 pub change: EventStateChange,
15 pub event_type: EventType,
17 pub distribute: bool,
19}
20
21#[derive(Debug, Clone, PartialEq, Eq)]
23pub struct AcceptedAcknowledgeAlarm {
24 pub event_object_identifier: ObjectIdentifier,
26 pub notification: Option<AcknowledgmentNotificationContext>,
31}
32
33pub fn handle_acknowledge_alarm(
37 db: &mut ObjectDatabase,
38 service_data: &[u8],
39) -> Result<AcceptedAcknowledgeAlarm, Error> {
40 let request =
41 AcknowledgeAlarmRequest::decode(service_data).map_err(Error::into_request_reject)?;
42
43 let object = db
44 .get_mut(&request.event_object_identifier)
45 .ok_or(Error::protocol(
46 ErrorClass::OBJECT,
47 ErrorCode::UNKNOWN_OBJECT,
48 ))?;
49
50 let change = object.acknowledge_alarm_correlated_detailed_internal(
51 request.event_state_acknowledged,
52 &request.timestamp,
53 )?;
54
55 let notification = change.and_then(|change| {
56 let algorithm = object.enrollment_summary_capability_internal()?.event_type;
57 let PropertyValue::BitString { unused_bits, data } = object
58 .read_property(PropertyIdentifier::EVENT_ENABLE, None)
59 .ok()?
60 else {
61 return None;
62 };
63 if unused_bits != 5 || data.len() != 1 || data[0] & 0x1f != 0 {
64 return None;
65 }
66 let distribute =
67 EventTransitionBits::from_bacnet(&data).contains(change.transition().bit_mask());
68 let event_type = change.event_type(algorithm);
69 Some(AcknowledgmentNotificationContext {
70 change,
71 event_type,
72 distribute,
73 })
74 });
75
76 let _ = (
80 request.acknowledging_process_identifier,
81 request.acknowledgment_source,
82 request.time_of_acknowledgment,
83 );
84
85 Ok(AcceptedAcknowledgeAlarm {
86 event_object_identifier: request.event_object_identifier,
87 notification,
88 })
89}