|  | // Copyright 2023 Google LLC | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | //! Contains traits that are used to find and connect to Low Energy Peers, i.e. the GAP Central | 
|  | //! and Observer roles role defined in the Bluetooth Core Specification | 
|  | //! (5.4, Volume 3 Part C Section 2.2.2) | 
|  | //! | 
|  | //! These traits should be implemented outside this crate, conforming to the types and structs here | 
|  | //! when necessary. | 
|  |  | 
|  | use crate::client::Client; | 
|  | use crate::types::*; | 
|  |  | 
|  | use bt_common::{PeerId, Uuid}; | 
|  | use futures::{Future, Stream}; | 
|  |  | 
|  | #[derive(Debug, Clone)] | 
|  | pub enum AdvertisingDatum { | 
|  | Services(Vec<Uuid>), | 
|  | ServiceData(Uuid, Vec<u8>), | 
|  | ManufacturerData(u16, Vec<u8>), | 
|  | // TODO: Update to a more structured Appearance | 
|  | Appearance(u16), | 
|  | TxPowerLevel(i8), | 
|  | Uri(String), | 
|  | } | 
|  |  | 
|  | /// Matches a single advertised attribute or condition from a Bluetooth Low Energy peer. | 
|  | #[derive(Clone, Debug)] | 
|  | pub enum Filter { | 
|  | /// Advertised Service UUID | 
|  | ServiceUuid(Uuid), | 
|  | /// ServiceData is included which is associated with the UUID | 
|  | HasServiceData(Uuid), | 
|  | /// ManufacturerData is provided with the Company Identifier Code given | 
|  | HasManufacturerData(u16), | 
|  | /// Connectable flag is set | 
|  | IsConnectable, | 
|  | /// String provided is included in the peer's name | 
|  | MatchesName(String), | 
|  | /// Path loss from the peer (RSSI - Advertised TX Power) is below the given dB value | 
|  | MaxPathLoss(i8), | 
|  | } | 
|  |  | 
|  | /// A ScanFilter must match all of its combined filters and conditions to provide a result. | 
|  | /// Currently can only include zero or more Filters. | 
|  | /// The Default ScanFilter will match everything and should be avoided. | 
|  | #[derive(Default, Clone, Debug)] | 
|  | pub struct ScanFilter { | 
|  | pub filters: Vec<Filter>, | 
|  | } | 
|  |  | 
|  | impl From<Filter> for ScanFilter { | 
|  | fn from(value: Filter) -> Self { | 
|  | ScanFilter { filters: vec![value] } | 
|  | } | 
|  | } | 
|  |  | 
|  | impl ScanFilter { | 
|  | pub fn add(&mut self, filter: Filter) -> &mut Self { | 
|  | self.filters.push(filter); | 
|  | self | 
|  | } | 
|  | } | 
|  |  | 
|  | #[derive(Debug, Clone)] | 
|  | pub enum PeerName { | 
|  | Unknown, | 
|  | PartialName(String), | 
|  | CompleteName(String), | 
|  | } | 
|  |  | 
|  | #[derive(Debug, Clone)] | 
|  | pub struct ScanResult { | 
|  | pub id: PeerId, | 
|  | pub connectable: bool, | 
|  | pub name: PeerName, | 
|  | pub advertised: Vec<AdvertisingDatum>, | 
|  | } | 
|  |  | 
|  | pub trait Central { | 
|  | type ScanResultStream: Stream<Item = Result<ScanResult>> + 'static; | 
|  | type Client: Client; | 
|  | type ClientFut: Future<Output = Result<Self::Client>>; | 
|  |  | 
|  | /// Scan for peers. | 
|  | /// If any of the filters match, the results will be returned in the Stream. | 
|  | fn scan(&self, filters: &[ScanFilter]) -> Self::ScanResultStream; | 
|  |  | 
|  | /// Connect to a specific peer. | 
|  | fn connect(&self, peer_id: PeerId) -> Self::ClientFut; | 
|  | } |