From 9c3724b2e13c5d0e3a635ad50bf099dfe1fa9abc Mon Sep 17 00:00:00 2001 From: Ivan Malison Date: Mon, 20 Jul 2026 12:28:14 -0700 Subject: [PATCH] fix split BLE DFU notification readiness --- rmk/src/split/ble/peripheral.rs | 20 +++++++++++++++++++- rmk/src/split/peripheral.rs | 2 +- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/rmk/src/split/ble/peripheral.rs b/rmk/src/split/ble/peripheral.rs index cff1b2e8e..43a1ba2a5 100644 --- a/rmk/src/split/ble/peripheral.rs +++ b/rmk/src/split/ble/peripheral.rs @@ -68,6 +68,12 @@ impl<'stack, 'server, 'c, P: PacketPool> SplitReader for BleSplitPeripheralDrive return Err(SplitDriverError::Disconnected); } GattConnectionEvent::Gatt { event: gatt_event } => { + #[cfg(feature = "dfu_split")] + let split_notifications_cccd_written = matches!( + &gatt_event, + GattEvent::Write(event) + if Some(event.handle()) == self.message_to_central.cccd_handle + ); match &gatt_event { GattEvent::Read(event) => { info!("Gatt read event: {:?}", event.handle()); @@ -96,6 +102,14 @@ impl<'stack, 'server, 'c, P: PacketPool> SplitReader for BleSplitPeripheralDrive Ok(r) => r.send().await, Err(e) => warn!("[gatt] error sending response: {:?}", e), } + // Accepting the CCCD write updates TrouBLE's subscription state. + // Announce only when this write enabled notifications. + #[cfg(feature = "dfu_split")] + if split_notifications_cccd_written && self.message_to_central.should_notify(self.conn) { + let hash = crate::dfu::read_embedded_firmware_hash(); + info!("dfu_split: notifications enabled, announcing hash {:#x}", hash); + self.write(&SplitMessage::FirmwareHashResponse(hash)).await.ok(); + } } GattConnectionEvent::ConnectionParamsUpdated { conn_interval, @@ -131,7 +145,11 @@ impl<'stack, 'server, 'c, P: PacketPool> SplitWriter for BleSplitPeripheralDrive .notify(self.conn, &buf, true) .await .map_err(|e| { - error!("BLE notify error: {:?}", e); + if e == Error::NotSubscribed { + debug!("Central has not subscribed to split notifications yet"); + } else { + error!("BLE notify error: {:?}", e); + } SplitDriverError::BleError(1) })?; Ok(buf.len()) diff --git a/rmk/src/split/peripheral.rs b/rmk/src/split/peripheral.rs index f1a84104e..4e0eed705 100644 --- a/rmk/src/split/peripheral.rs +++ b/rmk/src/split/peripheral.rs @@ -80,7 +80,7 @@ impl SplitPeripheral { pub(crate) async fn run(&mut self) { // Proactively announce our firmware hash so the central can detect // us even when it booted first and already gave up waiting for a query response. - #[cfg(feature = "dfu_split")] + #[cfg(all(feature = "dfu_split", not(feature = "_ble")))] { let hash = crate::dfu::read_embedded_firmware_hash(); self.split_driver