bacnet_server/handlers/alarm_event/
acknowledge_alarm.rs1use super::super::*;
7use bacnet_objects::event::EventStateChange;
8
9#[derive(Debug, Clone, PartialEq, Eq)]
11pub struct AcknowledgmentNotificationContext {
12 pub change: EventStateChange,
14 pub event_type: EventType,
16 pub distribute: bool,
18}
19
20#[derive(Debug, Clone, PartialEq, Eq)]
22pub struct AcceptedAcknowledgeAlarm {
23 pub event_object_identifier: ObjectIdentifier,
25 pub notification: Option<AcknowledgmentNotificationContext>,
30}
31
32pub fn handle_acknowledge_alarm(
36 db: &mut ObjectDatabase,
37 service_data: &[u8],
38) -> Result<AcceptedAcknowledgeAlarm, Error> {
39 let request = AcknowledgeAlarmRequest::decode(service_data)?;
40 let event_state = EventState::from_raw(request.event_state_acknowledged);
41
42 let object = db
43 .get_mut(&request.event_object_identifier)
44 .ok_or(Error::Protocol {
45 class: ErrorClass::OBJECT.to_raw() as u32,
46 code: ErrorCode::UNKNOWN_OBJECT.to_raw() as u32,
47 })?;
48
49 let change =
50 object.acknowledge_alarm_correlated_detailed_internal(event_state, &request.timestamp)?;
51
52 let notification = change.and_then(|change| {
53 let algorithm = object.enrollment_summary_capability_internal()?.event_type;
54 let PropertyValue::BitString { unused_bits, data } = object
55 .read_property(PropertyIdentifier::EVENT_ENABLE, None)
56 .ok()?
57 else {
58 return None;
59 };
60 if unused_bits != 5 || data.len() != 1 || data[0] & 0x1f != 0 {
61 return None;
62 }
63 let enabled = bacnet_types::bitstring::unpack_octet(&data, 3);
64 let distribute = enabled & change.transition().bit_mask() != 0;
65 let event_type = change.event_type(algorithm);
66 Some(AcknowledgmentNotificationContext {
67 change,
68 event_type,
69 distribute,
70 })
71 });
72
73 let _ = (
77 request.acknowledging_process_identifier,
78 request.acknowledgment_source,
79 request.time_of_acknowledgment,
80 );
81
82 Ok(AcceptedAcknowledgeAlarm {
83 event_object_identifier: request.event_object_identifier,
84 notification,
85 })
86}