use super::super::*;
use bacnet_objects::event::EventStateChange;
use bacnet_types::bitstring::EventTransitionBits;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AcknowledgmentNotificationContext {
pub change: EventStateChange,
pub event_type: EventType,
pub distribute: bool,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AcceptedAcknowledgeAlarm {
pub event_object_identifier: ObjectIdentifier,
pub notification: Option<AcknowledgmentNotificationContext>,
}
pub fn handle_acknowledge_alarm(
db: &mut ObjectDatabase,
service_data: &[u8],
) -> Result<AcceptedAcknowledgeAlarm, Error> {
let request =
AcknowledgeAlarmRequest::decode(service_data).map_err(Error::into_request_reject)?;
let object = db
.get_mut(&request.event_object_identifier)
.ok_or(Error::protocol(
ErrorClass::OBJECT,
ErrorCode::UNKNOWN_OBJECT,
))?;
let change = object.acknowledge_alarm_correlated_detailed_internal(
request.event_state_acknowledged,
&request.timestamp,
)?;
let notification = change.and_then(|change| {
let algorithm = object.enrollment_summary_capability_internal()?.event_type;
let PropertyValue::BitString { unused_bits, data } = object
.read_property(PropertyIdentifier::EVENT_ENABLE, None)
.ok()?
else {
return None;
};
if unused_bits != 5 || data.len() != 1 || data[0] & 0x1f != 0 {
return None;
}
let distribute =
EventTransitionBits::from_bacnet(&data).contains(change.transition().bit_mask());
let event_type = change.event_type(algorithm);
Some(AcknowledgmentNotificationContext {
change,
event_type,
distribute,
})
});
let _ = (
request.acknowledging_process_identifier,
request.acknowledgment_source,
request.time_of_acknowledgment,
);
Ok(AcceptedAcknowledgeAlarm {
event_object_identifier: request.event_object_identifier,
notification,
})
}