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