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}
25
26/// Matches a single advertised attribute or condition from a Bluetooth Low
27/// Energy peer.
28#[derive(Clone, Debug)]
29pub enum Filter {
30 /// Advertised Service UUID
31 ServiceUuid(Uuid),
32 /// ServiceData is included which is associated with the UUID
33 HasServiceData(Uuid),
34 /// ManufacturerData is provided with the Company Identifier Code given
35 HasManufacturerData(u16),
36 /// Connectable flag is set
37 IsConnectable,
38 /// String provided is included in the peer's name
39 MatchesName(String),
40 /// Path loss from the peer (RSSI - Advertised TX Power) is below the given
41 /// dB value
42 MaxPathLoss(i8),
43}
44
45/// A ScanFilter must match all of its combined filters and conditions to
46/// provide a result. Currently can only include zero or more Filters.
47/// The Default ScanFilter will match everything and should be avoided.
48#[derive(Default, Clone, Debug)]
49pub struct ScanFilter {
50 pub filters: Vec<Filter>,
51}
52
53impl From<Filter> for ScanFilter {
54 fn from(value: Filter) -> Self {
55 ScanFilter { filters: vec![value] }
56 }
57}
58
59impl ScanFilter {
60 pub fn add(&mut self, filter: Filter) -> &mut Self {
61 self.filters.push(filter);
62 self
63 }
64}
65
66#[derive(Debug, Clone)]
67pub enum PeerName {
68 Unknown,
69 PartialName(String),
70 CompleteName(String),
71}
72
73#[derive(Debug, Clone)]
74pub struct ScanResult {
75 pub id: PeerId,
76 pub connectable: bool,
77 pub name: PeerName,
78 pub advertised: Vec<AdvertisingDatum>,
79 pub advertising_sid: Option<u8>,
80 pub periodic_advertising_interval: Option<u16>,
81}
82
83pub trait Central<T: crate::GattTypes> {
84 /// Scan for peers.
85 /// If any of the filters match, the results will be returned in the Stream.
86 fn scan(&self, filters: &[ScanFilter]) -> T::ScanResultStream;
87
88 /// Connect to a specific peer.
89 fn connect(&self, peer_id: PeerId) -> T::ConnectFuture;
90
91 /// Get API for periodic advertising.
92 fn periodic_advertising(&self) -> crate::Result<T::PeriodicAdvertising>;
93}