From d0ef2e953780ebac7274ba4e4d8cdd7c116bd16c Mon Sep 17 00:00:00 2001 From: Andrew Mackenzie Date: Thu, 6 Nov 2025 14:26:30 +0100 Subject: [PATCH 1/3] Handle EOF when DuplexStream is closed, avoiding a panic. Fixes #75 --- src/utils_internal.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/utils_internal.rs b/src/utils_internal.rs index 17dd032..067a1b9 100644 --- a/src/utils_internal.rs +++ b/src/utils_internal.rs @@ -331,7 +331,9 @@ pub async fn build_ble_stream( // Data from user, forward it to the device from_server = server.read(&mut buf) => { let len = from_server.map_err(duplex_write_error_fn)?; - ble_handler.write_to_radio(&buf[..len]).await?; + if len != 0 { + ble_handler.write_to_radio(&buf[..len]).await?; + } }, event = adapter_events.next() => { if Some(AdapterEvent::Disconnected) == event { From 45c7ce0c8e7f8f519fdf6930e25373d5514ae5bf Mon Sep 17 00:00:00 2001 From: Andrew Mackenzie Date: Fri, 7 Nov 2025 13:03:38 +0100 Subject: [PATCH 2/3] Additional protection from panics on invalid input buffer lengths. --- src/connections/ble_handler.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/connections/ble_handler.rs b/src/connections/ble_handler.rs index 1d5d195..c3ea085 100644 --- a/src/connections/ble_handler.rs +++ b/src/connections/ble_handler.rs @@ -243,7 +243,13 @@ impl BleHandler { pub async fn write_to_radio(&self, buffer: &[u8]) -> Result<(), Error> { self.radio // TODO: remove the skipping of the first 4 bytes - .write(&self.toradio_char, &buffer[4..], WriteType::WithResponse) + .write( + &self.toradio_char, + buffer.get(4..).ok_or(Error::InvalidaDataSize { + data_length: buffer.len(), + })?, + WriteType::WithResponse, + ) .await .map_err(|e: btleplug::Error| { Error::InternalStreamError(InternalStreamError::StreamWriteError { From 5d7e4ca3bb3e7ce9774635a86471b65e4cded876 Mon Sep 17 00:00:00 2001 From: Andrew Mackenzie Date: Wed, 12 Nov 2025 18:27:20 +0100 Subject: [PATCH 3/3] Clarify the use of the "to" field of MeshPacket and how to determine if a packet was sent to a channel or a node. --- src/generated/meshtastic.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/generated/meshtastic.rs b/src/generated/meshtastic.rs index 76ce5a3..bedcba6 100644 --- a/src/generated/meshtastic.rs +++ b/src/generated/meshtastic.rs @@ -5111,7 +5111,11 @@ pub struct MeshPacket { #[prost(fixed32, tag = "1")] pub from: u32, /// - /// The (immediate) destination for this packet + /// The (immediate) destination for this packet. + /// If the value is u32::MAX, this indicates that the packet was not destined for a specific + /// node, but for a channel as indicated by the value of `channel` below. + /// If the value is not u32MAX, this indicates that the packet was destined for a specific + /// node (i.e. a kind of "Direct Message" to this node) and not broadcast on a channel. #[prost(fixed32, tag = "2")] pub to: u32, ///