Skip to content

Commit

Permalink
Merge pull request #5 from lukipuki/ble-setup
Browse files Browse the repository at this point in the history
Add a function to find a BLE peripheral
  • Loading branch information
ajmcquilkin authored Jan 23, 2024
2 parents 9bff8a9 + 6841a64 commit e77d168
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 1 deletion.
6 changes: 6 additions & 0 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ jobs:
- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable

- name: Install dependencies (Ubuntu only)
if: matrix.platform == 'ubuntu-20.04'
run: |
sudo apt-get update
sudo apt-get install -y libdbus-1-dev pkg-config
- name: Run test suite
working-directory: ./
run: cargo test
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,5 @@ specta = { git = "https://github.com/ajmcquilkin/specta.git", version = ">= 1.0.
serde = { version = "1.0", features = ["derive"], optional = true }
serde_json = { version = "1.0", optional = true }
thiserror = "1.0.48"
uuid = "1.6.1"
btleplug = "0.11.5"
4 changes: 4 additions & 0 deletions src/errors_internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ pub enum InternalChannelError {
IncomingStreamDataWriteError(#[from] tokio::sync::mpsc::error::SendError<IncomingStreamData>),
}

#[derive(Error, Debug)]
#[error("Bluetooth low energy connection error")]
pub struct BleConnectionError();

mod test {
#[allow(dead_code)]
fn is_send<T: Send>() {}
Expand Down
54 changes: 53 additions & 1 deletion src/utils_internal.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
use crate::errors_internal::{BleConnectionError, Error};
use btleplug::api::{Central, Manager as _, Peripheral as _, ScanFilter};
use btleplug::platform::{Adapter, Manager, Peripheral};
use log::error;
use std::time::Duration;
use std::time::UNIX_EPOCH;
use uuid::Uuid;

use rand::{distributions::Standard, prelude::Distribution, Rng};
use tokio_serial::{available_ports, SerialPort, SerialStream};
Expand All @@ -8,7 +13,6 @@ use crate::connections::stream_api::StreamHandle;
use crate::connections::wrappers::encoded_data::{
EncodedToRadioPacket, EncodedToRadioPacketWithHeader,
};
use crate::errors_internal::Error;

// Constants declarations

Expand Down Expand Up @@ -194,6 +198,54 @@ pub async fn build_tcp_stream(
Ok(StreamHandle::from_stream(stream))
}

const MSH_SERVICE: Uuid = Uuid::from_u128(0x6ba1b218_15a8_461f_9fa8_5dcae273eafd);

async fn scan_peripherals(adapter: &Adapter) -> Result<Vec<Peripheral>, btleplug::Error> {
adapter
.start_scan(ScanFilter {
services: vec![MSH_SERVICE],
})
.await?;
adapter.peripherals().await
}

/// 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: String) -> Result<Peripheral, 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),
description: "Failed to scan for BLE devices".to_owned(),
};
let manager = Manager::new().await.map_err(scan_error_fn)?;
let adapters = manager.adapters().await.map_err(scan_error_fn)?;

for adapter in &adapters {
let peripherals = scan_peripherals(&adapter).await;
match peripherals {
Err(e) => {
error!("Error while scanning for meshtastic peripherals: {e:?}");
// We continue, as there can be another adapter that can work
continue;
}
Ok(peripherals) => {
for peripheral in peripherals {
if let Ok(Some(peripheral_properties)) = peripheral.properties().await {
if peripheral_properties.local_name == Some(name.clone()) {
return Ok(peripheral);
}
}
}
}
}
}
Err(Error::StreamBuildError {
source: Box::new(BleConnectionError()),
description: format!("Failed to find {name}, or meshtastic is not running on the device")
+ ", or it's already connected.",
})
}

/// A helper method to generate random numbers using the `rand` crate.
///
/// This method is intended to be used to generate random id values. This method
Expand Down

0 comments on commit e77d168

Please sign in to comment.