1 //! BLE Advertising types and utilities
2 
3 use btif_macros::{btif_callback, btif_callbacks_dispatcher};
4 
5 use bt_topshim::btif::{DisplayAddress, RawAddress, Uuid};
6 use bt_topshim::profiles::gatt::{AdvertisingStatus, Gatt, GattAdvCallbacks, LeDiscMode, LePhy};
7 
8 use itertools::Itertools;
9 use log::{debug, error, info, warn};
10 use num_traits::clamp;
11 use std::collections::{HashMap, VecDeque};
12 use std::sync::{Arc, Mutex};
13 use std::time::{Duration, Instant};
14 use tokio::sync::mpsc::Sender;
15 use tokio::task::JoinHandle;
16 use tokio::time;
17 
18 use crate::bluetooth::{Bluetooth, IBluetooth};
19 use crate::callbacks::Callbacks;
20 use crate::{Message, RPCProxy, SuspendMode};
21 
22 pub type AdvertiserId = i32;
23 pub type CallbackId = u32;
24 pub type RegId = i32;
25 pub type ManfId = u16;
26 
27 /// Advertising parameters for each BLE advertising set.
28 #[derive(Debug, Default, Clone)]
29 pub struct AdvertisingSetParameters {
30     /// Discoverable modes.
31     pub discoverable: LeDiscMode,
32     /// Whether the advertisement will be connectable.
33     pub connectable: bool,
34     /// Whether the advertisement will be scannable.
35     pub scannable: bool,
36     /// Whether the legacy advertisement will be used.
37     pub is_legacy: bool,
38     /// Whether the advertisement will be anonymous.
39     pub is_anonymous: bool,
40     /// Whether the TX Power will be included.
41     pub include_tx_power: bool,
42     /// Primary advertising phy. Valid values are: 1 (1M), 2 (2M), 3 (Coded).
43     pub primary_phy: LePhy,
44     /// Secondary advertising phy. Valid values are: 1 (1M), 2 (2M), 3 (Coded).
45     pub secondary_phy: LePhy,
46     /// The advertising interval. Bluetooth LE Advertising interval, in 0.625 ms unit.
47     /// The valid range is from 160 (100 ms) to 16777215 (10485.759375 sec).
48     /// Recommended values are: 160 (100 ms), 400 (250 ms), 1600 (1 sec).
49     pub interval: i32,
50     /// Transmission power of Bluetooth LE Advertising, in dBm. The valid range is [-127, 1].
51     /// Recommended values are: -21, -15, 7, 1.
52     pub tx_power_level: i32,
53     /// Own address type for advertising to control public or privacy mode.
54     /// The valid types are: -1 (default), 0 (public), 1 (random).
55     pub own_address_type: i32,
56 }
57 
58 /// Represents the data to be advertised and the scan response data for active scans.
59 #[derive(Debug, Default, Clone)]
60 pub struct AdvertiseData {
61     /// A list of service UUIDs within the advertisement that are used to identify
62     /// the Bluetooth GATT services.
63     pub service_uuids: Vec<Uuid>,
64     /// A list of service solicitation UUIDs within the advertisement that we invite to connect.
65     pub solicit_uuids: Vec<Uuid>,
66     /// A list of transport discovery data.
67     pub transport_discovery_data: Vec<Vec<u8>>,
68     /// A collection of manufacturer Id and the corresponding manufacturer specific data.
69     pub manufacturer_data: HashMap<ManfId, Vec<u8>>,
70     /// A map of 128-bit UUID and its corresponding service data.
71     pub service_data: HashMap<String, Vec<u8>>,
72     /// Whether TX Power level will be included in the advertising packet.
73     pub include_tx_power_level: bool,
74     /// Whether the device name will be included in the advertisement packet.
75     pub include_device_name: bool,
76 }
77 
78 /// Parameters of the periodic advertising packet for BLE advertising set.
79 #[derive(Debug, Default)]
80 pub struct PeriodicAdvertisingParameters {
81     /// Whether TX Power level will be included.
82     pub include_tx_power: bool,
83     /// Periodic advertising interval in 1.25 ms unit. Valid values are from 80 (100 ms) to
84     /// 65519 (81.89875 sec). Value from range [interval, interval+20ms] will be picked as
85     /// the actual value.
86     pub interval: i32,
87 }
88 
89 /// Interface for advertiser callbacks to clients, passed to
90 /// `IBluetoothGatt::start_advertising_set`.
91 pub trait IAdvertisingSetCallback: RPCProxy {
92     /// Callback triggered in response to `start_advertising_set` indicating result of
93     /// the operation.
94     ///
95     /// * `reg_id` - Identifies the advertising set registered by `start_advertising_set`.
96     /// * `advertiser_id` - ID for the advertising set. It will be used in other advertising methods
97     ///     and callbacks.
98     /// * `tx_power` - Transmit power that will be used for this advertising set.
99     /// * `status` - Status of this operation.
on_advertising_set_started( &mut self, reg_id: i32, advertiser_id: i32, tx_power: i32, status: AdvertisingStatus, )100     fn on_advertising_set_started(
101         &mut self,
102         reg_id: i32,
103         advertiser_id: i32,
104         tx_power: i32,
105         status: AdvertisingStatus,
106     );
107 
108     /// Callback triggered in response to `get_own_address` indicating result of the operation.
on_own_address_read(&mut self, advertiser_id: i32, address_type: i32, address: RawAddress)109     fn on_own_address_read(&mut self, advertiser_id: i32, address_type: i32, address: RawAddress);
110 
111     /// Callback triggered in response to `stop_advertising_set` indicating the advertising set
112     /// is stopped.
on_advertising_set_stopped(&mut self, advertiser_id: i32)113     fn on_advertising_set_stopped(&mut self, advertiser_id: i32);
114 
115     /// Callback triggered in response to `enable_advertising_set` indicating result of
116     /// the operation.
on_advertising_enabled( &mut self, advertiser_id: i32, enable: bool, status: AdvertisingStatus, )117     fn on_advertising_enabled(
118         &mut self,
119         advertiser_id: i32,
120         enable: bool,
121         status: AdvertisingStatus,
122     );
123 
124     /// Callback triggered in response to `set_advertising_data` indicating result of the operation.
on_advertising_data_set(&mut self, advertiser_id: i32, status: AdvertisingStatus)125     fn on_advertising_data_set(&mut self, advertiser_id: i32, status: AdvertisingStatus);
126 
127     /// Callback triggered in response to `set_scan_response_data` indicating result of
128     /// the operation.
on_scan_response_data_set(&mut self, advertiser_id: i32, status: AdvertisingStatus)129     fn on_scan_response_data_set(&mut self, advertiser_id: i32, status: AdvertisingStatus);
130 
131     /// Callback triggered in response to `set_advertising_parameters` indicating result of
132     /// the operation.
on_advertising_parameters_updated( &mut self, advertiser_id: i32, tx_power: i32, status: AdvertisingStatus, )133     fn on_advertising_parameters_updated(
134         &mut self,
135         advertiser_id: i32,
136         tx_power: i32,
137         status: AdvertisingStatus,
138     );
139 
140     /// Callback triggered in response to `set_periodic_advertising_parameters` indicating result of
141     /// the operation.
on_periodic_advertising_parameters_updated( &mut self, advertiser_id: i32, status: AdvertisingStatus, )142     fn on_periodic_advertising_parameters_updated(
143         &mut self,
144         advertiser_id: i32,
145         status: AdvertisingStatus,
146     );
147 
148     /// Callback triggered in response to `set_periodic_advertising_data` indicating result of
149     /// the operation.
on_periodic_advertising_data_set(&mut self, advertiser_id: i32, status: AdvertisingStatus)150     fn on_periodic_advertising_data_set(&mut self, advertiser_id: i32, status: AdvertisingStatus);
151 
152     /// Callback triggered in response to `set_periodic_advertising_enable` indicating result of
153     /// the operation.
on_periodic_advertising_enabled( &mut self, advertiser_id: i32, enable: bool, status: AdvertisingStatus, )154     fn on_periodic_advertising_enabled(
155         &mut self,
156         advertiser_id: i32,
157         enable: bool,
158         status: AdvertisingStatus,
159     );
160 
161     /// When advertising module changes its suspend mode due to system suspend/resume.
on_suspend_mode_change(&mut self, suspend_mode: SuspendMode)162     fn on_suspend_mode_change(&mut self, suspend_mode: SuspendMode);
163 }
164 
165 // Advertising interval range.
166 const INTERVAL_MAX: i32 = 0xff_ffff; // 10485.759375 sec
167 const INTERVAL_MIN: i32 = 160; // 100 ms
168 const INTERVAL_DELTA: i32 = 50; // 31.25 ms gap between min and max
169 
170 // Periodic advertising interval range.
171 const PERIODIC_INTERVAL_MAX: i32 = 65519; // 81.89875 sec
172 const PERIODIC_INTERVAL_MIN: i32 = 80; // 100 ms
173 const PERIODIC_INTERVAL_DELTA: i32 = 16; // 20 ms gap between min and max
174 
175 // Device name length.
176 const DEVICE_NAME_MAX: usize = 26;
177 
178 // Advertising data types.
179 const COMPLETE_LIST_16_BIT_SERVICE_UUIDS: u8 = 0x03;
180 const COMPLETE_LIST_32_BIT_SERVICE_UUIDS: u8 = 0x05;
181 const COMPLETE_LIST_128_BIT_SERVICE_UUIDS: u8 = 0x07;
182 const SHORTENED_LOCAL_NAME: u8 = 0x08;
183 const COMPLETE_LOCAL_NAME: u8 = 0x09;
184 const TX_POWER_LEVEL: u8 = 0x0a;
185 const LIST_16_BIT_SERVICE_SOLICITATION_UUIDS: u8 = 0x14;
186 const LIST_128_BIT_SERVICE_SOLICITATION_UUIDS: u8 = 0x15;
187 const SERVICE_DATA_16_BIT_UUID: u8 = 0x16;
188 const LIST_32_BIT_SERVICE_SOLICITATION_UUIDS: u8 = 0x1f;
189 const SERVICE_DATA_32_BIT_UUID: u8 = 0x20;
190 const SERVICE_DATA_128_BIT_UUID: u8 = 0x21;
191 const TRANSPORT_DISCOVERY_DATA: u8 = 0x26;
192 const MANUFACTURER_SPECIFIC_DATA: u8 = 0xff;
193 const SERVICE_AD_TYPES: [u8; 3] = [
194     COMPLETE_LIST_16_BIT_SERVICE_UUIDS,
195     COMPLETE_LIST_32_BIT_SERVICE_UUIDS,
196     COMPLETE_LIST_128_BIT_SERVICE_UUIDS,
197 ];
198 const SOLICIT_AD_TYPES: [u8; 3] = [
199     LIST_16_BIT_SERVICE_SOLICITATION_UUIDS,
200     LIST_32_BIT_SERVICE_SOLICITATION_UUIDS,
201     LIST_128_BIT_SERVICE_SOLICITATION_UUIDS,
202 ];
203 
204 const LEGACY_ADV_DATA_LEN_MAX: usize = 31;
205 const EXT_ADV_DATA_LEN_MAX: usize = 254;
206 
207 // Invalid advertising set id.
208 const INVALID_ADV_ID: i32 = 0xff;
209 
210 // Invalid advertising set id.
211 pub const INVALID_REG_ID: i32 = -1;
212 
213 impl Into<bt_topshim::profiles::gatt::AdvertiseParameters> for AdvertisingSetParameters {
into(self) -> bt_topshim::profiles::gatt::AdvertiseParameters214     fn into(self) -> bt_topshim::profiles::gatt::AdvertiseParameters {
215         let mut props: u16 = 0;
216         if self.connectable {
217             props |= 0x01;
218         }
219         if self.scannable {
220             props |= 0x02;
221         }
222         if self.is_legacy {
223             props |= 0x10;
224         }
225         if self.is_anonymous {
226             props |= 0x20;
227         }
228         if self.include_tx_power {
229             props |= 0x40;
230         }
231 
232         match self.discoverable {
233             LeDiscMode::GeneralDiscoverable => {
234                 props |= 0x04;
235             }
236             _ => {}
237         }
238 
239         let interval = clamp(self.interval, INTERVAL_MIN, INTERVAL_MAX - INTERVAL_DELTA);
240 
241         bt_topshim::profiles::gatt::AdvertiseParameters {
242             advertising_event_properties: props,
243             min_interval: interval as u32,
244             max_interval: (interval + INTERVAL_DELTA) as u32,
245             channel_map: 0x07 as u8, // all channels
246             tx_power: self.tx_power_level as i8,
247             primary_advertising_phy: self.primary_phy.into(),
248             secondary_advertising_phy: self.secondary_phy.into(),
249             scan_request_notification_enable: 0 as u8, // false
250             own_address_type: self.own_address_type as i8,
251         }
252     }
253 }
254 
255 impl AdvertiseData {
append_adv_data(dest: &mut Vec<u8>, ad_type: u8, ad_payload: &[u8])256     fn append_adv_data(dest: &mut Vec<u8>, ad_type: u8, ad_payload: &[u8]) {
257         let len = clamp(ad_payload.len(), 0, 254);
258         dest.push((len + 1) as u8);
259         dest.push(ad_type);
260         dest.extend(&ad_payload[..len]);
261     }
262 
append_uuids(dest: &mut Vec<u8>, ad_types: &[u8; 3], uuids: &Vec<Uuid>)263     fn append_uuids(dest: &mut Vec<u8>, ad_types: &[u8; 3], uuids: &Vec<Uuid>) {
264         let mut uuid16_bytes = Vec::<u8>::new();
265         let mut uuid32_bytes = Vec::<u8>::new();
266         let mut uuid128_bytes = Vec::<u8>::new();
267 
268         // For better transmission efficiency, we generate a compact
269         // advertisement data by converting UUIDs into shorter binary forms
270         // and then group them by their length in order.
271         // The data generated for UUIDs looks like:
272         // [16-bit_UUID_LIST, 32-bit_UUID_LIST, 128-bit_UUID_LIST].
273         for uuid in uuids {
274             let uuid_slice = uuid.get_shortest_slice();
275             let id: Vec<u8> = uuid_slice.iter().rev().cloned().collect();
276             match id.len() {
277                 2 => uuid16_bytes.extend(id),
278                 4 => uuid32_bytes.extend(id),
279                 16 => uuid128_bytes.extend(id),
280                 _ => (),
281             }
282         }
283 
284         let bytes_list = vec![uuid16_bytes, uuid32_bytes, uuid128_bytes];
285         for (ad_type, bytes) in
286             ad_types.iter().zip(bytes_list.iter()).filter(|(_, bytes)| bytes.len() > 0)
287         {
288             AdvertiseData::append_adv_data(dest, *ad_type, bytes);
289         }
290     }
291 
append_service_uuids(dest: &mut Vec<u8>, uuids: &Vec<Uuid>)292     fn append_service_uuids(dest: &mut Vec<u8>, uuids: &Vec<Uuid>) {
293         AdvertiseData::append_uuids(dest, &SERVICE_AD_TYPES, uuids);
294     }
295 
append_solicit_uuids(dest: &mut Vec<u8>, uuids: &Vec<Uuid>)296     fn append_solicit_uuids(dest: &mut Vec<u8>, uuids: &Vec<Uuid>) {
297         AdvertiseData::append_uuids(dest, &SOLICIT_AD_TYPES, uuids);
298     }
299 
append_service_data(dest: &mut Vec<u8>, service_data: &HashMap<String, Vec<u8>>)300     fn append_service_data(dest: &mut Vec<u8>, service_data: &HashMap<String, Vec<u8>>) {
301         for (uuid, data) in
302             service_data.iter().filter_map(|(s, d)| Uuid::from_string(s).map(|s| (s, d)))
303         {
304             let uuid_slice = uuid.get_shortest_slice();
305             let concated: Vec<u8> = uuid_slice.iter().rev().chain(data).cloned().collect();
306             match uuid_slice.len() {
307                 2 => AdvertiseData::append_adv_data(dest, SERVICE_DATA_16_BIT_UUID, &concated),
308                 4 => AdvertiseData::append_adv_data(dest, SERVICE_DATA_32_BIT_UUID, &concated),
309                 16 => AdvertiseData::append_adv_data(dest, SERVICE_DATA_128_BIT_UUID, &concated),
310                 _ => (),
311             }
312         }
313     }
314 
append_device_name(dest: &mut Vec<u8>, device_name: &String)315     fn append_device_name(dest: &mut Vec<u8>, device_name: &String) {
316         if device_name.len() == 0 {
317             return;
318         }
319 
320         let (ad_type, name) = if device_name.len() > DEVICE_NAME_MAX {
321             (SHORTENED_LOCAL_NAME, [&device_name.as_bytes()[..DEVICE_NAME_MAX], &[0]].concat())
322         } else {
323             (COMPLETE_LOCAL_NAME, [device_name.as_bytes(), &[0]].concat())
324         };
325         AdvertiseData::append_adv_data(dest, ad_type, &name);
326     }
327 
append_manufacturer_data(dest: &mut Vec<u8>, manufacturer_data: &HashMap<ManfId, Vec<u8>>)328     fn append_manufacturer_data(dest: &mut Vec<u8>, manufacturer_data: &HashMap<ManfId, Vec<u8>>) {
329         for (m, data) in manufacturer_data.iter().sorted() {
330             let concated = [&m.to_le_bytes()[..], data].concat();
331             AdvertiseData::append_adv_data(dest, MANUFACTURER_SPECIFIC_DATA, &concated);
332         }
333     }
334 
append_transport_discovery_data( dest: &mut Vec<u8>, transport_discovery_data: &Vec<Vec<u8>>, )335     fn append_transport_discovery_data(
336         dest: &mut Vec<u8>,
337         transport_discovery_data: &Vec<Vec<u8>>,
338     ) {
339         for tdd in transport_discovery_data.iter().filter(|tdd| tdd.len() > 0) {
340             AdvertiseData::append_adv_data(dest, TRANSPORT_DISCOVERY_DATA, &tdd);
341         }
342     }
343 
344     /// Creates raw data from the AdvertiseData.
make_with(&self, device_name: &String) -> Vec<u8>345     pub fn make_with(&self, device_name: &String) -> Vec<u8> {
346         let mut bytes = Vec::<u8>::new();
347         if self.include_device_name {
348             AdvertiseData::append_device_name(&mut bytes, device_name);
349         }
350         if self.include_tx_power_level {
351             // Lower layers will fill tx power level.
352             AdvertiseData::append_adv_data(&mut bytes, TX_POWER_LEVEL, &[0]);
353         }
354         AdvertiseData::append_manufacturer_data(&mut bytes, &self.manufacturer_data);
355         AdvertiseData::append_service_uuids(&mut bytes, &self.service_uuids);
356         AdvertiseData::append_service_data(&mut bytes, &self.service_data);
357         AdvertiseData::append_solicit_uuids(&mut bytes, &self.solicit_uuids);
358         AdvertiseData::append_transport_discovery_data(&mut bytes, &self.transport_discovery_data);
359         bytes
360     }
361 
362     /// Validates the raw data as advertisement data.
validate_raw_data(is_legacy: bool, bytes: &Vec<u8>) -> bool363     pub fn validate_raw_data(is_legacy: bool, bytes: &Vec<u8>) -> bool {
364         bytes.len() <= if is_legacy { LEGACY_ADV_DATA_LEN_MAX } else { EXT_ADV_DATA_LEN_MAX }
365     }
366 
367     /// Checks if the advertisement can be upgraded to extended.
can_upgrade(parameters: &mut AdvertisingSetParameters, adv_bytes: &Vec<u8>) -> bool368     pub fn can_upgrade(parameters: &mut AdvertisingSetParameters, adv_bytes: &Vec<u8>) -> bool {
369         if parameters.is_legacy && !AdvertiseData::validate_raw_data(true, adv_bytes) {
370             info!("Auto upgrading advertisement to extended");
371             parameters.is_legacy = false;
372             return true;
373         }
374 
375         false
376     }
377 }
378 
379 impl Into<bt_topshim::profiles::gatt::PeriodicAdvertisingParameters>
380     for PeriodicAdvertisingParameters
381 {
into(self) -> bt_topshim::profiles::gatt::PeriodicAdvertisingParameters382     fn into(self) -> bt_topshim::profiles::gatt::PeriodicAdvertisingParameters {
383         let mut p = bt_topshim::profiles::gatt::PeriodicAdvertisingParameters::default();
384 
385         let interval = clamp(
386             self.interval,
387             PERIODIC_INTERVAL_MIN,
388             PERIODIC_INTERVAL_MAX - PERIODIC_INTERVAL_DELTA,
389         );
390 
391         p.enable = true;
392         p.include_adi = false;
393         p.min_interval = interval as u16;
394         p.max_interval = p.min_interval + (PERIODIC_INTERVAL_DELTA as u16);
395         if self.include_tx_power {
396             p.periodic_advertising_properties |= 0x40;
397         }
398 
399         p
400     }
401 }
402 
403 // Keeps information of an advertising set.
404 #[derive(Debug, PartialEq, Copy, Clone)]
405 struct AdvertisingSetInfo {
406     /// Identifies the advertising set when it's started successfully.
407     adv_id: Option<AdvertiserId>,
408 
409     /// Identifies callback associated.
410     callback_id: CallbackId,
411 
412     /// Identifies the advertising set when it's registered.
413     reg_id: RegId,
414 
415     /// Whether the advertising set has been enabled.
416     enabled: bool,
417 
418     /// Whether the advertising set has been paused.
419     paused: bool,
420 
421     /// Whether the stop of advertising set is held.
422     /// This flag is set when an advertising set is stopped while we're not able to do it, such as:
423     /// - The system is suspending / suspended
424     /// - The advertising set is not yet valid (started)
425     ///
426     /// The advertising set will be stopped on system resumed / advertising set becomes ready.
427     stopped: bool,
428 
429     /// Advertising duration, in 10 ms unit.
430     adv_timeout: u16,
431 
432     /// Maximum number of extended advertising events the controller
433     /// shall attempt to send before terminating the extended advertising.
434     adv_events: u8,
435 
436     /// Whether the legacy advertisement will be used.
437     legacy: bool,
438 }
439 
440 impl AdvertisingSetInfo {
new( callback_id: CallbackId, adv_timeout: u16, adv_events: u8, legacy: bool, reg_id: RegId, ) -> Self441     fn new(
442         callback_id: CallbackId,
443         adv_timeout: u16,
444         adv_events: u8,
445         legacy: bool,
446         reg_id: RegId,
447     ) -> Self {
448         AdvertisingSetInfo {
449             adv_id: None,
450             callback_id,
451             reg_id,
452             enabled: false,
453             paused: false,
454             stopped: false,
455             adv_timeout,
456             adv_events,
457             legacy,
458         }
459     }
460 
461     /// Gets advertising set registration ID.
reg_id(&self) -> RegId462     fn reg_id(&self) -> RegId {
463         self.reg_id
464     }
465 
466     /// Gets associated callback ID.
callback_id(&self) -> CallbackId467     fn callback_id(&self) -> CallbackId {
468         self.callback_id
469     }
470 
471     /// Updates advertiser ID.
set_adv_id(&mut self, id: Option<AdvertiserId>)472     fn set_adv_id(&mut self, id: Option<AdvertiserId>) {
473         self.adv_id = id;
474     }
475 
476     /// Gets advertiser ID, which is required for advertising |BleAdvertiserInterface|.
adv_id(&self) -> u8477     fn adv_id(&self) -> u8 {
478         // As advertiser ID was from topshim originally, type casting is safe.
479         self.adv_id.unwrap_or(INVALID_ADV_ID) as u8
480     }
481 
482     /// Updates advertising set status.
set_enabled(&mut self, enabled: bool)483     fn set_enabled(&mut self, enabled: bool) {
484         self.enabled = enabled;
485     }
486 
487     /// Returns true if the advertising set has been enabled, false otherwise.
is_enabled(&self) -> bool488     fn is_enabled(&self) -> bool {
489         self.enabled
490     }
491 
492     /// Marks the advertising set as paused or not.
set_paused(&mut self, paused: bool)493     fn set_paused(&mut self, paused: bool) {
494         self.paused = paused;
495     }
496 
497     /// Returns true if the advertising set has been paused, false otherwise.
is_paused(&self) -> bool498     fn is_paused(&self) -> bool {
499         self.paused
500     }
501 
502     /// Marks the advertising set as stopped.
set_stopped(&mut self)503     fn set_stopped(&mut self) {
504         self.stopped = true;
505     }
506 
507     /// Returns true if the advertising set has been stopped, false otherwise.
is_stopped(&self) -> bool508     fn is_stopped(&self) -> bool {
509         self.stopped
510     }
511 
512     /// Gets adv_timeout.
adv_timeout(&self) -> u16513     fn adv_timeout(&self) -> u16 {
514         self.adv_timeout
515     }
516 
517     /// Gets adv_events.
adv_events(&self) -> u8518     fn adv_events(&self) -> u8 {
519         self.adv_events
520     }
521 
522     /// Returns whether the legacy advertisement will be used.
is_legacy(&self) -> bool523     fn is_legacy(&self) -> bool {
524         self.legacy
525     }
526 
527     /// Returns whether the advertising set is valid.
is_valid(&self) -> bool528     fn is_valid(&self) -> bool {
529         self.adv_id.is_some()
530     }
531 }
532 
533 // Manages advertising sets and the callbacks.
534 pub(crate) struct AdvertiseManager {
535     tx: Sender<Message>,
536     adv_manager_impl: Option<Box<dyn AdvertiseManagerOps + Send>>,
537 }
538 
539 impl AdvertiseManager {
new(tx: Sender<Message>) -> Self540     pub(crate) fn new(tx: Sender<Message>) -> Self {
541         AdvertiseManager { tx, adv_manager_impl: None }
542     }
543 
544     /// Initializes the AdvertiseManager
545     /// This needs to be called after Bluetooth is ready because we need to query LE features.
initialize( &mut self, gatt: Arc<Mutex<Gatt>>, adapter: Arc<Mutex<Box<Bluetooth>>>, is_le_ext_adv_supported: bool, )546     pub(crate) fn initialize(
547         &mut self,
548         gatt: Arc<Mutex<Gatt>>,
549         adapter: Arc<Mutex<Box<Bluetooth>>>,
550         is_le_ext_adv_supported: bool,
551     ) {
552         self.adv_manager_impl = if is_le_ext_adv_supported {
553             info!("AdvertiseManager: Selected extended advertising stack");
554             Some(Box::new(AdvertiseManagerImpl::new(self.tx.clone(), gatt, adapter)))
555         } else {
556             info!("AdvertiseManager: Selected software rotation stack");
557             Some(Box::new(SoftwareRotationAdvertiseManagerImpl::new(
558                 self.tx.clone(),
559                 gatt,
560                 adapter,
561             )))
562         }
563     }
564 
get_impl(&mut self) -> &mut Box<dyn AdvertiseManagerOps + Send>565     pub fn get_impl(&mut self) -> &mut Box<dyn AdvertiseManagerOps + Send> {
566         self.adv_manager_impl.as_mut().unwrap()
567     }
568 }
569 
570 struct AdvertiseManagerImpl {
571     callbacks: Callbacks<dyn IAdvertisingSetCallback + Send>,
572     sets: HashMap<RegId, AdvertisingSetInfo>,
573     suspend_mode: SuspendMode,
574     gatt: Arc<Mutex<Gatt>>,
575     adapter: Arc<Mutex<Box<Bluetooth>>>,
576 }
577 
578 impl AdvertiseManagerImpl {
new( tx: Sender<Message>, gatt: Arc<Mutex<Gatt>>, adapter: Arc<Mutex<Box<Bluetooth>>>, ) -> Self579     fn new(
580         tx: Sender<Message>,
581         gatt: Arc<Mutex<Gatt>>,
582         adapter: Arc<Mutex<Box<Bluetooth>>>,
583     ) -> Self {
584         AdvertiseManagerImpl {
585             callbacks: Callbacks::new(tx, Message::AdvertiserCallbackDisconnected),
586             sets: HashMap::new(),
587             suspend_mode: SuspendMode::Normal,
588             gatt,
589             adapter,
590         }
591     }
592 
593     // Returns the minimum unoccupied register ID from 0.
new_reg_id(&mut self) -> RegId594     fn new_reg_id(&mut self) -> RegId {
595         (0..)
596             .find(|id| !self.sets.contains_key(id))
597             .expect("There must be an unoccupied register ID")
598     }
599 
600     /// Adds an advertising set.
add(&mut self, s: AdvertisingSetInfo)601     fn add(&mut self, s: AdvertisingSetInfo) {
602         if let Some(old) = self.sets.insert(s.reg_id(), s) {
603             warn!("An advertising set with the same reg_id ({}) exists. Drop it!", old.reg_id);
604         }
605     }
606 
607     /// Returns an iterator of valid advertising sets.
valid_sets(&self) -> impl Iterator<Item = &AdvertisingSetInfo>608     fn valid_sets(&self) -> impl Iterator<Item = &AdvertisingSetInfo> {
609         self.sets.iter().filter_map(|(_, s)| s.adv_id.map(|_| s))
610     }
611 
612     /// Returns an iterator of enabled advertising sets.
enabled_sets(&self) -> impl Iterator<Item = &AdvertisingSetInfo>613     fn enabled_sets(&self) -> impl Iterator<Item = &AdvertisingSetInfo> {
614         self.valid_sets().filter(|s| s.is_enabled())
615     }
616 
617     /// Returns an iterator of stopped advertising sets.
stopped_sets(&self) -> impl Iterator<Item = &AdvertisingSetInfo>618     fn stopped_sets(&self) -> impl Iterator<Item = &AdvertisingSetInfo> {
619         self.valid_sets().filter(|s| s.is_stopped())
620     }
621 
find_reg_id(&self, adv_id: AdvertiserId) -> Option<RegId>622     fn find_reg_id(&self, adv_id: AdvertiserId) -> Option<RegId> {
623         for (_, s) in &self.sets {
624             if s.adv_id == Some(adv_id) {
625                 return Some(s.reg_id());
626             }
627         }
628         return None;
629     }
630 
631     /// Returns a mutable reference to the advertising set with the reg_id specified.
get_mut_by_reg_id(&mut self, reg_id: RegId) -> Option<&mut AdvertisingSetInfo>632     fn get_mut_by_reg_id(&mut self, reg_id: RegId) -> Option<&mut AdvertisingSetInfo> {
633         self.sets.get_mut(&reg_id)
634     }
635 
636     /// Returns a shared reference to the advertising set with the reg_id specified.
get_by_reg_id(&self, reg_id: RegId) -> Option<&AdvertisingSetInfo>637     fn get_by_reg_id(&self, reg_id: RegId) -> Option<&AdvertisingSetInfo> {
638         self.sets.get(&reg_id)
639     }
640 
641     /// Returns a mutable reference to the advertising set with the advertiser ID specified.
get_mut_by_advertiser_id( &mut self, adv_id: AdvertiserId, ) -> Option<&mut AdvertisingSetInfo>642     fn get_mut_by_advertiser_id(
643         &mut self,
644         adv_id: AdvertiserId,
645     ) -> Option<&mut AdvertisingSetInfo> {
646         if let Some(reg_id) = self.find_reg_id(adv_id) {
647             return self.get_mut_by_reg_id(reg_id);
648         }
649         None
650     }
651 
652     /// Returns a shared reference to the advertising set with the advertiser ID specified.
get_by_advertiser_id(&self, adv_id: AdvertiserId) -> Option<&AdvertisingSetInfo>653     fn get_by_advertiser_id(&self, adv_id: AdvertiserId) -> Option<&AdvertisingSetInfo> {
654         if let Some(reg_id) = self.find_reg_id(adv_id) {
655             return self.get_by_reg_id(reg_id);
656         }
657         None
658     }
659 
660     /// Removes the advertising set with the reg_id specified.
661     ///
662     /// Returns the advertising set if found, None otherwise.
remove_by_reg_id(&mut self, reg_id: RegId) -> Option<AdvertisingSetInfo>663     fn remove_by_reg_id(&mut self, reg_id: RegId) -> Option<AdvertisingSetInfo> {
664         self.sets.remove(&reg_id)
665     }
666 
667     /// Removes the advertising set with the specified advertiser ID.
668     ///
669     /// Returns the advertising set if found, None otherwise.
remove_by_advertiser_id(&mut self, adv_id: AdvertiserId) -> Option<AdvertisingSetInfo>670     fn remove_by_advertiser_id(&mut self, adv_id: AdvertiserId) -> Option<AdvertisingSetInfo> {
671         if let Some(reg_id) = self.find_reg_id(adv_id) {
672             return self.remove_by_reg_id(reg_id);
673         }
674         None
675     }
676 
677     /// Returns callback of the advertising set.
get_callback( &mut self, s: &AdvertisingSetInfo, ) -> Option<&mut Box<dyn IAdvertisingSetCallback + Send>>678     fn get_callback(
679         &mut self,
680         s: &AdvertisingSetInfo,
681     ) -> Option<&mut Box<dyn IAdvertisingSetCallback + Send>> {
682         self.callbacks.get_by_id_mut(s.callback_id())
683     }
684 
685     /// Update suspend mode.
set_suspend_mode(&mut self, suspend_mode: SuspendMode)686     fn set_suspend_mode(&mut self, suspend_mode: SuspendMode) {
687         if suspend_mode != self.suspend_mode {
688             self.suspend_mode = suspend_mode;
689             self.notify_suspend_mode();
690         }
691     }
692 
693     /// Gets current suspend mode.
suspend_mode(&mut self) -> SuspendMode694     fn suspend_mode(&mut self) -> SuspendMode {
695         self.suspend_mode.clone()
696     }
697 
698     /// Notify current suspend mode to all active callbacks.
notify_suspend_mode(&mut self)699     fn notify_suspend_mode(&mut self) {
700         let suspend_mode = &self.suspend_mode;
701         self.callbacks.for_all_callbacks(|callback| {
702             callback.on_suspend_mode_change(suspend_mode.clone());
703         });
704     }
705 
get_adapter_name(&self) -> String706     fn get_adapter_name(&self) -> String {
707         self.adapter.lock().unwrap().get_name()
708     }
709 }
710 
711 pub enum AdvertiserActions {
712     /// Triggers the rotation of the advertising set.
713     /// Should only be used in the software rotation stack.
714     RunRotate,
715 }
716 
717 /// Defines all required ops for an AdvertiseManager to communicate with the upper/lower layers.
718 pub(crate) trait AdvertiseManagerOps:
719     IBluetoothAdvertiseManager + BtifGattAdvCallbacks
720 {
721     /// Prepares for suspend
enter_suspend(&mut self)722     fn enter_suspend(&mut self);
723 
724     /// Undoes previous suspend preparation
exit_suspend(&mut self)725     fn exit_suspend(&mut self);
726 
727     /// Handles advertise manager actions
handle_action(&mut self, action: AdvertiserActions)728     fn handle_action(&mut self, action: AdvertiserActions);
729 }
730 
731 impl AdvertiseManagerOps for AdvertiseManagerImpl {
enter_suspend(&mut self)732     fn enter_suspend(&mut self) {
733         if self.suspend_mode() != SuspendMode::Normal {
734             return;
735         }
736         self.set_suspend_mode(SuspendMode::Suspending);
737 
738         let mut pausing_cnt = 0;
739         for s in self.sets.values_mut().filter(|s| s.is_valid() && s.is_enabled()) {
740             s.set_paused(true);
741             self.gatt.lock().unwrap().advertiser.enable(
742                 s.adv_id(),
743                 false,
744                 s.adv_timeout(),
745                 s.adv_events(),
746             );
747             pausing_cnt += 1;
748         }
749 
750         if pausing_cnt == 0 {
751             self.set_suspend_mode(SuspendMode::Suspended);
752         }
753     }
754 
exit_suspend(&mut self)755     fn exit_suspend(&mut self) {
756         if self.suspend_mode() != SuspendMode::Suspended {
757             return;
758         }
759         for id in self.stopped_sets().map(|s| s.adv_id()).collect::<Vec<_>>() {
760             self.gatt.lock().unwrap().advertiser.unregister(id);
761             self.remove_by_advertiser_id(id as AdvertiserId);
762         }
763         for s in self.sets.values_mut().filter(|s| s.is_valid() && s.is_paused()) {
764             s.set_paused(false);
765             self.gatt.lock().unwrap().advertiser.enable(
766                 s.adv_id(),
767                 true,
768                 s.adv_timeout(),
769                 s.adv_events(),
770             );
771         }
772 
773         self.set_suspend_mode(SuspendMode::Normal);
774     }
775 
handle_action(&mut self, action: AdvertiserActions)776     fn handle_action(&mut self, action: AdvertiserActions) {
777         match action {
778             AdvertiserActions::RunRotate => {
779                 error!("Unexpected RunRotate call in hardware offloaded stack");
780             }
781         }
782     }
783 }
784 
785 pub trait IBluetoothAdvertiseManager {
786     /// Registers callback for BLE advertising.
register_callback(&mut self, callback: Box<dyn IAdvertisingSetCallback + Send>) -> u32787     fn register_callback(&mut self, callback: Box<dyn IAdvertisingSetCallback + Send>) -> u32;
788 
789     /// Unregisters callback for BLE advertising.
unregister_callback(&mut self, callback_id: u32) -> bool790     fn unregister_callback(&mut self, callback_id: u32) -> bool;
791 
792     /// Creates a new BLE advertising set and start advertising.
793     ///
794     /// Returns the reg_id for the advertising set, which is used in the callback
795     /// `on_advertising_set_started` to identify the advertising set started.
796     ///
797     /// * `parameters` - Advertising set parameters.
798     /// * `advertise_data` - Advertisement data to be broadcasted.
799     /// * `scan_response` - Scan response.
800     /// * `periodic_parameters` - Periodic advertising parameters. If None, periodic advertising
801     ///     will not be started.
802     /// * `periodic_data` - Periodic advertising data.
803     /// * `duration` - Advertising duration, in 10 ms unit. Valid range is from 1 (10 ms) to
804     ///     65535 (655.35 sec). 0 means no advertising timeout.
805     /// * `max_ext_adv_events` - Maximum number of extended advertising events the controller
806     ///     shall attempt to send before terminating the extended advertising, even if the
807     ///     duration has not expired. Valid range is from 1 to 255. 0 means event count limitation.
808     /// * `callback_id` - Identifies callback registered in register_advertiser_callback.
start_advertising_set( &mut self, parameters: AdvertisingSetParameters, advertise_data: AdvertiseData, scan_response: Option<AdvertiseData>, periodic_parameters: Option<PeriodicAdvertisingParameters>, periodic_data: Option<AdvertiseData>, duration: i32, max_ext_adv_events: i32, callback_id: u32, ) -> i32809     fn start_advertising_set(
810         &mut self,
811         parameters: AdvertisingSetParameters,
812         advertise_data: AdvertiseData,
813         scan_response: Option<AdvertiseData>,
814         periodic_parameters: Option<PeriodicAdvertisingParameters>,
815         periodic_data: Option<AdvertiseData>,
816         duration: i32,
817         max_ext_adv_events: i32,
818         callback_id: u32,
819     ) -> i32;
820 
821     /// Disposes a BLE advertising set.
stop_advertising_set(&mut self, advertiser_id: i32)822     fn stop_advertising_set(&mut self, advertiser_id: i32);
823 
824     /// Queries address associated with the advertising set.
get_own_address(&mut self, advertiser_id: i32)825     fn get_own_address(&mut self, advertiser_id: i32);
826 
827     /// Enables or disables an advertising set.
enable_advertising_set( &mut self, advertiser_id: i32, enable: bool, duration: i32, max_ext_adv_events: i32, )828     fn enable_advertising_set(
829         &mut self,
830         advertiser_id: i32,
831         enable: bool,
832         duration: i32,
833         max_ext_adv_events: i32,
834     );
835 
836     /// Updates advertisement data of the advertising set.
set_advertising_data(&mut self, advertiser_id: i32, data: AdvertiseData)837     fn set_advertising_data(&mut self, advertiser_id: i32, data: AdvertiseData);
838 
839     /// Set the advertisement data of the advertising set.
set_raw_adv_data(&mut self, advertiser_id: i32, data: Vec<u8>)840     fn set_raw_adv_data(&mut self, advertiser_id: i32, data: Vec<u8>);
841 
842     /// Updates scan response of the advertising set.
set_scan_response_data(&mut self, advertiser_id: i32, data: AdvertiseData)843     fn set_scan_response_data(&mut self, advertiser_id: i32, data: AdvertiseData);
844 
845     /// Updates advertising parameters of the advertising set.
846     ///
847     /// It must be called when advertising is not active.
set_advertising_parameters( &mut self, advertiser_id: i32, parameters: AdvertisingSetParameters, )848     fn set_advertising_parameters(
849         &mut self,
850         advertiser_id: i32,
851         parameters: AdvertisingSetParameters,
852     );
853 
854     /// Updates periodic advertising parameters.
set_periodic_advertising_parameters( &mut self, advertiser_id: i32, parameters: PeriodicAdvertisingParameters, )855     fn set_periodic_advertising_parameters(
856         &mut self,
857         advertiser_id: i32,
858         parameters: PeriodicAdvertisingParameters,
859     );
860 
861     /// Updates periodic advertisement data.
862     ///
863     /// It must be called after `set_periodic_advertising_parameters`, or after
864     /// advertising was started with periodic advertising data set.
set_periodic_advertising_data(&mut self, advertiser_id: i32, data: AdvertiseData)865     fn set_periodic_advertising_data(&mut self, advertiser_id: i32, data: AdvertiseData);
866 
867     /// Enables or disables periodic advertising.
set_periodic_advertising_enable( &mut self, advertiser_id: i32, enable: bool, include_adi: bool, )868     fn set_periodic_advertising_enable(
869         &mut self,
870         advertiser_id: i32,
871         enable: bool,
872         include_adi: bool,
873     );
874 }
875 
876 impl IBluetoothAdvertiseManager for AdvertiseManagerImpl {
register_callback(&mut self, callback: Box<dyn IAdvertisingSetCallback + Send>) -> u32877     fn register_callback(&mut self, callback: Box<dyn IAdvertisingSetCallback + Send>) -> u32 {
878         self.callbacks.add_callback(callback)
879     }
880 
unregister_callback(&mut self, callback_id: u32) -> bool881     fn unregister_callback(&mut self, callback_id: u32) -> bool {
882         for s in self.sets.values_mut().filter(|s| s.callback_id() == callback_id) {
883             if s.is_valid() {
884                 self.gatt.lock().unwrap().advertiser.unregister(s.adv_id());
885             } else {
886                 s.set_stopped();
887             }
888         }
889         self.sets.retain(|_, s| s.callback_id() != callback_id || !s.is_valid());
890 
891         self.callbacks.remove_callback(callback_id)
892     }
893 
start_advertising_set( &mut self, mut parameters: AdvertisingSetParameters, advertise_data: AdvertiseData, scan_response: Option<AdvertiseData>, periodic_parameters: Option<PeriodicAdvertisingParameters>, periodic_data: Option<AdvertiseData>, duration: i32, max_ext_adv_events: i32, callback_id: u32, ) -> i32894     fn start_advertising_set(
895         &mut self,
896         mut parameters: AdvertisingSetParameters,
897         advertise_data: AdvertiseData,
898         scan_response: Option<AdvertiseData>,
899         periodic_parameters: Option<PeriodicAdvertisingParameters>,
900         periodic_data: Option<AdvertiseData>,
901         duration: i32,
902         max_ext_adv_events: i32,
903         callback_id: u32,
904     ) -> i32 {
905         if self.suspend_mode() != SuspendMode::Normal {
906             return INVALID_REG_ID;
907         }
908 
909         let device_name = self.get_adapter_name();
910         let adv_bytes = advertise_data.make_with(&device_name);
911         // TODO(b/311417973): Remove this once we have more robust /device/bluetooth APIs to control extended advertising
912         let is_legacy =
913             parameters.is_legacy && !AdvertiseData::can_upgrade(&mut parameters, &adv_bytes);
914         let params = parameters.into();
915         if !AdvertiseData::validate_raw_data(is_legacy, &adv_bytes) {
916             warn!("Failed to start advertising set with invalid advertise data");
917             return INVALID_REG_ID;
918         }
919         let scan_bytes =
920             if let Some(d) = scan_response { d.make_with(&device_name) } else { Vec::<u8>::new() };
921         if !AdvertiseData::validate_raw_data(is_legacy, &scan_bytes) {
922             warn!("Failed to start advertising set with invalid scan response");
923             return INVALID_REG_ID;
924         }
925         let periodic_params = if let Some(p) = periodic_parameters {
926             p.into()
927         } else {
928             bt_topshim::profiles::gatt::PeriodicAdvertisingParameters::default()
929         };
930         let periodic_bytes =
931             if let Some(d) = periodic_data { d.make_with(&device_name) } else { Vec::<u8>::new() };
932         if !AdvertiseData::validate_raw_data(false, &periodic_bytes) {
933             warn!("Failed to start advertising set with invalid periodic data");
934             return INVALID_REG_ID;
935         }
936         let adv_timeout = clamp(duration, 0, 0xffff) as u16;
937         let adv_events = clamp(max_ext_adv_events, 0, 0xff) as u8;
938 
939         let reg_id = self.new_reg_id();
940         let s = AdvertisingSetInfo::new(callback_id, adv_timeout, adv_events, is_legacy, reg_id);
941         self.add(s);
942 
943         self.gatt.lock().unwrap().advertiser.start_advertising_set(
944             reg_id,
945             params,
946             adv_bytes,
947             scan_bytes,
948             periodic_params,
949             periodic_bytes,
950             adv_timeout,
951             adv_events,
952         );
953         reg_id
954     }
955 
stop_advertising_set(&mut self, advertiser_id: i32)956     fn stop_advertising_set(&mut self, advertiser_id: i32) {
957         let s = if let Some(s) = self.get_by_advertiser_id(advertiser_id) {
958             s.clone()
959         } else {
960             return;
961         };
962 
963         if self.suspend_mode() != SuspendMode::Normal {
964             if !s.is_stopped() {
965                 info!("Deferred advertisement unregistering due to suspending");
966                 self.get_mut_by_advertiser_id(advertiser_id).unwrap().set_stopped();
967                 if let Some(cb) = self.get_callback(&s) {
968                     cb.on_advertising_set_stopped(advertiser_id);
969                 }
970             }
971             return;
972         }
973 
974         self.gatt.lock().unwrap().advertiser.unregister(s.adv_id());
975         if let Some(cb) = self.get_callback(&s) {
976             cb.on_advertising_set_stopped(advertiser_id);
977         }
978         self.remove_by_advertiser_id(advertiser_id);
979     }
980 
get_own_address(&mut self, advertiser_id: i32)981     fn get_own_address(&mut self, advertiser_id: i32) {
982         if self.suspend_mode() != SuspendMode::Normal {
983             return;
984         }
985 
986         if let Some(s) = self.get_by_advertiser_id(advertiser_id) {
987             self.gatt.lock().unwrap().advertiser.get_own_address(s.adv_id());
988         }
989     }
990 
enable_advertising_set( &mut self, advertiser_id: i32, enable: bool, duration: i32, max_ext_adv_events: i32, )991     fn enable_advertising_set(
992         &mut self,
993         advertiser_id: i32,
994         enable: bool,
995         duration: i32,
996         max_ext_adv_events: i32,
997     ) {
998         if self.suspend_mode() != SuspendMode::Normal {
999             return;
1000         }
1001 
1002         let adv_timeout = clamp(duration, 0, 0xffff) as u16;
1003         let adv_events = clamp(max_ext_adv_events, 0, 0xff) as u8;
1004 
1005         if let Some(s) = self.get_by_advertiser_id(advertiser_id) {
1006             self.gatt.lock().unwrap().advertiser.enable(
1007                 s.adv_id(),
1008                 enable,
1009                 adv_timeout,
1010                 adv_events,
1011             );
1012         }
1013     }
1014 
set_advertising_data(&mut self, advertiser_id: i32, data: AdvertiseData)1015     fn set_advertising_data(&mut self, advertiser_id: i32, data: AdvertiseData) {
1016         if self.suspend_mode() != SuspendMode::Normal {
1017             return;
1018         }
1019 
1020         let device_name = self.get_adapter_name();
1021         let bytes = data.make_with(&device_name);
1022 
1023         if let Some(s) = self.get_by_advertiser_id(advertiser_id) {
1024             if !AdvertiseData::validate_raw_data(s.is_legacy(), &bytes) {
1025                 warn!("AdvertiseManagerImpl {}: invalid advertise data to update", advertiser_id);
1026                 return;
1027             }
1028             self.gatt.lock().unwrap().advertiser.set_data(s.adv_id(), false, bytes);
1029         }
1030     }
1031 
set_raw_adv_data(&mut self, advertiser_id: i32, data: Vec<u8>)1032     fn set_raw_adv_data(&mut self, advertiser_id: i32, data: Vec<u8>) {
1033         if self.suspend_mode() != SuspendMode::Normal {
1034             return;
1035         }
1036 
1037         if let Some(s) = self.get_by_advertiser_id(advertiser_id) {
1038             if !AdvertiseData::validate_raw_data(s.is_legacy(), &data) {
1039                 warn!(
1040                     "AdvertiseManagerImpl {}: invalid raw advertise data to update",
1041                     advertiser_id
1042                 );
1043                 return;
1044             }
1045             self.gatt.lock().unwrap().advertiser.set_data(s.adv_id(), false, data);
1046         }
1047     }
1048 
set_scan_response_data(&mut self, advertiser_id: i32, data: AdvertiseData)1049     fn set_scan_response_data(&mut self, advertiser_id: i32, data: AdvertiseData) {
1050         if self.suspend_mode() != SuspendMode::Normal {
1051             return;
1052         }
1053 
1054         let device_name = self.get_adapter_name();
1055         let bytes = data.make_with(&device_name);
1056 
1057         if let Some(s) = self.get_by_advertiser_id(advertiser_id) {
1058             if !AdvertiseData::validate_raw_data(s.is_legacy(), &bytes) {
1059                 warn!("AdvertiseManagerImpl {}: invalid scan response to update", advertiser_id);
1060                 return;
1061             }
1062             self.gatt.lock().unwrap().advertiser.set_data(s.adv_id(), true, bytes);
1063         }
1064     }
1065 
set_advertising_parameters( &mut self, advertiser_id: i32, parameters: AdvertisingSetParameters, )1066     fn set_advertising_parameters(
1067         &mut self,
1068         advertiser_id: i32,
1069         parameters: AdvertisingSetParameters,
1070     ) {
1071         if self.suspend_mode() != SuspendMode::Normal {
1072             return;
1073         }
1074 
1075         let params = parameters.into();
1076 
1077         if let Some(s) = self.get_by_advertiser_id(advertiser_id) {
1078             let was_enabled = s.is_enabled();
1079             if was_enabled {
1080                 self.gatt.lock().unwrap().advertiser.enable(
1081                     s.adv_id(),
1082                     false,
1083                     s.adv_timeout(),
1084                     s.adv_events(),
1085                 );
1086             }
1087             self.gatt.lock().unwrap().advertiser.set_parameters(s.adv_id(), params);
1088             if was_enabled {
1089                 self.gatt.lock().unwrap().advertiser.enable(
1090                     s.adv_id(),
1091                     true,
1092                     s.adv_timeout(),
1093                     s.adv_events(),
1094                 );
1095             }
1096         }
1097     }
1098 
set_periodic_advertising_parameters( &mut self, advertiser_id: i32, parameters: PeriodicAdvertisingParameters, )1099     fn set_periodic_advertising_parameters(
1100         &mut self,
1101         advertiser_id: i32,
1102         parameters: PeriodicAdvertisingParameters,
1103     ) {
1104         if self.suspend_mode() != SuspendMode::Normal {
1105             return;
1106         }
1107 
1108         let params = parameters.into();
1109 
1110         if let Some(s) = self.get_by_advertiser_id(advertiser_id) {
1111             self.gatt
1112                 .lock()
1113                 .unwrap()
1114                 .advertiser
1115                 .set_periodic_advertising_parameters(s.adv_id(), params);
1116         }
1117     }
1118 
set_periodic_advertising_data(&mut self, advertiser_id: i32, data: AdvertiseData)1119     fn set_periodic_advertising_data(&mut self, advertiser_id: i32, data: AdvertiseData) {
1120         if self.suspend_mode() != SuspendMode::Normal {
1121             return;
1122         }
1123 
1124         let device_name = self.get_adapter_name();
1125         let bytes = data.make_with(&device_name);
1126 
1127         if let Some(s) = self.get_by_advertiser_id(advertiser_id) {
1128             if !AdvertiseData::validate_raw_data(false, &bytes) {
1129                 warn!("AdvertiseManagerImpl {}: invalid periodic data to update", advertiser_id);
1130                 return;
1131             }
1132             self.gatt.lock().unwrap().advertiser.set_periodic_advertising_data(s.adv_id(), bytes);
1133         }
1134     }
1135 
set_periodic_advertising_enable( &mut self, advertiser_id: i32, enable: bool, include_adi: bool, )1136     fn set_periodic_advertising_enable(
1137         &mut self,
1138         advertiser_id: i32,
1139         enable: bool,
1140         include_adi: bool,
1141     ) {
1142         if self.suspend_mode() != SuspendMode::Normal {
1143             return;
1144         }
1145         if let Some(s) = self.get_by_advertiser_id(advertiser_id) {
1146             self.gatt.lock().unwrap().advertiser.set_periodic_advertising_enable(
1147                 s.adv_id(),
1148                 enable,
1149                 include_adi,
1150             );
1151         }
1152     }
1153 }
1154 
1155 #[btif_callbacks_dispatcher(dispatch_le_adv_callbacks, GattAdvCallbacks)]
1156 pub(crate) trait BtifGattAdvCallbacks {
1157     #[btif_callback(OnAdvertisingSetStarted)]
on_advertising_set_started( &mut self, reg_id: i32, advertiser_id: u8, tx_power: i8, status: AdvertisingStatus, )1158     fn on_advertising_set_started(
1159         &mut self,
1160         reg_id: i32,
1161         advertiser_id: u8,
1162         tx_power: i8,
1163         status: AdvertisingStatus,
1164     );
1165 
1166     #[btif_callback(OnAdvertisingEnabled)]
on_advertising_enabled(&mut self, adv_id: u8, enabled: bool, status: AdvertisingStatus)1167     fn on_advertising_enabled(&mut self, adv_id: u8, enabled: bool, status: AdvertisingStatus);
1168 
1169     #[btif_callback(OnAdvertisingDataSet)]
on_advertising_data_set(&mut self, adv_id: u8, status: AdvertisingStatus)1170     fn on_advertising_data_set(&mut self, adv_id: u8, status: AdvertisingStatus);
1171 
1172     #[btif_callback(OnScanResponseDataSet)]
on_scan_response_data_set(&mut self, adv_id: u8, status: AdvertisingStatus)1173     fn on_scan_response_data_set(&mut self, adv_id: u8, status: AdvertisingStatus);
1174 
1175     #[btif_callback(OnAdvertisingParametersUpdated)]
on_advertising_parameters_updated( &mut self, adv_id: u8, tx_power: i8, status: AdvertisingStatus, )1176     fn on_advertising_parameters_updated(
1177         &mut self,
1178         adv_id: u8,
1179         tx_power: i8,
1180         status: AdvertisingStatus,
1181     );
1182 
1183     #[btif_callback(OnPeriodicAdvertisingParametersUpdated)]
on_periodic_advertising_parameters_updated(&mut self, adv_id: u8, status: AdvertisingStatus)1184     fn on_periodic_advertising_parameters_updated(&mut self, adv_id: u8, status: AdvertisingStatus);
1185 
1186     #[btif_callback(OnPeriodicAdvertisingDataSet)]
on_periodic_advertising_data_set(&mut self, adv_id: u8, status: AdvertisingStatus)1187     fn on_periodic_advertising_data_set(&mut self, adv_id: u8, status: AdvertisingStatus);
1188 
1189     #[btif_callback(OnPeriodicAdvertisingEnabled)]
on_periodic_advertising_enabled( &mut self, adv_id: u8, enabled: bool, status: AdvertisingStatus, )1190     fn on_periodic_advertising_enabled(
1191         &mut self,
1192         adv_id: u8,
1193         enabled: bool,
1194         status: AdvertisingStatus,
1195     );
1196 
1197     #[btif_callback(OnOwnAddressRead)]
on_own_address_read(&mut self, adv_id: u8, addr_type: u8, address: RawAddress)1198     fn on_own_address_read(&mut self, adv_id: u8, addr_type: u8, address: RawAddress);
1199 }
1200 
1201 impl BtifGattAdvCallbacks for AdvertiseManagerImpl {
on_advertising_set_started( &mut self, reg_id: i32, advertiser_id: u8, tx_power: i8, status: AdvertisingStatus, )1202     fn on_advertising_set_started(
1203         &mut self,
1204         reg_id: i32,
1205         advertiser_id: u8,
1206         tx_power: i8,
1207         status: AdvertisingStatus,
1208     ) {
1209         debug!(
1210             "on_advertising_set_started(): reg_id = {}, advertiser_id = {}, tx_power = {}, status = {:?}",
1211             reg_id, advertiser_id, tx_power, status
1212         );
1213 
1214         let s = if let Some(s) = self.sets.get_mut(&reg_id) {
1215             s
1216         } else {
1217             error!("AdvertisingSetInfo not found");
1218             // An unknown advertising set has started. Unregister it anyway.
1219             self.gatt.lock().unwrap().advertiser.unregister(advertiser_id);
1220             return;
1221         };
1222 
1223         if s.is_stopped() {
1224             // The advertising set needs to be stopped. This could happen when |unregister_callback|
1225             // is called before an advertising becomes ready.
1226             self.gatt.lock().unwrap().advertiser.unregister(advertiser_id);
1227             self.sets.remove(&reg_id);
1228             return;
1229         }
1230 
1231         s.set_adv_id(Some(advertiser_id.into()));
1232         s.set_enabled(status == AdvertisingStatus::Success);
1233 
1234         if let Some(cb) = self.callbacks.get_by_id_mut(s.callback_id()) {
1235             cb.on_advertising_set_started(reg_id, advertiser_id.into(), tx_power.into(), status);
1236         }
1237 
1238         if status != AdvertisingStatus::Success {
1239             warn!(
1240                 "on_advertising_set_started(): failed! reg_id = {}, status = {:?}",
1241                 reg_id, status
1242             );
1243             self.sets.remove(&reg_id);
1244         }
1245     }
1246 
on_advertising_enabled(&mut self, adv_id: u8, enabled: bool, status: AdvertisingStatus)1247     fn on_advertising_enabled(&mut self, adv_id: u8, enabled: bool, status: AdvertisingStatus) {
1248         debug!(
1249             "on_advertising_enabled(): adv_id = {}, enabled = {}, status = {:?}",
1250             adv_id, enabled, status
1251         );
1252 
1253         let advertiser_id: i32 = adv_id.into();
1254 
1255         if let Some(s) = self.get_mut_by_advertiser_id(advertiser_id) {
1256             s.set_enabled(enabled);
1257         } else {
1258             return;
1259         }
1260 
1261         let s = self.get_by_advertiser_id(advertiser_id).unwrap().clone();
1262         if let Some(cb) = self.get_callback(&s) {
1263             cb.on_advertising_enabled(advertiser_id, enabled, status);
1264         }
1265 
1266         if self.suspend_mode() == SuspendMode::Suspending {
1267             if self.enabled_sets().count() == 0 {
1268                 self.set_suspend_mode(SuspendMode::Suspended);
1269             }
1270         }
1271     }
1272 
on_advertising_data_set(&mut self, adv_id: u8, status: AdvertisingStatus)1273     fn on_advertising_data_set(&mut self, adv_id: u8, status: AdvertisingStatus) {
1274         debug!("on_advertising_data_set(): adv_id = {}, status = {:?}", adv_id, status);
1275 
1276         let advertiser_id: i32 = adv_id.into();
1277         if None == self.get_by_advertiser_id(advertiser_id) {
1278             return;
1279         }
1280         let s = self.get_by_advertiser_id(advertiser_id).unwrap().clone();
1281 
1282         if let Some(cb) = self.get_callback(&s) {
1283             cb.on_advertising_data_set(advertiser_id, status);
1284         }
1285     }
1286 
on_scan_response_data_set(&mut self, adv_id: u8, status: AdvertisingStatus)1287     fn on_scan_response_data_set(&mut self, adv_id: u8, status: AdvertisingStatus) {
1288         debug!("on_scan_response_data_set(): adv_id = {}, status = {:?}", adv_id, status);
1289 
1290         let advertiser_id: i32 = adv_id.into();
1291         if None == self.get_by_advertiser_id(advertiser_id) {
1292             return;
1293         }
1294         let s = self.get_by_advertiser_id(advertiser_id).unwrap().clone();
1295 
1296         if let Some(cb) = self.get_callback(&s) {
1297             cb.on_scan_response_data_set(advertiser_id, status);
1298         }
1299     }
1300 
on_advertising_parameters_updated( &mut self, adv_id: u8, tx_power: i8, status: AdvertisingStatus, )1301     fn on_advertising_parameters_updated(
1302         &mut self,
1303         adv_id: u8,
1304         tx_power: i8,
1305         status: AdvertisingStatus,
1306     ) {
1307         debug!(
1308             "on_advertising_parameters_updated(): adv_id = {}, tx_power = {}, status = {:?}",
1309             adv_id, tx_power, status
1310         );
1311 
1312         let advertiser_id: i32 = adv_id.into();
1313         if None == self.get_by_advertiser_id(advertiser_id) {
1314             return;
1315         }
1316         let s = self.get_by_advertiser_id(advertiser_id).unwrap().clone();
1317 
1318         if let Some(cb) = self.get_callback(&s) {
1319             cb.on_advertising_parameters_updated(advertiser_id, tx_power.into(), status);
1320         }
1321     }
1322 
on_periodic_advertising_parameters_updated( &mut self, adv_id: u8, status: AdvertisingStatus, )1323     fn on_periodic_advertising_parameters_updated(
1324         &mut self,
1325         adv_id: u8,
1326         status: AdvertisingStatus,
1327     ) {
1328         debug!(
1329             "on_periodic_advertising_parameters_updated(): adv_id = {}, status = {:?}",
1330             adv_id, status
1331         );
1332 
1333         let advertiser_id: i32 = adv_id.into();
1334         if None == self.get_by_advertiser_id(advertiser_id) {
1335             return;
1336         }
1337         let s = self.get_by_advertiser_id(advertiser_id).unwrap().clone();
1338 
1339         if let Some(cb) = self.get_callback(&s) {
1340             cb.on_periodic_advertising_parameters_updated(advertiser_id, status);
1341         }
1342     }
1343 
on_periodic_advertising_data_set(&mut self, adv_id: u8, status: AdvertisingStatus)1344     fn on_periodic_advertising_data_set(&mut self, adv_id: u8, status: AdvertisingStatus) {
1345         debug!("on_periodic_advertising_data_set(): adv_id = {}, status = {:?}", adv_id, status);
1346 
1347         let advertiser_id: i32 = adv_id.into();
1348         if None == self.get_by_advertiser_id(advertiser_id) {
1349             return;
1350         }
1351         let s = self.get_by_advertiser_id(advertiser_id).unwrap().clone();
1352 
1353         if let Some(cb) = self.get_callback(&s) {
1354             cb.on_periodic_advertising_data_set(advertiser_id, status);
1355         }
1356     }
1357 
on_periodic_advertising_enabled( &mut self, adv_id: u8, enabled: bool, status: AdvertisingStatus, )1358     fn on_periodic_advertising_enabled(
1359         &mut self,
1360         adv_id: u8,
1361         enabled: bool,
1362         status: AdvertisingStatus,
1363     ) {
1364         debug!(
1365             "on_periodic_advertising_enabled(): adv_id = {}, enabled = {}, status = {:?}",
1366             adv_id, enabled, status
1367         );
1368 
1369         let advertiser_id: i32 = adv_id.into();
1370         if None == self.get_by_advertiser_id(advertiser_id) {
1371             return;
1372         }
1373         let s = self.get_by_advertiser_id(advertiser_id).unwrap().clone();
1374 
1375         if let Some(cb) = self.get_callback(&s) {
1376             cb.on_periodic_advertising_enabled(advertiser_id, enabled, status);
1377         }
1378     }
1379 
on_own_address_read(&mut self, adv_id: u8, addr_type: u8, address: RawAddress)1380     fn on_own_address_read(&mut self, adv_id: u8, addr_type: u8, address: RawAddress) {
1381         debug!(
1382             "on_own_address_read(): adv_id = {}, addr_type = {}, address = {}",
1383             adv_id,
1384             addr_type,
1385             DisplayAddress(&address)
1386         );
1387 
1388         let advertiser_id: i32 = adv_id.into();
1389         if None == self.get_by_advertiser_id(advertiser_id) {
1390             return;
1391         }
1392         let s = self.get_by_advertiser_id(advertiser_id).unwrap().clone();
1393 
1394         if let Some(cb) = self.get_callback(&s) {
1395             cb.on_own_address_read(advertiser_id, addr_type.into(), address);
1396         }
1397     }
1398 }
1399 
1400 /// The underlying legacy advertising rotates every SOFTWARE_ROTATION_INTERVAL seconds.
1401 const SOFTWARE_ROTATION_INTERVAL: Duration = Duration::from_secs(2);
1402 
1403 /// The ID of a software rotation advertising.
1404 ///
1405 /// From DBus API's perspective this is used as both Advertiser ID and Register ID.
1406 /// Unlike the extended advertising stack we can't propagate the LibBluetooth Advertiser ID to
1407 /// DBus clients because there can be at most 1 advertiser in LibBluetooth layer at the same time.
1408 pub type SoftwareRotationAdvertierId = i32;
1409 
1410 struct SoftwareRotationAdvertiseInfo {
1411     id: SoftwareRotationAdvertierId,
1412     callback_id: u32,
1413 
1414     advertising_params: AdvertisingSetParameters,
1415     advertising_data: Vec<u8>,
1416     scan_response_data: Vec<u8>,
1417 
1418     /// Filled in on the first time the advertiser started.
1419     tx_power: Option<i32>,
1420 
1421     /// True if it's advertising (from DBus client's perspective), false otherwise.
1422     enabled: bool,
1423     duration: i32,
1424     /// None means no timeout
1425     expire_time: Option<Instant>,
1426 }
1427 
1428 enum SoftwareRotationAdvertiseState {
1429     /// No advertiser is running in LibBluetooth.
1430     Stopped,
1431     /// A StartAdvertisingSet call to LibBluetooth is pending.
1432     Pending(SoftwareRotationAdvertierId),
1433     /// An advertiser is running in LibBluetooth, i.e., an OnAdvertisingSetStarted is received.
1434     /// Parameters: ID, LibBluetooth BLE Advertiser ID, rotation timer handle
1435     Advertising(SoftwareRotationAdvertierId, u8, JoinHandle<()>),
1436 }
1437 
1438 struct SoftwareRotationAdvertiseManagerImpl {
1439     callbacks: Callbacks<dyn IAdvertisingSetCallback + Send>,
1440     suspend_mode: SuspendMode,
1441     gatt: Arc<Mutex<Gatt>>,
1442     adapter: Arc<Mutex<Box<Bluetooth>>>,
1443     tx: Sender<Message>,
1444 
1445     state: SoftwareRotationAdvertiseState,
1446     adv_info: HashMap<SoftwareRotationAdvertierId, SoftwareRotationAdvertiseInfo>,
1447     /// The enabled advertising sets to be rotate.
1448     /// When they are removed from the queue, OnAdvertisingEnabled needs to be sent.
1449     /// Note that the current advertiser running in LibBluetooth must *NOT* be in the queue.
1450     adv_queue: VecDeque<SoftwareRotationAdvertierId>,
1451 }
1452 
1453 impl SoftwareRotationAdvertiseManagerImpl {
new( tx: Sender<Message>, gatt: Arc<Mutex<Gatt>>, adapter: Arc<Mutex<Box<Bluetooth>>>, ) -> Self1454     fn new(
1455         tx: Sender<Message>,
1456         gatt: Arc<Mutex<Gatt>>,
1457         adapter: Arc<Mutex<Box<Bluetooth>>>,
1458     ) -> Self {
1459         Self {
1460             callbacks: Callbacks::new(tx.clone(), Message::AdvertiserCallbackDisconnected),
1461             suspend_mode: SuspendMode::Normal,
1462             gatt,
1463             adapter,
1464             tx,
1465             state: SoftwareRotationAdvertiseState::Stopped,
1466             adv_info: HashMap::new(),
1467             adv_queue: VecDeque::new(),
1468         }
1469     }
1470 }
1471 
1472 impl SoftwareRotationAdvertiseManagerImpl {
1473     /// Updates suspend mode.
set_suspend_mode(&mut self, suspend_mode: SuspendMode)1474     fn set_suspend_mode(&mut self, suspend_mode: SuspendMode) {
1475         if suspend_mode != self.suspend_mode {
1476             self.suspend_mode = suspend_mode.clone();
1477             self.callbacks.for_all_callbacks(|cb| {
1478                 cb.on_suspend_mode_change(suspend_mode.clone());
1479             });
1480         }
1481     }
1482 
get_adapter_name(&self) -> String1483     fn get_adapter_name(&self) -> String {
1484         self.adapter.lock().unwrap().get_name()
1485     }
1486 
1487     /// Returns the ID of the advertiser running in LibBluetooth.
current_id(&self) -> Option<SoftwareRotationAdvertierId>1488     fn current_id(&self) -> Option<SoftwareRotationAdvertierId> {
1489         match &self.state {
1490             SoftwareRotationAdvertiseState::Pending(id) => Some(*id),
1491             SoftwareRotationAdvertiseState::Advertising(id, _, _) => Some(*id),
1492             SoftwareRotationAdvertiseState::Stopped => None,
1493         }
1494     }
1495 
1496     /// Returns the minimum unoccupied ID from 0.
new_id(&mut self) -> SoftwareRotationAdvertierId1497     fn new_id(&mut self) -> SoftwareRotationAdvertierId {
1498         // The advertiser running in LibBluetooth may have been removed in this layer.
1499         // Avoid conflicting with it.
1500         let current_id = self.current_id();
1501         (0..)
1502             .find(|id| !self.adv_info.contains_key(id) && Some(*id) != current_id)
1503             .expect("There must be an unoccupied register ID")
1504     }
1505 
is_pending(&self) -> bool1506     fn is_pending(&self) -> bool {
1507         matches!(&self.state, SoftwareRotationAdvertiseState::Pending(_))
1508     }
1509 
is_stopped(&self) -> bool1510     fn is_stopped(&self) -> bool {
1511         matches!(&self.state, SoftwareRotationAdvertiseState::Stopped)
1512     }
1513 
1514     /// Clears the removed or disabled advertisers from the queue and invokes callback.
refresh_queue(&mut self)1515     fn refresh_queue(&mut self) {
1516         let now = Instant::now();
1517         let adv_info = &mut self.adv_info;
1518         let callbacks = &mut self.callbacks;
1519         self.adv_queue.retain(|id| {
1520             let Some(info) = adv_info.get_mut(id) else {
1521                 // This advertiser has been removed.
1522                 return false;
1523             };
1524             if info.expire_time.map_or(false, |t| t < now) {
1525                 // This advertiser has expired.
1526                 info.enabled = false;
1527                 callbacks.get_by_id_mut(info.callback_id).map(|cb| {
1528                     cb.on_advertising_enabled(info.id, false, AdvertisingStatus::Success);
1529                 });
1530             }
1531             info.enabled
1532         });
1533     }
1534 
stop_current_advertising(&mut self)1535     fn stop_current_advertising(&mut self) {
1536         match &self.state {
1537             SoftwareRotationAdvertiseState::Advertising(id, adv_id, handle) => {
1538                 handle.abort();
1539                 self.gatt.lock().unwrap().advertiser.unregister(*adv_id);
1540                 self.adv_queue.push_back(*id);
1541                 self.state = SoftwareRotationAdvertiseState::Stopped;
1542             }
1543             SoftwareRotationAdvertiseState::Pending(_) => {
1544                 error!("stop_current_advertising: Unexpected Pending state");
1545             }
1546             SoftwareRotationAdvertiseState::Stopped => {}
1547         };
1548     }
1549 
start_next_advertising(&mut self)1550     fn start_next_advertising(&mut self) {
1551         match &self.state {
1552             SoftwareRotationAdvertiseState::Stopped => {
1553                 self.state = loop {
1554                     let Some(id) = self.adv_queue.pop_front() else {
1555                         break SoftwareRotationAdvertiseState::Stopped;
1556                     };
1557                     let Some(info) = self.adv_info.get(&id) else {
1558                         error!("start_next_advertising: Unknown ID, which means queue is not refreshed!");
1559                         continue;
1560                     };
1561                     self.gatt.lock().unwrap().advertiser.start_advertising_set(
1562                         id,
1563                         info.advertising_params.clone().into(),
1564                         info.advertising_data.clone(),
1565                         info.scan_response_data.clone(),
1566                         Default::default(), // Unsupported periodic_parameters
1567                         vec![],             // Unsupported periodic_data
1568                         0,                  // Set no timeout. Timeout is controlled in this layer.
1569                         0,                  // Unsupported max_ext_adv_events
1570                     );
1571                     break SoftwareRotationAdvertiseState::Pending(id);
1572                 }
1573             }
1574             SoftwareRotationAdvertiseState::Pending(_) => {
1575                 error!("start_next_advertising: Unexpected Pending state");
1576             }
1577             SoftwareRotationAdvertiseState::Advertising(_, _, _) => {
1578                 error!("start_next_advertising: Unexpected Advertising state");
1579             }
1580         };
1581     }
1582 
run_rotate(&mut self)1583     fn run_rotate(&mut self) {
1584         if self.is_pending() {
1585             return;
1586         }
1587         let Some(current_id) = self.current_id() else {
1588             // State is Stopped. Try to start next one.
1589             self.refresh_queue();
1590             self.start_next_advertising();
1591             return;
1592         };
1593         // We are Advertising. Checks if the current advertiser is still allowed
1594         // to advertise, or if we should schedule the next one in the queue.
1595         let current_is_enabled = {
1596             let now = Instant::now();
1597             if let Some(info) = self.adv_info.get(&current_id) {
1598                 if info.enabled {
1599                     info.expire_time.map_or(true, |t| t >= now)
1600                 } else {
1601                     false
1602                 }
1603             } else {
1604                 false
1605             }
1606         };
1607         if !current_is_enabled {
1608             // If current advertiser is not allowed to advertise,
1609             // stop it and then let |refresh_queue| handle the callback.
1610             self.stop_current_advertising();
1611             self.refresh_queue();
1612             self.start_next_advertising();
1613         } else {
1614             // Current advertiser is still enabled, refresh the other advertisers in the queue.
1615             self.refresh_queue();
1616             if self.adv_queue.is_empty() {
1617                 // No need to rotate.
1618             } else {
1619                 self.stop_current_advertising();
1620                 self.start_next_advertising();
1621             }
1622         }
1623     }
1624 }
1625 
1626 impl AdvertiseManagerOps for SoftwareRotationAdvertiseManagerImpl {
enter_suspend(&mut self)1627     fn enter_suspend(&mut self) {
1628         if self.suspend_mode != SuspendMode::Normal {
1629             return;
1630         }
1631 
1632         self.set_suspend_mode(SuspendMode::Suspending);
1633         if self.is_pending() {
1634             // We will unregister it on_advertising_set_started and then set mode to suspended.
1635             return;
1636         }
1637         self.stop_current_advertising();
1638         self.set_suspend_mode(SuspendMode::Suspended);
1639     }
1640 
exit_suspend(&mut self)1641     fn exit_suspend(&mut self) {
1642         if self.suspend_mode != SuspendMode::Suspended {
1643             return;
1644         }
1645         self.refresh_queue();
1646         self.start_next_advertising();
1647         self.set_suspend_mode(SuspendMode::Normal);
1648     }
1649 
handle_action(&mut self, action: AdvertiserActions)1650     fn handle_action(&mut self, action: AdvertiserActions) {
1651         match action {
1652             AdvertiserActions::RunRotate => {
1653                 if self.suspend_mode == SuspendMode::Normal {
1654                     self.run_rotate();
1655                 }
1656             }
1657         }
1658     }
1659 }
1660 
1661 /// Generates expire time from now per the definition in IBluetoothAdvertiseManager
1662 ///
1663 /// None means never timeout.
gen_expire_time_from_now(duration: i32) -> Option<Instant>1664 fn gen_expire_time_from_now(duration: i32) -> Option<Instant> {
1665     let duration = clamp(duration, 0, 0xffff) as u64;
1666     if duration != 0 {
1667         Some(Instant::now() + Duration::from_millis(duration * 10))
1668     } else {
1669         None
1670     }
1671 }
1672 
1673 impl IBluetoothAdvertiseManager for SoftwareRotationAdvertiseManagerImpl {
register_callback(&mut self, callback: Box<dyn IAdvertisingSetCallback + Send>) -> u321674     fn register_callback(&mut self, callback: Box<dyn IAdvertisingSetCallback + Send>) -> u32 {
1675         self.callbacks.add_callback(callback)
1676     }
1677 
unregister_callback(&mut self, callback_id: u32) -> bool1678     fn unregister_callback(&mut self, callback_id: u32) -> bool {
1679         self.adv_info.retain(|_, info| info.callback_id != callback_id);
1680         let ret = self.callbacks.remove_callback(callback_id);
1681         if let Some(current_id) = self.current_id() {
1682             if !self.adv_info.contains_key(&current_id) {
1683                 self.run_rotate();
1684             }
1685         }
1686         ret
1687     }
1688 
start_advertising_set( &mut self, advertising_params: AdvertisingSetParameters, advertising_data: AdvertiseData, scan_response_data: Option<AdvertiseData>, periodic_parameters: Option<PeriodicAdvertisingParameters>, periodic_data: Option<AdvertiseData>, duration: i32, max_ext_adv_events: i32, callback_id: u32, ) -> i321689     fn start_advertising_set(
1690         &mut self,
1691         advertising_params: AdvertisingSetParameters,
1692         advertising_data: AdvertiseData,
1693         scan_response_data: Option<AdvertiseData>,
1694         periodic_parameters: Option<PeriodicAdvertisingParameters>,
1695         periodic_data: Option<AdvertiseData>,
1696         duration: i32,
1697         max_ext_adv_events: i32,
1698         callback_id: u32,
1699     ) -> i32 {
1700         if self.suspend_mode != SuspendMode::Normal {
1701             return INVALID_REG_ID;
1702         }
1703 
1704         let is_legacy = advertising_params.is_legacy;
1705         let device_name = self.get_adapter_name();
1706 
1707         let advertising_data = advertising_data.make_with(&device_name);
1708         if !AdvertiseData::validate_raw_data(is_legacy, &advertising_data) {
1709             warn!("Failed to start advertising set with invalid advertising data");
1710             return INVALID_REG_ID;
1711         }
1712 
1713         let scan_response_data =
1714             scan_response_data.map_or(vec![], |data| data.make_with(&device_name));
1715         if !AdvertiseData::validate_raw_data(is_legacy, &scan_response_data) {
1716             warn!("Failed to start advertising set with invalid scan response data");
1717             return INVALID_REG_ID;
1718         }
1719 
1720         if periodic_parameters.is_some() {
1721             warn!("Periodic parameters is not supported in software rotation stack, ignored");
1722         }
1723         if periodic_data.is_some() {
1724             warn!("Periodic data is not supported in software rotation stack, ignored");
1725         }
1726         if max_ext_adv_events != 0 {
1727             warn!("max_ext_adv_events is not supported in software rotation stack, ignored");
1728         }
1729 
1730         let id = self.new_id();
1731 
1732         // expire_time will be determined on this advertiser is started at the first time.
1733         self.adv_info.insert(
1734             id,
1735             SoftwareRotationAdvertiseInfo {
1736                 id,
1737                 callback_id,
1738                 advertising_params,
1739                 advertising_data,
1740                 scan_response_data,
1741                 tx_power: None,
1742                 enabled: true,
1743                 duration,
1744                 expire_time: None,
1745             },
1746         );
1747         // Schedule it as the next one and rotate.
1748         self.adv_queue.push_front(id);
1749         self.run_rotate();
1750 
1751         id
1752     }
1753 
stop_advertising_set(&mut self, adv_id: i32)1754     fn stop_advertising_set(&mut self, adv_id: i32) {
1755         let current_id = self.current_id();
1756         let Some(info) = self.adv_info.remove(&adv_id) else {
1757             warn!("stop_advertising_set: Unknown adv_id {}", adv_id);
1758             return;
1759         };
1760         self.callbacks.get_by_id_mut(info.callback_id).map(|cb| {
1761             cb.on_advertising_set_stopped(info.id);
1762         });
1763         if current_id == Some(info.id) {
1764             self.run_rotate();
1765         }
1766     }
1767 
get_own_address(&mut self, _adv_id: i32)1768     fn get_own_address(&mut self, _adv_id: i32) {
1769         error!("get_own_address is not supported in software rotation stack");
1770     }
1771 
enable_advertising_set( &mut self, adv_id: i32, enable: bool, duration: i32, max_ext_adv_events: i32, )1772     fn enable_advertising_set(
1773         &mut self,
1774         adv_id: i32,
1775         enable: bool,
1776         duration: i32,
1777         max_ext_adv_events: i32,
1778     ) {
1779         if self.suspend_mode != SuspendMode::Normal {
1780             return;
1781         }
1782 
1783         let current_id = self.current_id();
1784         let Some(info) = self.adv_info.get_mut(&adv_id) else {
1785             warn!("enable_advertising_set: Unknown adv_id {}", adv_id);
1786             return;
1787         };
1788 
1789         if max_ext_adv_events != 0 {
1790             warn!("max_ext_adv_events is not supported in software rotation stack, ignored");
1791         }
1792 
1793         info.enabled = enable;
1794         // We won't really call enable() to LibBluetooth so calculate the expire time right now.
1795         info.expire_time = gen_expire_time_from_now(duration);
1796         // This actually won't be used as the expire_time is already determined.
1797         // Still fill it in to keep the data updated.
1798         info.duration = duration;
1799 
1800         if enable && !self.adv_queue.contains(&info.id) && current_id != Some(info.id) {
1801             // The adv was not enabled and not in the queue. Invoke callback and queue it.
1802             self.callbacks.get_by_id_mut(info.callback_id).map(|cb| {
1803                 cb.on_advertising_enabled(info.id, false, AdvertisingStatus::Success);
1804             });
1805             self.adv_queue.push_back(info.id);
1806             if self.is_stopped() {
1807                 self.start_next_advertising();
1808             }
1809         } else if !enable && current_id == Some(info.id) {
1810             self.run_rotate();
1811         }
1812     }
1813 
set_advertising_data(&mut self, adv_id: i32, data: AdvertiseData)1814     fn set_advertising_data(&mut self, adv_id: i32, data: AdvertiseData) {
1815         if self.suspend_mode != SuspendMode::Normal {
1816             return;
1817         }
1818 
1819         let current_id = self.current_id();
1820         let device_name = self.get_adapter_name();
1821         let Some(info) = self.adv_info.get_mut(&adv_id) else {
1822             warn!("set_advertising_data: Unknown adv_id {}", adv_id);
1823             return;
1824         };
1825         let data = data.make_with(&device_name);
1826         if !AdvertiseData::validate_raw_data(info.advertising_params.is_legacy, &data) {
1827             warn!("set_advertising_data {}: invalid advertise data to update", adv_id);
1828             return;
1829         }
1830         info.advertising_data = data;
1831         self.callbacks.get_by_id_mut(info.callback_id).map(|cb| {
1832             cb.on_advertising_data_set(info.id, AdvertisingStatus::Success);
1833         });
1834 
1835         if current_id == Some(info.id) {
1836             self.run_rotate();
1837         }
1838     }
1839 
set_raw_adv_data(&mut self, adv_id: i32, data: Vec<u8>)1840     fn set_raw_adv_data(&mut self, adv_id: i32, data: Vec<u8>) {
1841         if self.suspend_mode != SuspendMode::Normal {
1842             return;
1843         }
1844 
1845         let current_id = self.current_id();
1846         let Some(info) = self.adv_info.get_mut(&adv_id) else {
1847             warn!("set_raw_adv_data: Unknown adv_id {}", adv_id);
1848             return;
1849         };
1850         if !AdvertiseData::validate_raw_data(info.advertising_params.is_legacy, &data) {
1851             warn!("set_raw_adv_data {}: invalid raw advertise data to update", adv_id);
1852             return;
1853         }
1854         info.advertising_data = data;
1855         self.callbacks.get_by_id_mut(info.callback_id).map(|cb| {
1856             cb.on_advertising_data_set(info.id, AdvertisingStatus::Success);
1857         });
1858 
1859         if current_id == Some(info.id) {
1860             self.run_rotate();
1861         }
1862     }
1863 
set_scan_response_data(&mut self, adv_id: i32, data: AdvertiseData)1864     fn set_scan_response_data(&mut self, adv_id: i32, data: AdvertiseData) {
1865         if self.suspend_mode != SuspendMode::Normal {
1866             return;
1867         }
1868 
1869         let current_id = self.current_id();
1870         let device_name = self.get_adapter_name();
1871         let Some(info) = self.adv_info.get_mut(&adv_id) else {
1872             warn!("set_scan_response_data: Unknown adv_id {}", adv_id);
1873             return;
1874         };
1875         let data = data.make_with(&device_name);
1876         if !AdvertiseData::validate_raw_data(info.advertising_params.is_legacy, &data) {
1877             warn!("set_scan_response_data {}: invalid scan response to update", adv_id);
1878             return;
1879         }
1880         info.scan_response_data = data;
1881         self.callbacks.get_by_id_mut(info.callback_id).map(|cb| {
1882             cb.on_scan_response_data_set(info.id, AdvertisingStatus::Success);
1883         });
1884 
1885         if current_id == Some(info.id) {
1886             self.run_rotate();
1887         }
1888     }
1889 
set_advertising_parameters(&mut self, adv_id: i32, params: AdvertisingSetParameters)1890     fn set_advertising_parameters(&mut self, adv_id: i32, params: AdvertisingSetParameters) {
1891         if self.suspend_mode != SuspendMode::Normal {
1892             return;
1893         }
1894 
1895         let current_id = self.current_id();
1896         let Some(info) = self.adv_info.get_mut(&adv_id) else {
1897             warn!("set_advertising_parameters: Unknown adv_id {}", adv_id);
1898             return;
1899         };
1900         info.advertising_params = params;
1901         let Some(tx_power) = info.tx_power else {
1902             error!("set_advertising_parameters: tx_power is None! Is this called before adv has started?");
1903             return;
1904         };
1905         self.callbacks.get_by_id_mut(info.callback_id).map(|cb| {
1906             cb.on_advertising_parameters_updated(info.id, tx_power, AdvertisingStatus::Success);
1907         });
1908 
1909         if current_id == Some(info.id) {
1910             self.run_rotate();
1911         }
1912     }
1913 
set_periodic_advertising_parameters( &mut self, _adv_id: i32, _parameters: PeriodicAdvertisingParameters, )1914     fn set_periodic_advertising_parameters(
1915         &mut self,
1916         _adv_id: i32,
1917         _parameters: PeriodicAdvertisingParameters,
1918     ) {
1919         error!("set_periodic_advertising_parameters is not supported in software rotation stack");
1920     }
1921 
set_periodic_advertising_data(&mut self, _adv_id: i32, _data: AdvertiseData)1922     fn set_periodic_advertising_data(&mut self, _adv_id: i32, _data: AdvertiseData) {
1923         error!("set_periodic_advertising_data is not supported in software rotation stack");
1924     }
1925 
set_periodic_advertising_enable(&mut self, _adv_id: i32, _enable: bool, _include_adi: bool)1926     fn set_periodic_advertising_enable(&mut self, _adv_id: i32, _enable: bool, _include_adi: bool) {
1927         error!("set_periodic_advertising_enable is not supported in software rotation stack");
1928     }
1929 }
1930 
1931 impl BtifGattAdvCallbacks for SoftwareRotationAdvertiseManagerImpl {
on_advertising_set_started( &mut self, reg_id: i32, adv_id: u8, tx_power: i8, status: AdvertisingStatus, )1932     fn on_advertising_set_started(
1933         &mut self,
1934         reg_id: i32,
1935         adv_id: u8,
1936         tx_power: i8,
1937         status: AdvertisingStatus,
1938     ) {
1939         debug!(
1940             "on_advertising_set_started(): reg_id = {}, advertiser_id = {}, tx_power = {}, status = {:?}",
1941             reg_id, adv_id, tx_power, status
1942         );
1943 
1944         // Unregister if it's unexpected.
1945         match &self.state {
1946             SoftwareRotationAdvertiseState::Pending(pending_id) if pending_id == &reg_id => {}
1947             _ => {
1948                 error!(
1949                     "Unexpected on_advertising_set_started reg_id = {}, adv_id = {}, status = {:?}",
1950                     reg_id, adv_id, status
1951                 );
1952                 if status == AdvertisingStatus::Success {
1953                     self.gatt.lock().unwrap().advertiser.unregister(adv_id);
1954                 }
1955                 return;
1956             }
1957         }
1958         // Switch out from the pending state.
1959         self.state = if status != AdvertisingStatus::Success {
1960             warn!("on_advertising_set_started failed: reg_id = {}, status = {:?}", reg_id, status);
1961             SoftwareRotationAdvertiseState::Stopped
1962         } else {
1963             let txl = self.tx.clone();
1964             SoftwareRotationAdvertiseState::Advertising(
1965                 reg_id,
1966                 adv_id,
1967                 tokio::spawn(async move {
1968                     loop {
1969                         time::sleep(SOFTWARE_ROTATION_INTERVAL).await;
1970                         let _ = txl
1971                             .send(Message::AdvertiserActions(AdvertiserActions::RunRotate))
1972                             .await;
1973                     }
1974                 }),
1975             )
1976         };
1977 
1978         // 1. Handle on_advertising_set_started callback if it's the first time it started
1979         // 2. Stop advertising if it's removed or disabled
1980         // 3. Disable or remove the advertiser if it failed
1981         if let Some(info) = self.adv_info.get_mut(&reg_id) {
1982             if info.tx_power.is_none() {
1983                 // tx_power is none means it's the first time this advertiser started.
1984                 if status != AdvertisingStatus::Success {
1985                     self.callbacks.get_by_id_mut(info.callback_id).map(|cb| {
1986                         cb.on_advertising_set_started(info.id, INVALID_ADV_ID, 0, status);
1987                     });
1988                     self.adv_info.remove(&reg_id);
1989                 } else {
1990                     info.tx_power = Some(tx_power.into());
1991                     info.expire_time = gen_expire_time_from_now(info.duration);
1992                     self.callbacks.get_by_id_mut(info.callback_id).map(|cb| {
1993                         cb.on_advertising_set_started(info.id, info.id, tx_power.into(), status);
1994                     });
1995                 }
1996             } else {
1997                 // Not the first time. This means we are not able to report the failure through
1998                 // on_advertising_set_started if it failed. Disable it instead in that case.
1999                 if status != AdvertisingStatus::Success {
2000                     info.enabled = false;
2001                     // Push to the queue and let refresh_queue handle the disabled callback.
2002                     self.adv_queue.push_back(reg_id);
2003                 } else {
2004                     if !info.enabled {
2005                         self.stop_current_advertising();
2006                     }
2007                 }
2008             }
2009         } else {
2010             self.stop_current_advertising();
2011         }
2012 
2013         // Rotate again if the next advertiser is new. We need to consume all
2014         // "first time" advertiser before suspended to make sure callbacks are sent.
2015         if let Some(id) = self.adv_queue.front() {
2016             if let Some(info) = self.adv_info.get(id) {
2017                 if info.tx_power.is_none() {
2018                     self.run_rotate();
2019                     return;
2020                 }
2021             }
2022         }
2023 
2024         // We're fine to suspend since there is no advertiser pending callback.
2025         if self.suspend_mode != SuspendMode::Normal {
2026             self.stop_current_advertising();
2027             self.set_suspend_mode(SuspendMode::Suspended);
2028             return;
2029         }
2030 
2031         // If the current advertiser is stopped for some reason, schedule the next one.
2032         if self.is_stopped() {
2033             self.refresh_queue();
2034             self.start_next_advertising();
2035         }
2036     }
2037 
on_advertising_enabled(&mut self, _adv_id: u8, _enabled: bool, _status: AdvertisingStatus)2038     fn on_advertising_enabled(&mut self, _adv_id: u8, _enabled: bool, _status: AdvertisingStatus) {
2039         error!("Unexpected on_advertising_enabled in software rotation stack");
2040     }
2041 
on_advertising_data_set(&mut self, _adv_id: u8, _status: AdvertisingStatus)2042     fn on_advertising_data_set(&mut self, _adv_id: u8, _status: AdvertisingStatus) {
2043         error!("Unexpected on_advertising_data_set in software rotation stack");
2044     }
2045 
on_scan_response_data_set(&mut self, _adv_id: u8, _status: AdvertisingStatus)2046     fn on_scan_response_data_set(&mut self, _adv_id: u8, _status: AdvertisingStatus) {
2047         error!("Unexpected on_scan_response_data_set in software rotation stack");
2048     }
2049 
on_advertising_parameters_updated( &mut self, _adv_id: u8, _tx_power: i8, _status: AdvertisingStatus, )2050     fn on_advertising_parameters_updated(
2051         &mut self,
2052         _adv_id: u8,
2053         _tx_power: i8,
2054         _status: AdvertisingStatus,
2055     ) {
2056         error!("Unexpected on_advertising_parameters_updated in software rotation stack");
2057     }
2058 
on_periodic_advertising_parameters_updated( &mut self, _adv_id: u8, _status: AdvertisingStatus, )2059     fn on_periodic_advertising_parameters_updated(
2060         &mut self,
2061         _adv_id: u8,
2062         _status: AdvertisingStatus,
2063     ) {
2064         error!("Unexpected on_periodic_advertising_parameters_updated in software rotation stack");
2065     }
2066 
on_periodic_advertising_data_set(&mut self, _adv_id: u8, _status: AdvertisingStatus)2067     fn on_periodic_advertising_data_set(&mut self, _adv_id: u8, _status: AdvertisingStatus) {
2068         error!("Unexpected on_periodic_advertising_data_set in software rotation stack");
2069     }
2070 
on_periodic_advertising_enabled( &mut self, _adv_id: u8, _enabled: bool, _status: AdvertisingStatus, )2071     fn on_periodic_advertising_enabled(
2072         &mut self,
2073         _adv_id: u8,
2074         _enabled: bool,
2075         _status: AdvertisingStatus,
2076     ) {
2077         error!("Unexpected on_periodic_advertising_enabled in software rotation stack");
2078     }
2079 
on_own_address_read(&mut self, _adv_id: u8, _addr_type: u8, _address: RawAddress)2080     fn on_own_address_read(&mut self, _adv_id: u8, _addr_type: u8, _address: RawAddress) {
2081         error!("Unexpected on_own_address_read in software rotation stack");
2082     }
2083 }
2084 
2085 #[cfg(test)]
2086 mod tests {
2087     use super::*;
2088     use std::iter::FromIterator;
2089 
2090     #[test]
test_append_ad_data_clamped()2091     fn test_append_ad_data_clamped() {
2092         let mut bytes = Vec::<u8>::new();
2093         let mut ans = Vec::<u8>::new();
2094         ans.push(255);
2095         ans.push(102);
2096         ans.extend(Vec::<u8>::from_iter(0..254));
2097 
2098         let payload = Vec::<u8>::from_iter(0..255);
2099         AdvertiseData::append_adv_data(&mut bytes, 102, &payload);
2100         assert_eq!(bytes, ans);
2101     }
2102 
2103     #[test]
test_append_ad_data_multiple()2104     fn test_append_ad_data_multiple() {
2105         let mut bytes = Vec::<u8>::new();
2106 
2107         let payload = vec![0 as u8, 1, 2, 3, 4];
2108         AdvertiseData::append_adv_data(&mut bytes, 100, &payload);
2109         AdvertiseData::append_adv_data(&mut bytes, 101, &[0]);
2110         assert_eq!(bytes, vec![6 as u8, 100, 0, 1, 2, 3, 4, 2, 101, 0]);
2111     }
2112 
2113     #[test]
test_append_service_uuids()2114     fn test_append_service_uuids() {
2115         let mut bytes = Vec::<u8>::new();
2116         let uuid_16 = Uuid::from_string("0000fef3-0000-1000-8000-00805f9b34fb").unwrap();
2117         let uuids = vec![uuid_16.clone()];
2118         let exp_16: Vec<u8> = vec![3, 0x3, 0xf3, 0xfe];
2119         AdvertiseData::append_service_uuids(&mut bytes, &uuids);
2120         assert_eq!(bytes, exp_16);
2121 
2122         let mut bytes = Vec::<u8>::new();
2123         let uuid_32 = Uuid::from_string("00112233-0000-1000-8000-00805f9b34fb").unwrap();
2124         let uuids = vec![uuid_32.clone()];
2125         let exp_32: Vec<u8> = vec![5, 0x5, 0x33, 0x22, 0x11, 0x0];
2126         AdvertiseData::append_service_uuids(&mut bytes, &uuids);
2127         assert_eq!(bytes, exp_32);
2128 
2129         let mut bytes = Vec::<u8>::new();
2130         let uuid_128 = Uuid::from_string("00010203-0405-0607-0809-0a0b0c0d0e0f").unwrap();
2131         let uuids = vec![uuid_128.clone()];
2132         let exp_128: Vec<u8> = vec![
2133             17, 0x7, 0xf, 0xe, 0xd, 0xc, 0xb, 0xa, 0x9, 0x8, 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0,
2134         ];
2135         AdvertiseData::append_service_uuids(&mut bytes, &uuids);
2136         assert_eq!(bytes, exp_128);
2137 
2138         let mut bytes = Vec::<u8>::new();
2139         let uuids = vec![uuid_16, uuid_32, uuid_128];
2140         let exp_bytes: Vec<u8> =
2141             [exp_16.as_slice(), exp_32.as_slice(), exp_128.as_slice()].concat();
2142         AdvertiseData::append_service_uuids(&mut bytes, &uuids);
2143         assert_eq!(bytes, exp_bytes);
2144 
2145         // Interleaved UUIDs.
2146         let mut bytes = Vec::<u8>::new();
2147         let uuid_16_2 = Uuid::from_string("0000aabb-0000-1000-8000-00805f9b34fb").unwrap();
2148         let uuids = vec![uuid_16, uuid_128, uuid_16_2, uuid_32];
2149         let exp_16: Vec<u8> = vec![5, 0x3, 0xf3, 0xfe, 0xbb, 0xaa];
2150         let exp_bytes: Vec<u8> =
2151             [exp_16.as_slice(), exp_32.as_slice(), exp_128.as_slice()].concat();
2152         AdvertiseData::append_service_uuids(&mut bytes, &uuids);
2153         assert_eq!(bytes, exp_bytes);
2154     }
2155 
2156     #[test]
test_append_solicit_uuids()2157     fn test_append_solicit_uuids() {
2158         let mut bytes = Vec::<u8>::new();
2159         let uuid_16 = Uuid::from_string("0000fef3-0000-1000-8000-00805f9b34fb").unwrap();
2160         let uuid_32 = Uuid::from_string("00112233-0000-1000-8000-00805f9b34fb").unwrap();
2161         let uuid_128 = Uuid::from_string("00010203-0405-0607-0809-0a0b0c0d0e0f").unwrap();
2162         let uuids = vec![uuid_16, uuid_32, uuid_128];
2163         let exp_16: Vec<u8> = vec![3, 0x14, 0xf3, 0xfe];
2164         let exp_32: Vec<u8> = vec![5, 0x1f, 0x33, 0x22, 0x11, 0x0];
2165         let exp_128: Vec<u8> = vec![
2166             17, 0x15, 0xf, 0xe, 0xd, 0xc, 0xb, 0xa, 0x9, 0x8, 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1,
2167             0x0,
2168         ];
2169         let exp_bytes: Vec<u8> =
2170             [exp_16.as_slice(), exp_32.as_slice(), exp_128.as_slice()].concat();
2171         AdvertiseData::append_solicit_uuids(&mut bytes, &uuids);
2172         assert_eq!(bytes, exp_bytes);
2173     }
2174 
2175     #[test]
test_append_service_data_good_id()2176     fn test_append_service_data_good_id() {
2177         let mut bytes = Vec::<u8>::new();
2178         let uuid_str = "0000fef3-0000-1000-8000-00805f9b34fb".to_string();
2179         let mut service_data = HashMap::new();
2180         let data: Vec<u8> = vec![
2181             0x4A, 0x17, 0x23, 0x41, 0x39, 0x37, 0x45, 0x11, 0x16, 0x60, 0x1D, 0xB8, 0x27, 0xA2,
2182             0xEF, 0xAA, 0xFE, 0x58, 0x04, 0x9F, 0xE3, 0x8F, 0xD0, 0x04, 0x29, 0x4F, 0xC2,
2183         ];
2184         service_data.insert(uuid_str, data.clone());
2185         let mut exp_bytes: Vec<u8> = vec![30, 0x16, 0xf3, 0xfe];
2186         exp_bytes.extend(data);
2187         AdvertiseData::append_service_data(&mut bytes, &service_data);
2188         assert_eq!(bytes, exp_bytes);
2189     }
2190 
2191     #[test]
test_append_service_data_bad_id()2192     fn test_append_service_data_bad_id() {
2193         let mut bytes = Vec::<u8>::new();
2194         let uuid_str = "fef3".to_string();
2195         let mut service_data = HashMap::new();
2196         let data: Vec<u8> = vec![
2197             0x4A, 0x17, 0x23, 0x41, 0x39, 0x37, 0x45, 0x11, 0x16, 0x60, 0x1D, 0xB8, 0x27, 0xA2,
2198             0xEF, 0xAA, 0xFE, 0x58, 0x04, 0x9F, 0xE3, 0x8F, 0xD0, 0x04, 0x29, 0x4F, 0xC2,
2199         ];
2200         service_data.insert(uuid_str, data.clone());
2201         let exp_bytes: Vec<u8> = Vec::new();
2202         AdvertiseData::append_service_data(&mut bytes, &service_data);
2203         assert_eq!(bytes, exp_bytes);
2204     }
2205 
2206     #[test]
test_append_device_name()2207     fn test_append_device_name() {
2208         let mut bytes = Vec::<u8>::new();
2209         let complete_name = "abc".to_string();
2210         let exp_bytes: Vec<u8> = vec![5, 0x9, 0x61, 0x62, 0x63, 0x0];
2211         AdvertiseData::append_device_name(&mut bytes, &complete_name);
2212         assert_eq!(bytes, exp_bytes);
2213 
2214         let mut bytes = Vec::<u8>::new();
2215         let shortened_name = "abcdefghijklmnopqrstuvwxyz7890".to_string();
2216         let exp_bytes: Vec<u8> = vec![
2217             28, 0x8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d,
2218             0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x0,
2219         ];
2220         AdvertiseData::append_device_name(&mut bytes, &shortened_name);
2221         assert_eq!(bytes, exp_bytes);
2222     }
2223 
2224     #[test]
test_append_manufacturer_data()2225     fn test_append_manufacturer_data() {
2226         let mut bytes = Vec::<u8>::new();
2227         let manufacturer_data = HashMap::from([(0x0123 as u16, vec![0, 1, 2])]);
2228         let exp_bytes: Vec<u8> = vec![6, 0xff, 0x23, 0x01, 0x0, 0x1, 0x2];
2229         AdvertiseData::append_manufacturer_data(&mut bytes, &manufacturer_data);
2230         assert_eq!(bytes, exp_bytes);
2231     }
2232 
2233     #[test]
test_append_transport_discovery_data()2234     fn test_append_transport_discovery_data() {
2235         let mut bytes = Vec::<u8>::new();
2236         let transport_discovery_data = vec![vec![0, 1, 2]];
2237         let exp_bytes: Vec<u8> = vec![0x4, 0x26, 0x0, 0x1, 0x2];
2238         AdvertiseData::append_transport_discovery_data(&mut bytes, &transport_discovery_data);
2239         assert_eq!(bytes, exp_bytes);
2240 
2241         let mut bytes = Vec::<u8>::new();
2242         let transport_discovery_data = vec![vec![1, 2, 4, 8], vec![0xa, 0xb]];
2243         let exp_bytes: Vec<u8> = vec![0x5, 0x26, 0x1, 0x2, 0x4, 0x8, 3, 0x26, 0xa, 0xb];
2244         AdvertiseData::append_transport_discovery_data(&mut bytes, &transport_discovery_data);
2245         assert_eq!(bytes, exp_bytes);
2246     }
2247 }
2248