• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use std::collections::HashMap;
2 use std::sync::{Arc, Mutex};
3 
4 use crate::ClientContext;
5 use crate::{console_yellow, print_info};
6 
7 use bt_topshim::btif::Uuid;
8 use bt_topshim::profiles::gatt::LePhy;
9 use btstack::bluetooth_adv::{AdvertiseData, AdvertiserId, AdvertisingSetParameters};
10 use btstack::bluetooth_gatt::IBluetoothGatt;
11 
12 /// Avertisement parameter and data for a BLE advertising set.
13 #[derive(Debug, Clone)]
14 pub(crate) struct AdvSet {
15     /// ID for the advertising set if it's being started successfully, None otherwise.
16     pub(crate) adv_id: Option<AdvertiserId>,
17 
18     /// Advertising parameters.
19     pub(crate) params: AdvertisingSetParameters,
20 
21     /// Advertising data.
22     pub(crate) data: AdvertiseData,
23 
24     /// Scan response data.
25     pub(crate) scan_rsp: AdvertiseData,
26 }
27 
28 impl AdvSet {
new(is_legacy: bool) -> Self29     pub(crate) fn new(is_legacy: bool) -> Self {
30         let params = AdvertisingSetParameters {
31             connectable: false,
32             scannable: false,
33             is_legacy,
34             is_anonymous: false,
35             include_tx_power: true,
36             primary_phy: LePhy::Phy1m,
37             secondary_phy: LePhy::Phy1m,
38             interval: 100,
39             tx_power_level: 0x7f, // no preference
40             own_address_type: 1,  // random
41         };
42 
43         let data = AdvertiseData {
44             service_uuids: Vec::new(),
45             solicit_uuids: Vec::new(),
46             transport_discovery_data: Vec::new(),
47             manufacturer_data: HashMap::from([(0, vec![0, 1, 2])]),
48             service_data: HashMap::new(),
49             include_tx_power_level: true,
50             include_device_name: true,
51         };
52 
53         let scan_rsp = AdvertiseData {
54             service_uuids: vec![Uuid::from([
55                 0x00, 0x00, 0xfe, 0xf3, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5f, 0x9b,
56                 0x34, 0xfb,
57             ])],
58             solicit_uuids: Vec::new(),
59             transport_discovery_data: Vec::new(),
60             manufacturer_data: HashMap::new(),
61             service_data: HashMap::from([(
62                 "0000fef3-0000-1000-8000-00805f9b34fb".to_string(),
63                 vec![0x0a, 0x0b],
64             )]),
65             include_tx_power_level: false,
66             include_device_name: false,
67         };
68 
69         AdvSet { adv_id: None, params, data, scan_rsp }
70     }
71 
start(context: Arc<Mutex<ClientContext>>, s: AdvSet, callback_id: u32)72     pub(crate) fn start(context: Arc<Mutex<ClientContext>>, s: AdvSet, callback_id: u32) {
73         let mut context = context.lock().unwrap();
74 
75         let reg_id = context.gatt_dbus.as_mut().unwrap().start_advertising_set(
76             s.params.clone(),
77             s.data.clone(),
78             None,
79             None,
80             None,
81             0,
82             0,
83             callback_id,
84         );
85         print_info!("Starting advertising set for reg_id = {}", reg_id);
86         context.adv_sets.insert(reg_id, s);
87     }
88 
stop_all(context: Arc<Mutex<ClientContext>>)89     pub(crate) fn stop_all(context: Arc<Mutex<ClientContext>>) {
90         let mut context = context.lock().unwrap();
91 
92         let adv_ids: Vec<_> = context.adv_sets.iter().filter_map(|(_, s)| s.adv_id).collect();
93         for adv_id in adv_ids {
94             print_info!("Stopping advertising set {}", adv_id);
95             context.gatt_dbus.as_mut().unwrap().stop_advertising_set(adv_id);
96         }
97         context.adv_sets.clear();
98     }
99 }
100