From bba8c3a24b322461833046b29c647216ff9b2ee5 Mon Sep 17 00:00:00 2001 From: puddly <32534428+puddly@users.noreply.github.com> Date: Thu, 17 Sep 2026 20:05:14 +0000 Subject: [PATCH] Indicate to the client if incoming packets were APS encrypted --- crates/ziggurat-driver/src/zigbee_stack.rs | 77 +++++++++++----------- crates/ziggurat-protocol/src/bridge.rs | 2 + crates/ziggurat-protocol/src/wire.rs | 3 +- 3 files changed, 44 insertions(+), 38 deletions(-) diff --git a/crates/ziggurat-driver/src/zigbee_stack.rs b/crates/ziggurat-driver/src/zigbee_stack.rs index 70e464e..0eb1baf 100644 --- a/crates/ziggurat-driver/src/zigbee_stack.rs +++ b/crates/ziggurat-driver/src/zigbee_stack.rs @@ -866,6 +866,7 @@ pub enum ZigbeeNotification { dst_ep: u8, lqi: u8, rssi: i8, + aps_encrypted: bool, data: Vec, }, /// The outgoing NWK security frame counter has advanced; the client should persist @@ -1258,47 +1259,48 @@ impl ZigbeeStack { continue; }; - let (aps_frame, aps_source_eui64) = match parse_aps_frame(aps_payload) { - Ok(ApsFrame::Data(data)) => (data, None), - Ok(ApsFrame::EncryptedData(encrypted)) => { - match self.decrypt_aps_data_frame(&nwk_frame, &encrypted) { - Some((data, source_eui64)) => (data, Some(source_eui64)), - None => { - tracing::warn!( - "Failed to decrypt APS data frame from {:?}", + let (aps_frame, aps_source_eui64, aps_encrypted) = + match parse_aps_frame(aps_payload) { + Ok(ApsFrame::Data(data)) => (data, None, false), + Ok(ApsFrame::EncryptedData(encrypted)) => { + match self.decrypt_aps_data_frame(&nwk_frame, &encrypted) { + Some((data, source_eui64)) => (data, Some(source_eui64), true), + None => { + tracing::warn!( + "Failed to decrypt APS data frame from {:?}", + nwk_frame.nwk_header.source + ); + continue; + } + } + } + Ok(ApsFrame::Ack(ack)) => { + self.handle_aps_ack(&nwk_frame, &ack); + continue; + } + Ok(ApsFrame::EncryptedAck(encrypted)) => { + match self.decrypt_aps_ack_frame(&nwk_frame, &encrypted) { + Some(ack) => self.handle_aps_ack(&nwk_frame, &ack), + None => tracing::warn!( + "Failed to decrypt APS ACK from {:?}", nwk_frame.nwk_header.source - ); - continue; + ), } + continue; } - } - Ok(ApsFrame::Ack(ack)) => { - self.handle_aps_ack(&nwk_frame, &ack); - continue; - } - Ok(ApsFrame::EncryptedAck(encrypted)) => { - match self.decrypt_aps_ack_frame(&nwk_frame, &encrypted) { - Some(ack) => self.handle_aps_ack(&nwk_frame, &ack), - None => tracing::warn!( - "Failed to decrypt APS ACK from {:?}", - nwk_frame.nwk_header.source - ), + Ok(ApsFrame::Command(cmd)) => { + self.handle_aps_command_frame(&nwk_frame, &cmd, None, None); + continue; } - continue; - } - Ok(ApsFrame::Command(cmd)) => { - self.handle_aps_command_frame(&nwk_frame, &cmd, None, None); - continue; - } - Ok(ApsFrame::EncryptedCommand(encrypted_cmd)) => { - self.handle_encrypted_aps_command_frame(&nwk_frame, &encrypted_cmd); - continue; - } - Err(e) => { - tracing::warn!("Error parsing APS frame: {e:?}"); - continue; - } - }; + Ok(ApsFrame::EncryptedCommand(encrypted_cmd)) => { + self.handle_encrypted_aps_command_frame(&nwk_frame, &encrypted_cmd); + continue; + } + Err(e) => { + tracing::warn!("Error parsing APS frame: {e:?}"); + continue; + } + }; tracing::trace!("Received APS data frame: {aps_frame:?}"); @@ -1335,6 +1337,7 @@ impl ZigbeeStack { dst_ep: aps_frame.destination_endpoint.unwrap_or(0), lqi: packet.lqi, rssi: packet.rssi, + aps_encrypted, data: aps_frame.asdu.to_vec(), }; self.push_notification(notification); diff --git a/crates/ziggurat-protocol/src/bridge.rs b/crates/ziggurat-protocol/src/bridge.rs index 4e5975e..2f2c7cf 100644 --- a/crates/ziggurat-protocol/src/bridge.rs +++ b/crates/ziggurat-protocol/src/bridge.rs @@ -452,11 +452,13 @@ pub fn notification_frame(update: &ZigbeeNotification) -> Option> { dst_ep, lqi, rssi, + aps_encrypted, data, } => Notification::ReceivedAps(ReceivedApsPayload { source: *source, destination: *destination, has_group: group.is_some(), + aps_encrypted: *aps_encrypted, group: group.unwrap_or(0), profile_id: *profile_id, cluster_id: *cluster_id, diff --git a/crates/ziggurat-protocol/src/wire.rs b/crates/ziggurat-protocol/src/wire.rs index 871f546..f8344da 100644 --- a/crates/ziggurat-protocol/src/wire.rs +++ b/crates/ziggurat-protocol/src/wire.rs @@ -662,7 +662,8 @@ pub struct ReceivedApsPayload { pub source: Nwk, pub destination: Nwk, pub has_group: bool, - pub reserved: u7, + pub aps_encrypted: bool, + pub reserved: u6, pub group: u16, pub profile_id: u16, pub cluster_id: u16,