Skip to content

Commit

Permalink
Receive notifications about device being disconnected
Browse files Browse the repository at this point in the history
  • Loading branch information
lukipuki committed Feb 2, 2024
1 parent 4a15d8d commit 2172b93
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 5 deletions.
31 changes: 26 additions & 5 deletions src/connections/ble_handler.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use btleplug::api::{
Central, Characteristic, Manager as _, Peripheral as _, ScanFilter, ValueNotification,
WriteType,
Central, CentralEvent, Characteristic, Manager as _, Peripheral as _, ScanFilter,
ValueNotification, WriteType,
};
use btleplug::platform::{Adapter, Manager, Peripheral};
use futures_util::stream::BoxStream;
Expand All @@ -16,6 +16,7 @@ const FROMNUM: Uuid = Uuid::from_u128(0xed9da18c_a800_4f66_a670_aa7547e34453);

pub struct BleHandler {
radio: Peripheral,
adapter: Adapter,
toradio_char: Characteristic,
fromradio_char: Characteristic,
fromnum_char: Characteristic,
Expand All @@ -24,7 +25,7 @@ pub struct BleHandler {
#[allow(dead_code)]
impl BleHandler {
pub async fn new(name: String) -> Result<Self, Error> {
let radio = Self::find_ble_radio(&name).await?;
let (radio, adapter) = Self::find_ble_radio(&name).await?;
radio.connect().await.map_err(|e| Error::StreamBuildError {
source: Box::new(e),
description: format!("Failed to connect to the device {name}"),
Expand All @@ -33,6 +34,7 @@ impl BleHandler {
Self::find_characteristics(&radio).await?;
Ok(BleHandler {
radio,
adapter,
toradio_char,
fromradio_char,
fromnum_char,
Expand All @@ -50,7 +52,9 @@ impl BleHandler {

/// Finds a BLE radio matching a given name and running meshtastic.
/// It searches for the 'MSH_SERVICE' running on the device.
async fn find_ble_radio(name: &str) -> Result<Peripheral, Error> {
///
/// It also returns the associated adapter that can reach this radio.
async fn find_ble_radio(name: &str) -> Result<(Peripheral, Adapter), Error> {
//TODO: support searching both by a name and by a MAC address
let scan_error_fn = |e: btleplug::Error| Error::StreamBuildError {
source: Box::new(e),
Expand All @@ -72,7 +76,7 @@ impl BleHandler {
for peripheral in peripherals {
if let Ok(Some(peripheral_properties)) = peripheral.properties().await {
if peripheral_properties.local_name == needle {
return Ok(peripheral);
return Ok((peripheral, adapter.clone()));
}
}
}
Expand Down Expand Up @@ -178,4 +182,21 @@ impl BleHandler {
_ => None,
}
}

pub async fn adapter_events(&self) -> Result<BoxStream<CentralEvent>, Error> {
self.adapter
.events()
.await
.map_err(|e| Error::StreamBuildError {
source: Box::new(e),
description: format!("Failed to listen to device events"),
})
}

pub fn is_disconnected_event(&self, event: Option<CentralEvent>) -> bool {
if let Some(CentralEvent::DeviceDisconnected(peripheral_id)) = event {
return self.radio.id() == peripheral_id;
}
return false;
}
}
5 changes: 5 additions & 0 deletions src/errors_internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ pub enum InternalStreamError {
StreamWriteError {
source: Box<dyn std::error::Error + Send + Sync + 'static>,
},

/// An error indicatiing that the connection has been lost and both reading and writing are
/// not possible anymore.
#[error("Connection lost")]
ConnectionLost,
}

/// An enum that defines the possible internal errors that can occur within the library when handling data channels.
Expand Down

0 comments on commit 2172b93

Please sign in to comment.