Skip to main content

bt_gatt/
central.rs

1// Copyright 2023 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5//! Contains traits that are used to find and connect to Low Energy Peers, i.e.
6//! the GAP Central and Observer roles role defined in the Bluetooth Core
7//! Specification (5.4, Volume 3 Part C Section 2.2.2)
8//!
9//! These traits should be implemented outside this crate, conforming to the
10//! types and structs here when necessary.
11
12use bt_common::{PeerId, Uuid};
13
14#[derive(Debug, Clone)]
15pub enum AdvertisingDatum {
16    Services(Vec<Uuid>),
17    ServiceData(Uuid, Vec<u8>),
18    ManufacturerData(u16, Vec<u8>),
19    // TODO: Update to a more structured Appearance
20    Appearance(u16),
21    TxPowerLevel(i8),
22    Uri(String),
23    BroadcastName(String),
24    ResolvableSetIdentifier([u8; 6]),
25}
26
27/// Matches a single advertised attribute or condition from a Bluetooth Low
28/// Energy peer.
29#[derive(Clone, Debug)]
30pub enum Filter {
31    /// Advertised Service UUID
32    ServiceUuid(Uuid),
33    /// ServiceData is included which is associated with the UUID
34    HasServiceData(Uuid),
35    /// ManufacturerData is provided with the Company Identifier Code given
36    HasManufacturerData(u16),
37    /// Connectable flag is set
38    IsConnectable,
39    /// String provided is included in the peer's name
40    MatchesName(String),
41    /// Path loss from the peer (RSSI - Advertised TX Power) is below the given
42    /// dB value
43    MaxPathLoss(i8),
44}
45
46/// A ScanFilter must match all of its combined filters and conditions to
47/// provide a result. Currently can only include zero or more Filters.
48/// The Default ScanFilter will match everything and should be avoided.
49#[derive(Default, Clone, Debug)]
50pub struct ScanFilter {
51    pub filters: Vec<Filter>,
52}
53
54impl From<Filter> for ScanFilter {
55    fn from(value: Filter) -> Self {
56        ScanFilter { filters: vec![value] }
57    }
58}
59
60impl ScanFilter {
61    pub fn add(&mut self, filter: Filter) -> &mut Self {
62        self.filters.push(filter);
63        self
64    }
65}
66
67#[derive(Debug, Clone)]
68pub enum PeerName {
69    Unknown,
70    PartialName(String),
71    CompleteName(String),
72}
73
74#[derive(Debug, Clone)]
75pub struct ScanResult {
76    pub id: PeerId,
77    pub connectable: bool,
78    pub name: PeerName,
79    pub advertised: Vec<AdvertisingDatum>,
80    pub advertising_sid: Option<u8>,
81    pub periodic_advertising_interval: Option<u16>,
82}
83
84pub trait Central<T: crate::GattTypes> {
85    /// Scan for peers.
86    /// If any of the filters match, the results will be returned in the Stream.
87    fn scan(&self, filters: &[ScanFilter]) -> T::ScanResultStream;
88
89    /// Connect to a specific peer.
90    fn connect(&self, peer_id: PeerId) -> T::ConnectFuture;
91
92    /// Get API for periodic advertising.
93    fn periodic_advertising(&self) -> crate::Result<T::PeriodicAdvertising>;
94}