bacnet_client/client/
event_notifications.rs1use super::*;
2use bacnet_encoding::constructed::decode_event_notification_tolerant;
3use bacnet_services::alarm_event::EventNotificationRequest;
4
5pub const DEFAULT_EVENT_CHANNEL_CAPACITY: usize = 64;
7
8pub const MAX_EVENT_CHANNEL_CAPACITY: usize = 65_536;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13pub enum EventNotificationDelivery {
14 Confirmed,
16 Unconfirmed,
18}
19
20#[derive(Debug, Clone)]
22pub struct ReceivedEventNotification {
23 pub notification: EventNotificationRequest,
26 pub source_mac: MacAddr,
28 pub source_network: Option<u16>,
30 pub source_address: Option<MacAddr>,
32 pub delivery: EventNotificationDelivery,
34}
35
36impl ReceivedEventNotification {
37 fn decode(
38 data: &[u8],
39 source_mac: &[u8],
40 source_network: &Option<NpduAddress>,
41 delivery: EventNotificationDelivery,
42 ) -> Result<Self, Error> {
43 let notification = decode_event_notification_tolerant(data)?;
44 let (network, address) = match source_network {
45 Some(source) if !source.mac_address.is_empty() => {
46 (Some(source.network), Some(source.mac_address.clone()))
47 }
48 _ => (None, None),
49 };
50 Ok(Self {
51 notification,
52 source_mac: MacAddr::from_slice(source_mac),
53 source_network: network,
54 source_address: address,
55 delivery,
56 })
57 }
58}
59
60impl ClientOptions {
61 pub fn with_event_channel_capacity(mut self, capacity: usize) -> Self {
64 self.event_channel_capacity = capacity;
65 self
66 }
67}
68
69impl<T: TransportPort + 'static> BACnetClient<T> {
70 pub fn event_notifications(&self) -> broadcast::Receiver<ReceivedEventNotification> {
78 self.event_tx.subscribe()
79 }
80
81 pub(super) async fn receive_confirmed_event_notification(
82 network: &Arc<NetworkLayer<T>>,
83 event_tx: &broadcast::Sender<ReceivedEventNotification>,
84 source_mac: &[u8],
85 source_network: &Option<NpduAddress>,
86 reply: InboundReply,
87 req: ConfirmedRequestPdu,
88 decode_warning: &WarnThrottle,
89 ) {
90 let received = match ReceivedEventNotification::decode(
91 &req.service_request,
92 source_mac,
93 source_network,
94 EventNotificationDelivery::Confirmed,
95 ) {
96 Ok(received) => received,
97 Err(error) => {
98 warn_throttled!(
99 decode_warning,
100 %error,
101 "Failed to decode ConfirmedEventNotification"
102 );
103 let reject_reason = error
106 .reject_reason()
107 .unwrap_or(RejectReason::INVALID_DATA_ENCODING);
108 Self::send_confirmed_request_reject(
109 network,
110 source_mac,
111 source_network,
112 reply,
113 req.invoke_id,
114 reject_reason,
115 )
116 .await;
117 return;
118 }
119 };
120 let _ = event_tx.send(received);
121 let ack = Apdu::SimpleAck(SimpleAck {
122 invoke_id: req.invoke_id,
123 service_choice: req.service_choice,
124 });
125 let mut buf = BytesMut::with_capacity(3);
126 if let Err(error) = encode_apdu(&mut buf, &ack) {
127 warn!(%error, "Failed to encode event notification acknowledgment");
128 return;
129 }
130 if let Err(error) =
131 Self::send_received_reply_apdu(network, &buf, source_mac, source_network, reply).await
132 {
133 warn!(%error, "Failed to send event notification acknowledgment");
134 }
135 }
136}
137
138pub(super) fn receive_unconfirmed_event_notification(
139 event_tx: &broadcast::Sender<ReceivedEventNotification>,
140 source_mac: &[u8],
141 source_network: &Option<NpduAddress>,
142 data: &[u8],
143 decode_warning: &WarnThrottle,
144) {
145 match ReceivedEventNotification::decode(
146 data,
147 source_mac,
148 source_network,
149 EventNotificationDelivery::Unconfirmed,
150 ) {
151 Ok(received) => {
152 let _ = event_tx.send(received);
153 }
154 Err(error) => {
155 warn_throttled!(
156 decode_warning,
157 %error,
158 "Failed to decode UnconfirmedEventNotification"
159 );
160 }
161 }
162}