[fp-rs] Temporarily removing bluetooth lib abstraction layer, applications now talk directly to platform code.

Rust's type system is causing issues with notating associated types. For
now, concrete types will be used, but this will be fixed when the API is
updated with splitting Device into ClassicDevice and BleDevice.
This commit is contained in:
Lucas Silva Shepard
2023-07-29 17:22:16 -07:00
parent ba945aa360
commit f42fdb4186
5 changed files with 24 additions and 44 deletions
@@ -33,13 +33,6 @@ pub struct BleAddress {
#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)]
pub struct ClassicAddress([u8; 6]);
/// Enum for interfacing with Bluetooth Addresses.
#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)]
pub enum Address {
Ble(BleAddress),
Classic(ClassicAddress),
}
impl BleAddress {
/// `BleAddress` constructor.
pub fn new(addr: u64, kind: BleAddressKind) -> Self {
+4 -2
View File
@@ -14,18 +14,20 @@
use async_trait::async_trait;
use super::{Address, BluetoothError, PairingResult, ServiceData};
use super::{BluetoothError, PairingResult, ServiceData};
/// Concrete types implementing this trait represent Bluetooth Peripheral devices.
/// They provide methods for retrieving device info and running device actions,
/// such as pairing.
#[async_trait]
pub trait Device: Sized {
type Address;
/// Retrieve the name advertised by this device.
fn name(&self) -> Result<String, BluetoothError>;
/// Retrieve this device's Bluetooth address information.
fn address(&self) -> Address;
fn address(&self) -> Self::Address;
/// Attempt pairing with the peripheral device.
async fn pair(&self) -> Result<PairingResult, BluetoothError>;
+5 -12
View File
@@ -18,24 +18,17 @@
pub mod common;
pub use common::{Adapter, Address, BluetoothError, ClassicAddress, Device};
pub use common::{Adapter, BluetoothError, ClassicAddress, Device};
cfg_if::cfg_if! {
if #[cfg(windows)] {
mod windows;
pub use self::windows::{ClassicDevice, BleAdapter};
use self::windows as platform;
} else {
mod unsupported;
use unsupported::{ClassicDevice, BleAdapter};
use unsupported as platform;
}
}
pub async fn default_adapter() -> Result<BleAdapter, BluetoothError> {
BleAdapter::default().await
}
pub async fn new_classic_device(
addr: ClassicAddress,
) -> Result<impl Device, BluetoothError> {
ClassicDevice::new(addr).await
}
pub type BleAdapter = platform::BleAdapter;
pub type ClassicDevice = platform::ClassicDevice;
@@ -49,7 +49,7 @@ use windows::{
Foundation::TypedEventHandler,
};
use crate::bluetooth::common::{Address, BleAddress, ClassicAddress, Device, ServiceData, BluetoothError, PairingResult};
use crate::bluetooth::{common::{BleAddress, ClassicAddress, Device, ServiceData, BluetoothError, PairingResult}, BleAdapter};
/// Concrete type implementing `Device`, used for Windows BLE.
pub struct BleDevice {
@@ -81,12 +81,14 @@ impl BleDevice {
#[async_trait]
impl Device for BleDevice {
type Address = BleAddress;
fn name(&self) -> Result<String, BluetoothError> {
Ok(self.inner.Name()?.to_string())
}
fn address(&self) -> Address {
Address::Ble(self.addr)
fn address(&self) -> Self::Address {
self.addr
}
async fn pair(&self) -> Result<PairingResult, BluetoothError> {
@@ -119,12 +121,14 @@ impl ClassicDevice {
#[async_trait]
impl Device for ClassicDevice {
type Address = ClassicAddress;
fn name(&self) -> Result<String, BluetoothError> {
Ok(self.inner.Name()?.to_string_lossy())
}
fn address(&self) -> Address {
Address::Classic(self.addr)
fn address(&self) -> Self::Address {
self.addr
}
async fn pair(&self) -> Result<PairingResult, BluetoothError> {
+6 -18
View File
@@ -27,7 +27,7 @@ use futures::{
mod bluetooth;
use bluetooth::{Adapter, Address, BleAdapter, ClassicAddress, Device};
use bluetooth::{Adapter, BleAdapter, ClassicAddress, Device};
async fn get_user_input(
device_vec: Arc<Mutex<Vec<<BleAdapter as Adapter>::Device>>>,
@@ -49,23 +49,11 @@ async fn get_user_input(
let index_to_device = device_vec.lock().await;
match index_to_device.get(val) {
Some(device) => {
let addr: Address = device.address();
// Dynamic dispatch is necessary here because `BleDevice` and
// `ClassicDevice` share the `Device` trait (and thus must have
// the same return type for `address()` method). This can be
// changed later if `Device` trait should exclusively define
// shared cross-platform behavior.
let classic_addr = match addr {
Address::Ble(ble) => ClassicAddress::try_from(ble),
Address::Classic(_) => panic!(
"Address should come from BLE Device, therefore \
shouldn't be Classic."
),
}?;
let addr = device.address();
let classic_addr = ClassicAddress::try_from(addr)?;
let classic_device =
bluetooth::new_classic_device(classic_addr).await?;
bluetooth::ClassicDevice::new(classic_addr).await?;
match classic_device.pair().await {
Ok(_) => {
@@ -82,7 +70,7 @@ async fn get_user_input(
fn main() -> Result<(), Box<dyn Error>> {
let run = async {
let mut adapter = bluetooth::default_adapter().await?;
let mut adapter = bluetooth::BleAdapter::default().await?;
adapter.start_scan()?;
let mut addr_set = HashSet::new();
@@ -103,7 +91,7 @@ fn main() -> Result<(), Box<dyn Error>> {
// This is a Fast Pair device.
if uuid == 0x2cfe {
let addr: Address = ble_device.address();
let addr = ble_device.address();
let name = ble_device.name()?;
if addr_set.insert(addr) {