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 From<AdvertisingSetParameters> for bt_topshim::profiles::gatt::AdvertiseParameters {
from(val: AdvertisingSetParameters) -> Self214     fn from(val: AdvertisingSetParameters) -> Self {
215         let mut props: u16 = 0;
216         let mut is_discoverable = false;
217         let mut address = RawAddress::default();
218         if val.connectable {
219             props |= 0x01;
220         }
221         if val.scannable {
222             props |= 0x02;
223         }
224         if val.is_legacy {
225             props |= 0x10;
226         }
227         if val.is_anonymous {
228             props |= 0x20;
229         }
230         if val.include_tx_power {
231             props |= 0x40;
232         }
233 
234         match val.discoverable {
235             LeDiscMode::GeneralDiscoverable => is_discoverable = true,
236             _ => {}
237         }
238 
239         let interval = clamp(val.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_u8, // all channels
246             tx_power: val.tx_power_level as i8,
247             primary_advertising_phy: val.primary_phy.into(),
248             secondary_advertising_phy: val.secondary_phy.into(),
249             scan_request_notification_enable: 0_u8, // false
250             own_address_type: val.own_address_type as i8,
251             peer_address: address,
252             peer_address_type: 0x00 as i8,
253             discoverable: is_discoverable,
254         }
255     }
256 }
257 
258 impl AdvertiseData {
append_adv_data(dest: &mut Vec<u8>, ad_type: u8, ad_payload: &[u8])259     fn append_adv_data(dest: &mut Vec<u8>, ad_type: u8, ad_payload: &[u8]) {
260         let len = clamp(ad_payload.len(), 0, 254);
261         dest.push((len + 1) as u8);
262         dest.push(ad_type);
263         dest.extend(&ad_payload[..len]);
264     }
265 
append_uuids(dest: &mut Vec<u8>, ad_types: &[u8; 3], uuids: &Vec<Uuid>)266     fn append_uuids(dest: &mut Vec<u8>, ad_types: &[u8; 3], uuids: &Vec<Uuid>) {
267         let mut uuid16_bytes = Vec::<u8>::new();
268         let mut uuid32_bytes = Vec::<u8>::new();
269         let mut uuid128_bytes = Vec::<u8>::new();
270 
271         // For better transmission efficiency, we generate a compact
272         // advertisement data by converting UUIDs into shorter binary forms
273         // and then group them by their length in order.
274         // The data generated for UUIDs looks like:
275         // [16-bit_UUID_LIST, 32-bit_UUID_LIST, 128-bit_UUID_LIST].
276         for uuid in uuids {
277             let uuid_slice = uuid.get_shortest_slice();
278             let id: Vec<u8> = uuid_slice.iter().rev().cloned().collect();
279             match id.len() {
280                 2 => uuid16_bytes.extend(id),
281                 4 => uuid32_bytes.extend(id),
282                 16 => uuid128_bytes.extend(id),
283                 _ => (),
284             }
285         }
286 
287         let bytes_list = [uuid16_bytes, uuid32_bytes, uuid128_bytes];
288         for (ad_type, bytes) in
289             ad_types.iter().zip(bytes_list.iter()).filter(|(_, bytes)| !bytes.is_empty())
290         {
291             AdvertiseData::append_adv_data(dest, *ad_type, bytes);
292         }
293     }
294 
append_service_uuids(dest: &mut Vec<u8>, uuids: &Vec<Uuid>)295     fn append_service_uuids(dest: &mut Vec<u8>, uuids: &Vec<Uuid>) {
296         AdvertiseData::append_uuids(dest, &SERVICE_AD_TYPES, uuids);
297     }
298 
append_solicit_uuids(dest: &mut Vec<u8>, uuids: &Vec<Uuid>)299     fn append_solicit_uuids(dest: &mut Vec<u8>, uuids: &Vec<Uuid>) {
300         AdvertiseData::append_uuids(dest, &SOLICIT_AD_TYPES, uuids);
301     }
302 
append_service_data(dest: &mut Vec<u8>, service_data: &HashMap<String, Vec<u8>>)303     fn append_service_data(dest: &mut Vec<u8>, service_data: &HashMap<String, Vec<u8>>) {
304         for (uuid, data) in
305             service_data.iter().filter_map(|(s, d)| Uuid::from_string(s).map(|s| (s, d)))
306         {
307             let uuid_slice = uuid.get_shortest_slice();
308             let concated: Vec<u8> = uuid_slice.iter().rev().chain(data).cloned().collect();
309             match uuid_slice.len() {
310                 2 => AdvertiseData::append_adv_data(dest, SERVICE_DATA_16_BIT_UUID, &concated),
311                 4 => AdvertiseData::append_adv_data(dest, SERVICE_DATA_32_BIT_UUID, &concated),
312                 16 => AdvertiseData::append_adv_data(dest, SERVICE_DATA_128_BIT_UUID, &concated),
313                 _ => (),
314             }
315         }
316     }
317 
append_device_name(dest: &mut Vec<u8>, device_name: &String)318     fn append_device_name(dest: &mut Vec<u8>, device_name: &String) {
319         if device_name.is_empty() {
320             return;
321         }
322 
323         let (ad_type, name) = if device_name.len() > DEVICE_NAME_MAX {
324             (SHORTENED_LOCAL_NAME, [&device_name.as_bytes()[..DEVICE_NAME_MAX], &[0]].concat())
325         } else {
326             (COMPLETE_LOCAL_NAME, [device_name.as_bytes(), &[0]].concat())
327         };
328         AdvertiseData::append_adv_data(dest, ad_type, &name);
329     }
330 
append_manufacturer_data(dest: &mut Vec<u8>, manufacturer_data: &HashMap<ManfId, Vec<u8>>)331     fn append_manufacturer_data(dest: &mut Vec<u8>, manufacturer_data: &HashMap<ManfId, Vec<u8>>) {
332         for (m, data) in manufacturer_data.iter().sorted() {
333             let concated = [&m.to_le_bytes()[..], data].concat();
334             AdvertiseData::append_adv_data(dest, MANUFACTURER_SPECIFIC_DATA, &concated);
335         }
336     }
337 
append_transport_discovery_data( dest: &mut Vec<u8>, transport_discovery_data: &Vec<Vec<u8>>, )338     fn append_transport_discovery_data(
339         dest: &mut Vec<u8>,
340         transport_discovery_data: &Vec<Vec<u8>>,
341     ) {
342         for tdd in transport_discovery_data.iter().filter(|tdd| !tdd.is_empty()) {
343             AdvertiseData::append_adv_data(dest, TRANSPORT_DISCOVERY_DATA, tdd);
344         }
345     }
346 
347     /// Creates raw data from the AdvertiseData.
make_with(&self, device_name: &String) -> Vec<u8>348     pub fn make_with(&self, device_name: &String) -> Vec<u8> {
349         let mut bytes = Vec::<u8>::new();
350         if self.include_device_name {
351             AdvertiseData::append_device_name(&mut bytes, device_name);
352         }
353         if self.include_tx_power_level {
354             // Lower layers will fill tx power level.
355             AdvertiseData::append_adv_data(&mut bytes, TX_POWER_LEVEL, &[0]);
356         }
357         AdvertiseData::append_manufacturer_data(&mut bytes, &self.manufacturer_data);
358         AdvertiseData::append_service_uuids(&mut bytes, &self.service_uuids);
359         AdvertiseData::append_service_data(&mut bytes, &self.service_data);
360         AdvertiseData::append_solicit_uuids(&mut bytes, &self.solicit_uuids);
361         AdvertiseData::append_transport_discovery_data(&mut bytes, &self.transport_discovery_data);
362         bytes
363     }
364 
365     /// Validates the raw data as advertisement data.
validate_raw_data(is_legacy: bool, bytes: &Vec<u8>) -> bool366     pub fn validate_raw_data(is_legacy: bool, bytes: &Vec<u8>) -> bool {
367         bytes.len() <= if is_legacy { LEGACY_ADV_DATA_LEN_MAX } else { EXT_ADV_DATA_LEN_MAX }
368     }
369 
370     /// Checks if the advertisement can be upgraded to extended.
can_upgrade(parameters: &mut AdvertisingSetParameters, adv_bytes: &Vec<u8>) -> bool371     pub fn can_upgrade(parameters: &mut AdvertisingSetParameters, adv_bytes: &Vec<u8>) -> bool {
372         if parameters.is_legacy && !AdvertiseData::validate_raw_data(true, adv_bytes) {
373             info!("Auto upgrading advertisement to extended");
374             parameters.is_legacy = false;
375             return true;
376         }
377 
378         false
379     }
380 }
381 
382 impl From<PeriodicAdvertisingParameters>
383     for bt_topshim::profiles::gatt::PeriodicAdvertisingParameters
384 {
from(val: PeriodicAdvertisingParameters) -> Self385     fn from(val: PeriodicAdvertisingParameters) -> Self {
386         let mut p = bt_topshim::profiles::gatt::PeriodicAdvertisingParameters::default();
387 
388         let interval = clamp(
389             val.interval,
390             PERIODIC_INTERVAL_MIN,
391             PERIODIC_INTERVAL_MAX - PERIODIC_INTERVAL_DELTA,
392         );
393 
394         p.enable = true;
395         p.include_adi = false;
396         p.min_interval = interval as u16;
397         p.max_interval = p.min_interval + (PERIODIC_INTERVAL_DELTA as u16);
398         if val.include_tx_power {
399             p.periodic_advertising_properties |= 0x40;
400         }
401 
402         p
403     }
404 }
405 
406 // Keeps information of an advertising set.
407 #[derive(Debug, PartialEq, Copy, Clone)]
408 struct AdvertisingSetInfo {
409     /// Identifies the advertising set when it's started successfully.
410     adv_id: Option<AdvertiserId>,
411 
412     /// Identifies callback associated.
413     callback_id: CallbackId,
414 
415     /// Identifies the advertising set when it's registered.
416     reg_id: RegId,
417 
418     /// Whether the advertising set has been enabled.
419     enabled: bool,
420 
421     /// Whether the advertising set has been paused.
422     paused: bool,
423 
424     /// Whether the stop of advertising set is held.
425     /// This flag is set when an advertising set is stopped while we're not able to do it, such as:
426     /// - The system is suspending / suspended
427     /// - The advertising set is not yet valid (started)
428     ///
429     /// The advertising set will be stopped on system resumed / advertising set becomes ready.
430     stopped: bool,
431 
432     /// Advertising duration, in 10 ms unit.
433     adv_timeout: u16,
434 
435     /// Maximum number of extended advertising events the controller
436     /// shall attempt to send before terminating the extended advertising.
437     adv_events: u8,
438 
439     /// Whether the legacy advertisement will be used.
440     legacy: bool,
441 }
442 
443 impl AdvertisingSetInfo {
new( callback_id: CallbackId, adv_timeout: u16, adv_events: u8, legacy: bool, reg_id: RegId, ) -> Self444     fn new(
445         callback_id: CallbackId,
446         adv_timeout: u16,
447         adv_events: u8,
448         legacy: bool,
449         reg_id: RegId,
450     ) -> Self {
451         AdvertisingSetInfo {
452             adv_id: None,
453             callback_id,
454             reg_id,
455             enabled: false,
456             paused: false,
457             stopped: false,
458             adv_timeout,
459             adv_events,
460             legacy,
461         }
462     }
463 
464     /// Gets advertising set registration ID.
reg_id(&self) -> RegId465     fn reg_id(&self) -> RegId {
466         self.reg_id
467     }
468 
469     /// Gets associated callback ID.
callback_id(&self) -> CallbackId470     fn callback_id(&self) -> CallbackId {
471         self.callback_id
472     }
473 
474     /// Updates advertiser ID.
set_adv_id(&mut self, id: Option<AdvertiserId>)475     fn set_adv_id(&mut self, id: Option<AdvertiserId>) {
476         self.adv_id = id;
477     }
478 
479     /// Gets advertiser ID, which is required for advertising |BleAdvertiserInterface|.
adv_id(&self) -> u8480     fn adv_id(&self) -> u8 {
481         // As advertiser ID was from topshim originally, type casting is safe.
482         self.adv_id.unwrap_or(INVALID_ADV_ID) as u8
483     }
484 
485     /// Updates advertising set status.
set_enabled(&mut self, enabled: bool)486     fn set_enabled(&mut self, enabled: bool) {
487         self.enabled = enabled;
488     }
489 
490     /// Returns true if the advertising set has been enabled, false otherwise.
is_enabled(&self) -> bool491     fn is_enabled(&self) -> bool {
492         self.enabled
493     }
494 
495     /// Marks the advertising set as paused or not.
set_paused(&mut self, paused: bool)496     fn set_paused(&mut self, paused: bool) {
497         self.paused = paused;
498     }
499 
500     /// Returns true if the advertising set has been paused, false otherwise.
is_paused(&self) -> bool501     fn is_paused(&self) -> bool {
502         self.paused
503     }
504 
505     /// Marks the advertising set as stopped.
set_stopped(&mut self)506     fn set_stopped(&mut self) {
507         self.stopped = true;
508     }
509 
510     /// Returns true if the advertising set has been stopped, false otherwise.
is_stopped(&self) -> bool511     fn is_stopped(&self) -> bool {
512         self.stopped
513     }
514 
515     /// Gets adv_timeout.
adv_timeout(&self) -> u16516     fn adv_timeout(&self) -> u16 {
517         self.adv_timeout
518     }
519 
520     /// Gets adv_events.
adv_events(&self) -> u8521     fn adv_events(&self) -> u8 {
522         self.adv_events
523     }
524 
525     /// Returns whether the legacy advertisement will be used.
is_legacy(&self) -> bool526     fn is_legacy(&self) -> bool {
527         self.legacy
528     }
529 
530     /// Returns whether the advertising set is valid.
is_valid(&self) -> bool531     fn is_valid(&self) -> bool {
532         self.adv_id.is_some()
533     }
534 }
535 
536 // Manages advertising sets and the callbacks.
537 pub(crate) struct AdvertiseManager {
538     tx: Sender<Message>,
539     adv_manager_impl: Option<Box<dyn AdvertiseManagerOps + Send>>,
540 }
541 
542 impl AdvertiseManager {
new(tx: Sender<Message>) -> Self543     pub(crate) fn new(tx: Sender<Message>) -> Self {
544         AdvertiseManager { tx, adv_manager_impl: None }
545     }
546 
547     /// Initializes the AdvertiseManager
548     /// 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>>>, )549     pub(crate) fn initialize(
550         &mut self,
551         gatt: Arc<Mutex<Gatt>>,
552         adapter: Arc<Mutex<Box<Bluetooth>>>,
553     ) {
554         let is_le_ext_adv_supported =
555             adapter.lock().unwrap().is_le_extended_advertising_supported();
556         self.adv_manager_impl = if is_le_ext_adv_supported {
557             info!("AdvertiseManager: Selected extended advertising stack");
558             Some(Box::new(AdvertiseManagerImpl::new(self.tx.clone(), gatt, adapter)))
559         } else {
560             info!("AdvertiseManager: Selected software rotation stack");
561             Some(Box::new(SoftwareRotationAdvertiseManagerImpl::new(
562                 self.tx.clone(),
563                 gatt,
564                 adapter,
565             )))
566         }
567     }
568 
get_impl(&mut self) -> &mut Box<dyn AdvertiseManagerOps + Send>569     pub fn get_impl(&mut self) -> &mut Box<dyn AdvertiseManagerOps + Send> {
570         self.adv_manager_impl.as_mut().unwrap()
571     }
572 }
573 
574 struct AdvertiseManagerImpl {
575     callbacks: Callbacks<dyn IAdvertisingSetCallback + Send>,
576     sets: HashMap<RegId, AdvertisingSetInfo>,
577     suspend_mode: SuspendMode,
578     gatt: Arc<Mutex<Gatt>>,
579     adapter: Arc<Mutex<Box<Bluetooth>>>,
580 }
581 
582 impl AdvertiseManagerImpl {
new( tx: Sender<Message>, gatt: Arc<Mutex<Gatt>>, adapter: Arc<Mutex<Box<Bluetooth>>>, ) -> Self583     fn new(
584         tx: Sender<Message>,
585         gatt: Arc<Mutex<Gatt>>,
586         adapter: Arc<Mutex<Box<Bluetooth>>>,
587     ) -> Self {
588         AdvertiseManagerImpl {
589             callbacks: Callbacks::new(tx, Message::AdvertiserCallbackDisconnected),
590             sets: HashMap::new(),
591             suspend_mode: SuspendMode::Normal,
592             gatt,
593             adapter,
594         }
595     }
596 
597     // Returns the minimum unoccupied register ID from 0.
new_reg_id(&mut self) -> RegId598     fn new_reg_id(&mut self) -> RegId {
599         (0..)
600             .find(|id| !self.sets.contains_key(id))
601             .expect("There must be an unoccupied register ID")
602     }
603 
604     /// Adds an advertising set.
add(&mut self, s: AdvertisingSetInfo)605     fn add(&mut self, s: AdvertisingSetInfo) {
606         if let Some(old) = self.sets.insert(s.reg_id(), s) {
607             warn!("An advertising set with the same reg_id ({}) exists. Drop it!", old.reg_id);
608         }
609     }
610 
611     /// Returns an iterator of valid advertising sets.
valid_sets(&self) -> impl Iterator<Item = &AdvertisingSetInfo>612     fn valid_sets(&self) -> impl Iterator<Item = &AdvertisingSetInfo> {
613         self.sets.iter().filter_map(|(_, s)| s.adv_id.map(|_| s))
614     }
615 
616     /// Returns an iterator of enabled advertising sets.
enabled_sets(&self) -> impl Iterator<Item = &AdvertisingSetInfo>617     fn enabled_sets(&self) -> impl Iterator<Item = &AdvertisingSetInfo> {
618         self.valid_sets().filter(|s| s.is_enabled())
619     }
620 
621     /// Returns an iterator of stopped advertising sets.
stopped_sets(&self) -> impl Iterator<Item = &AdvertisingSetInfo>622     fn stopped_sets(&self) -> impl Iterator<Item = &AdvertisingSetInfo> {
623         self.valid_sets().filter(|s| s.is_stopped())
624     }
625 
find_reg_id(&self, adv_id: AdvertiserId) -> Option<RegId>626     fn find_reg_id(&self, adv_id: AdvertiserId) -> Option<RegId> {
627         for (_, s) in &self.sets {
628             if s.adv_id == Some(adv_id) {
629                 return Some(s.reg_id());
630             }
631         }
632         None
633     }
634 
635     /// 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>636     fn get_mut_by_reg_id(&mut self, reg_id: RegId) -> Option<&mut AdvertisingSetInfo> {
637         self.sets.get_mut(&reg_id)
638     }
639 
640     /// Returns a shared reference to the advertising set with the reg_id specified.
get_by_reg_id(&self, reg_id: RegId) -> Option<&AdvertisingSetInfo>641     fn get_by_reg_id(&self, reg_id: RegId) -> Option<&AdvertisingSetInfo> {
642         self.sets.get(&reg_id)
643     }
644 
645     /// 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>646     fn get_mut_by_advertiser_id(
647         &mut self,
648         adv_id: AdvertiserId,
649     ) -> Option<&mut AdvertisingSetInfo> {
650         if let Some(reg_id) = self.find_reg_id(adv_id) {
651             return self.get_mut_by_reg_id(reg_id);
652         }
653         None
654     }
655 
656     /// Returns a shared reference to the advertising set with the advertiser ID specified.
get_by_advertiser_id(&self, adv_id: AdvertiserId) -> Option<&AdvertisingSetInfo>657     fn get_by_advertiser_id(&self, adv_id: AdvertiserId) -> Option<&AdvertisingSetInfo> {
658         if let Some(reg_id) = self.find_reg_id(adv_id) {
659             return self.get_by_reg_id(reg_id);
660         }
661         None
662     }
663 
664     /// Removes the advertising set with the reg_id specified.
665     ///
666     /// Returns the advertising set if found, None otherwise.
remove_by_reg_id(&mut self, reg_id: RegId) -> Option<AdvertisingSetInfo>667     fn remove_by_reg_id(&mut self, reg_id: RegId) -> Option<AdvertisingSetInfo> {
668         self.sets.remove(&reg_id)
669     }
670 
671     /// Removes the advertising set with the specified advertiser ID.
672     ///
673     /// Returns the advertising set if found, None otherwise.
remove_by_advertiser_id(&mut self, adv_id: AdvertiserId) -> Option<AdvertisingSetInfo>674     fn remove_by_advertiser_id(&mut self, adv_id: AdvertiserId) -> Option<AdvertisingSetInfo> {
675         if let Some(reg_id) = self.find_reg_id(adv_id) {
676             return self.remove_by_reg_id(reg_id);
677         }
678         None
679     }
680 
681     /// Returns callback of the advertising set.
get_callback( &mut self, s: &AdvertisingSetInfo, ) -> Option<&mut Box<dyn IAdvertisingSetCallback + Send>>682     fn get_callback(
683         &mut self,
684         s: &AdvertisingSetInfo,
685     ) -> Option<&mut Box<dyn IAdvertisingSetCallback + Send>> {
686         self.callbacks.get_by_id_mut(s.callback_id())
687     }
688 
689     /// Update suspend mode.
set_suspend_mode(&mut self, suspend_mode: SuspendMode)690     fn set_suspend_mode(&mut self, suspend_mode: SuspendMode) {
691         if suspend_mode != self.suspend_mode {
692             self.suspend_mode = suspend_mode;
693             self.notify_suspend_mode();
694         }
695     }
696 
697     /// Gets current suspend mode.
suspend_mode(&mut self) -> SuspendMode698     fn suspend_mode(&mut self) -> SuspendMode {
699         self.suspend_mode.clone()
700     }
701 
702     /// Notify current suspend mode to all active callbacks.
notify_suspend_mode(&mut self)703     fn notify_suspend_mode(&mut self) {
704         let suspend_mode = &self.suspend_mode;
705         self.callbacks.for_all_callbacks(|callback| {
706             callback.on_suspend_mode_change(suspend_mode.clone());
707         });
708     }
709 
get_adapter_name(&self) -> String710     fn get_adapter_name(&self) -> String {
711         self.adapter.lock().unwrap().get_name()
712     }
713 }
714 
715 pub enum AdvertiserActions {
716     /// Triggers the rotation of the advertising set.
717     /// Should only be used in the software rotation stack.
718     RunRotate,
719 }
720 
721 /// Defines all required ops for an AdvertiseManager to communicate with the upper/lower layers.
722 pub(crate) trait AdvertiseManagerOps:
723     IBluetoothAdvertiseManager + BtifGattAdvCallbacks
724 {
725     /// Prepares for suspend
enter_suspend(&mut self)726     fn enter_suspend(&mut self);
727 
728     /// Undoes previous suspend preparation
exit_suspend(&mut self)729     fn exit_suspend(&mut self);
730 
731     /// Handles advertise manager actions
handle_action(&mut self, action: AdvertiserActions)732     fn handle_action(&mut self, action: AdvertiserActions);
733 }
734 
735 impl AdvertiseManagerOps for AdvertiseManagerImpl {
enter_suspend(&mut self)736     fn enter_suspend(&mut self) {
737         if self.suspend_mode() != SuspendMode::Normal {
738             return;
739         }
740         self.set_suspend_mode(SuspendMode::Suspending);
741 
742         let mut pausing_cnt = 0;
743         for s in self.sets.values_mut().filter(|s| s.is_valid() && s.is_enabled()) {
744             s.set_paused(true);
745             self.gatt.lock().unwrap().advertiser.enable(
746                 s.adv_id(),
747                 false,
748                 s.adv_timeout(),
749                 s.adv_events(),
750             );
751             pausing_cnt += 1;
752         }
753 
754         if pausing_cnt == 0 {
755             self.set_suspend_mode(SuspendMode::Suspended);
756         }
757     }
758 
exit_suspend(&mut self)759     fn exit_suspend(&mut self) {
760         if self.suspend_mode() != SuspendMode::Suspended {
761             return;
762         }
763         for id in self.stopped_sets().map(|s| s.adv_id()).collect::<Vec<_>>() {
764             self.gatt.lock().unwrap().advertiser.unregister(id);
765             self.remove_by_advertiser_id(id as AdvertiserId);
766         }
767         for s in self.sets.values_mut().filter(|s| s.is_valid() && s.is_paused()) {
768             s.set_paused(false);
769             self.gatt.lock().unwrap().advertiser.enable(
770                 s.adv_id(),
771                 true,
772                 s.adv_timeout(),
773                 s.adv_events(),
774             );
775         }
776 
777         self.set_suspend_mode(SuspendMode::Normal);
778     }
779 
handle_action(&mut self, action: AdvertiserActions)780     fn handle_action(&mut self, action: AdvertiserActions) {
781         match action {
782             AdvertiserActions::RunRotate => {
783                 error!("Unexpected RunRotate call in hardware offloaded stack");
784             }
785         }
786     }
787 }
788 
789 pub trait IBluetoothAdvertiseManager {
790     /// Registers callback for BLE advertising.
register_callback(&mut self, callback: Box<dyn IAdvertisingSetCallback + Send>) -> u32791     fn register_callback(&mut self, callback: Box<dyn IAdvertisingSetCallback + Send>) -> u32;
792 
793     /// Unregisters callback for BLE advertising.
unregister_callback(&mut self, callback_id: u32) -> bool794     fn unregister_callback(&mut self, callback_id: u32) -> bool;
795 
796     /// Creates a new BLE advertising set and start advertising.
797     ///
798     /// Returns the reg_id for the advertising set, which is used in the callback
799     /// `on_advertising_set_started` to identify the advertising set started.
800     ///
801     /// * `parameters` - Advertising set parameters.
802     /// * `advertise_data` - Advertisement data to be broadcasted.
803     /// * `scan_response` - Scan response.
804     /// * `periodic_parameters` - Periodic advertising parameters. If None, periodic advertising
805     ///     will not be started.
806     /// * `periodic_data` - Periodic advertising data.
807     /// * `duration` - Advertising duration, in 10 ms unit. Valid range is from 1 (10 ms) to
808     ///     65535 (655.35 sec). 0 means no advertising timeout.
809     /// * `max_ext_adv_events` - Maximum number of extended advertising events the controller
810     ///     shall attempt to send before terminating the extended advertising, even if the
811     ///     duration has not expired. Valid range is from 1 to 255. 0 means event count limitation.
812     /// * `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, ) -> i32813     fn start_advertising_set(
814         &mut self,
815         parameters: AdvertisingSetParameters,
816         advertise_data: AdvertiseData,
817         scan_response: Option<AdvertiseData>,
818         periodic_parameters: Option<PeriodicAdvertisingParameters>,
819         periodic_data: Option<AdvertiseData>,
820         duration: i32,
821         max_ext_adv_events: i32,
822         callback_id: u32,
823     ) -> i32;
824 
825     /// Disposes a BLE advertising set.
stop_advertising_set(&mut self, advertiser_id: i32)826     fn stop_advertising_set(&mut self, advertiser_id: i32);
827 
828     /// Queries address associated with the advertising set.
get_own_address(&mut self, advertiser_id: i32)829     fn get_own_address(&mut self, advertiser_id: i32);
830 
831     /// Enables or disables an advertising set.
enable_advertising_set( &mut self, advertiser_id: i32, enable: bool, duration: i32, max_ext_adv_events: i32, )832     fn enable_advertising_set(
833         &mut self,
834         advertiser_id: i32,
835         enable: bool,
836         duration: i32,
837         max_ext_adv_events: i32,
838     );
839 
840     /// Updates advertisement data of the advertising set.
set_advertising_data(&mut self, advertiser_id: i32, data: AdvertiseData)841     fn set_advertising_data(&mut self, advertiser_id: i32, data: AdvertiseData);
842 
843     /// Set the advertisement data of the advertising set.
set_raw_adv_data(&mut self, advertiser_id: i32, data: Vec<u8>)844     fn set_raw_adv_data(&mut self, advertiser_id: i32, data: Vec<u8>);
845 
846     /// Updates scan response of the advertising set.
set_scan_response_data(&mut self, advertiser_id: i32, data: AdvertiseData)847     fn set_scan_response_data(&mut self, advertiser_id: i32, data: AdvertiseData);
848 
849     /// Updates advertising parameters of the advertising set.
850     ///
851     /// It must be called when advertising is not active.
set_advertising_parameters( &mut self, advertiser_id: i32, parameters: AdvertisingSetParameters, )852     fn set_advertising_parameters(
853         &mut self,
854         advertiser_id: i32,
855         parameters: AdvertisingSetParameters,
856     );
857 
858     /// Updates periodic advertising parameters.
set_periodic_advertising_parameters( &mut self, advertiser_id: i32, parameters: PeriodicAdvertisingParameters, )859     fn set_periodic_advertising_parameters(
860         &mut self,
861         advertiser_id: i32,
862         parameters: PeriodicAdvertisingParameters,
863     );
864 
865     /// Updates periodic advertisement data.
866     ///
867     /// It must be called after `set_periodic_advertising_parameters`, or after
868     /// advertising was started with periodic advertising data set.
set_periodic_advertising_data(&mut self, advertiser_id: i32, data: AdvertiseData)869     fn set_periodic_advertising_data(&mut self, advertiser_id: i32, data: AdvertiseData);
870 
871     /// Enables or disables periodic advertising.
set_periodic_advertising_enable( &mut self, advertiser_id: i32, enable: bool, include_adi: bool, )872     fn set_periodic_advertising_enable(
873         &mut self,
874         advertiser_id: i32,
875         enable: bool,
876         include_adi: bool,
877     );
878 }
879 
880 impl IBluetoothAdvertiseManager for AdvertiseManagerImpl {
register_callback(&mut self, callback: Box<dyn IAdvertisingSetCallback + Send>) -> u32881     fn register_callback(&mut self, callback: Box<dyn IAdvertisingSetCallback + Send>) -> u32 {
882         self.callbacks.add_callback(callback)
883     }
884 
unregister_callback(&mut self, callback_id: u32) -> bool885     fn unregister_callback(&mut self, callback_id: u32) -> bool {
886         for s in self.sets.values_mut().filter(|s| s.callback_id() == callback_id) {
887             if s.is_valid() {
888                 self.gatt.lock().unwrap().advertiser.unregister(s.adv_id());
889             } else {
890                 s.set_stopped();
891             }
892         }
893         self.sets.retain(|_, s| s.callback_id() != callback_id || !s.is_valid());
894 
895         self.callbacks.remove_callback(callback_id)
896     }
897 
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, ) -> i32898     fn start_advertising_set(
899         &mut self,
900         mut parameters: AdvertisingSetParameters,
901         advertise_data: AdvertiseData,
902         scan_response: Option<AdvertiseData>,
903         periodic_parameters: Option<PeriodicAdvertisingParameters>,
904         periodic_data: Option<AdvertiseData>,
905         duration: i32,
906         max_ext_adv_events: i32,
907         callback_id: u32,
908     ) -> i32 {
909         if self.suspend_mode() != SuspendMode::Normal {
910             return INVALID_REG_ID;
911         }
912 
913         let device_name = self.get_adapter_name();
914         let adv_bytes = advertise_data.make_with(&device_name);
915         // TODO(b/311417973): Remove this once we have more robust /device/bluetooth APIs to control extended advertising
916         let is_legacy =
917             parameters.is_legacy && !AdvertiseData::can_upgrade(&mut parameters, &adv_bytes);
918         let params = parameters.into();
919         if !AdvertiseData::validate_raw_data(is_legacy, &adv_bytes) {
920             warn!("Failed to start advertising set with invalid advertise data");
921             return INVALID_REG_ID;
922         }
923         let scan_bytes =
924             if let Some(d) = scan_response { d.make_with(&device_name) } else { Vec::<u8>::new() };
925         if !AdvertiseData::validate_raw_data(is_legacy, &scan_bytes) {
926             warn!("Failed to start advertising set with invalid scan response");
927             return INVALID_REG_ID;
928         }
929         let periodic_params = if let Some(p) = periodic_parameters {
930             p.into()
931         } else {
932             bt_topshim::profiles::gatt::PeriodicAdvertisingParameters::default()
933         };
934         let periodic_bytes =
935             if let Some(d) = periodic_data { d.make_with(&device_name) } else { Vec::<u8>::new() };
936         if !AdvertiseData::validate_raw_data(false, &periodic_bytes) {
937             warn!("Failed to start advertising set with invalid periodic data");
938             return INVALID_REG_ID;
939         }
940         let adv_timeout = clamp(duration, 0, 0xffff) as u16;
941         let adv_events = clamp(max_ext_adv_events, 0, 0xff) as u8;
942 
943         let reg_id = self.new_reg_id();
944         let s = AdvertisingSetInfo::new(callback_id, adv_timeout, adv_events, is_legacy, reg_id);
945         self.add(s);
946 
947         self.gatt.lock().unwrap().advertiser.start_advertising_set(
948             reg_id,
949             params,
950             adv_bytes,
951             scan_bytes,
952             periodic_params,
953             periodic_bytes,
954             adv_timeout,
955             adv_events,
956         );
957         reg_id
958     }
959 
stop_advertising_set(&mut self, advertiser_id: i32)960     fn stop_advertising_set(&mut self, advertiser_id: i32) {
961         let s = if let Some(s) = self.get_by_advertiser_id(advertiser_id) {
962             *s
963         } else {
964             return;
965         };
966 
967         if self.suspend_mode() != SuspendMode::Normal {
968             if !s.is_stopped() {
969                 info!("Deferred advertisement unregistering due to suspending");
970                 self.get_mut_by_advertiser_id(advertiser_id).unwrap().set_stopped();
971                 if let Some(cb) = self.get_callback(&s) {
972                     cb.on_advertising_set_stopped(advertiser_id);
973                 }
974             }
975             return;
976         }
977 
978         self.gatt.lock().unwrap().advertiser.unregister(s.adv_id());
979         if let Some(cb) = self.get_callback(&s) {
980             cb.on_advertising_set_stopped(advertiser_id);
981         }
982         self.remove_by_advertiser_id(advertiser_id);
983     }
984 
get_own_address(&mut self, advertiser_id: i32)985     fn get_own_address(&mut self, advertiser_id: i32) {
986         if self.suspend_mode() != SuspendMode::Normal {
987             return;
988         }
989 
990         if let Some(s) = self.get_by_advertiser_id(advertiser_id) {
991             self.gatt.lock().unwrap().advertiser.get_own_address(s.adv_id());
992         }
993     }
994 
enable_advertising_set( &mut self, advertiser_id: i32, enable: bool, duration: i32, max_ext_adv_events: i32, )995     fn enable_advertising_set(
996         &mut self,
997         advertiser_id: i32,
998         enable: bool,
999         duration: i32,
1000         max_ext_adv_events: i32,
1001     ) {
1002         if self.suspend_mode() != SuspendMode::Normal {
1003             return;
1004         }
1005 
1006         let adv_timeout = clamp(duration, 0, 0xffff) as u16;
1007         let adv_events = clamp(max_ext_adv_events, 0, 0xff) as u8;
1008 
1009         if let Some(s) = self.get_by_advertiser_id(advertiser_id) {
1010             self.gatt.lock().unwrap().advertiser.enable(
1011                 s.adv_id(),
1012                 enable,
1013                 adv_timeout,
1014                 adv_events,
1015             );
1016         }
1017     }
1018 
set_advertising_data(&mut self, advertiser_id: i32, data: AdvertiseData)1019     fn set_advertising_data(&mut self, advertiser_id: i32, data: AdvertiseData) {
1020         if self.suspend_mode() != SuspendMode::Normal {
1021             return;
1022         }
1023 
1024         let device_name = self.get_adapter_name();
1025         let bytes = data.make_with(&device_name);
1026 
1027         if let Some(s) = self.get_by_advertiser_id(advertiser_id) {
1028             if !AdvertiseData::validate_raw_data(s.is_legacy(), &bytes) {
1029                 warn!("AdvertiseManagerImpl {}: invalid advertise data to update", advertiser_id);
1030                 return;
1031             }
1032             self.gatt.lock().unwrap().advertiser.set_data(s.adv_id(), false, bytes);
1033         }
1034     }
1035 
set_raw_adv_data(&mut self, advertiser_id: i32, data: Vec<u8>)1036     fn set_raw_adv_data(&mut self, advertiser_id: i32, data: Vec<u8>) {
1037         if self.suspend_mode() != SuspendMode::Normal {
1038             return;
1039         }
1040 
1041         if let Some(s) = self.get_by_advertiser_id(advertiser_id) {
1042             if !AdvertiseData::validate_raw_data(s.is_legacy(), &data) {
1043                 warn!(
1044                     "AdvertiseManagerImpl {}: invalid raw advertise data to update",
1045                     advertiser_id
1046                 );
1047                 return;
1048             }
1049             self.gatt.lock().unwrap().advertiser.set_data(s.adv_id(), false, data);
1050         }
1051     }
1052 
set_scan_response_data(&mut self, advertiser_id: i32, data: AdvertiseData)1053     fn set_scan_response_data(&mut self, advertiser_id: i32, data: AdvertiseData) {
1054         if self.suspend_mode() != SuspendMode::Normal {
1055             return;
1056         }
1057 
1058         let device_name = self.get_adapter_name();
1059         let bytes = data.make_with(&device_name);
1060 
1061         if let Some(s) = self.get_by_advertiser_id(advertiser_id) {
1062             if !AdvertiseData::validate_raw_data(s.is_legacy(), &bytes) {
1063                 warn!("AdvertiseManagerImpl {}: invalid scan response to update", advertiser_id);
1064                 return;
1065             }
1066             self.gatt.lock().unwrap().advertiser.set_data(s.adv_id(), true, bytes);
1067         }
1068     }
1069 
set_advertising_parameters( &mut self, advertiser_id: i32, parameters: AdvertisingSetParameters, )1070     fn set_advertising_parameters(
1071         &mut self,
1072         advertiser_id: i32,
1073         parameters: AdvertisingSetParameters,
1074     ) {
1075         if self.suspend_mode() != SuspendMode::Normal {
1076             return;
1077         }
1078 
1079         let params = parameters.into();
1080 
1081         if let Some(s) = self.get_by_advertiser_id(advertiser_id) {
1082             let was_enabled = s.is_enabled();
1083             if was_enabled {
1084                 self.gatt.lock().unwrap().advertiser.enable(
1085                     s.adv_id(),
1086                     false,
1087                     s.adv_timeout(),
1088                     s.adv_events(),
1089                 );
1090             }
1091             self.gatt.lock().unwrap().advertiser.set_parameters(s.adv_id(), params);
1092             if was_enabled {
1093                 self.gatt.lock().unwrap().advertiser.enable(
1094                     s.adv_id(),
1095                     true,
1096                     s.adv_timeout(),
1097                     s.adv_events(),
1098                 );
1099             }
1100         }
1101     }
1102 
set_periodic_advertising_parameters( &mut self, advertiser_id: i32, parameters: PeriodicAdvertisingParameters, )1103     fn set_periodic_advertising_parameters(
1104         &mut self,
1105         advertiser_id: i32,
1106         parameters: PeriodicAdvertisingParameters,
1107     ) {
1108         if self.suspend_mode() != SuspendMode::Normal {
1109             return;
1110         }
1111 
1112         let params = parameters.into();
1113 
1114         if let Some(s) = self.get_by_advertiser_id(advertiser_id) {
1115             self.gatt
1116                 .lock()
1117                 .unwrap()
1118                 .advertiser
1119                 .set_periodic_advertising_parameters(s.adv_id(), params);
1120         }
1121     }
1122 
set_periodic_advertising_data(&mut self, advertiser_id: i32, data: AdvertiseData)1123     fn set_periodic_advertising_data(&mut self, advertiser_id: i32, data: AdvertiseData) {
1124         if self.suspend_mode() != SuspendMode::Normal {
1125             return;
1126         }
1127 
1128         let device_name = self.get_adapter_name();
1129         let bytes = data.make_with(&device_name);
1130 
1131         if let Some(s) = self.get_by_advertiser_id(advertiser_id) {
1132             if !AdvertiseData::validate_raw_data(false, &bytes) {
1133                 warn!("AdvertiseManagerImpl {}: invalid periodic data to update", advertiser_id);
1134                 return;
1135             }
1136             self.gatt.lock().unwrap().advertiser.set_periodic_advertising_data(s.adv_id(), bytes);
1137         }
1138     }
1139 
set_periodic_advertising_enable( &mut self, advertiser_id: i32, enable: bool, include_adi: bool, )1140     fn set_periodic_advertising_enable(
1141         &mut self,
1142         advertiser_id: i32,
1143         enable: bool,
1144         include_adi: bool,
1145     ) {
1146         if self.suspend_mode() != SuspendMode::Normal {
1147             return;
1148         }
1149         if let Some(s) = self.get_by_advertiser_id(advertiser_id) {
1150             self.gatt.lock().unwrap().advertiser.set_periodic_advertising_enable(
1151                 s.adv_id(),
1152                 enable,
1153                 include_adi,
1154             );
1155         }
1156     }
1157 }
1158 
1159 #[btif_callbacks_dispatcher(dispatch_le_adv_callbacks, GattAdvCallbacks)]
1160 pub(crate) trait BtifGattAdvCallbacks {
1161     #[btif_callback(OnAdvertisingSetStarted)]
on_advertising_set_started( &mut self, reg_id: i32, advertiser_id: u8, tx_power: i8, status: AdvertisingStatus, )1162     fn on_advertising_set_started(
1163         &mut self,
1164         reg_id: i32,
1165         advertiser_id: u8,
1166         tx_power: i8,
1167         status: AdvertisingStatus,
1168     );
1169 
1170     #[btif_callback(OnAdvertisingEnabled)]
on_advertising_enabled(&mut self, adv_id: u8, enabled: bool, status: AdvertisingStatus)1171     fn on_advertising_enabled(&mut self, adv_id: u8, enabled: bool, status: AdvertisingStatus);
1172 
1173     #[btif_callback(OnAdvertisingDataSet)]
on_advertising_data_set(&mut self, adv_id: u8, status: AdvertisingStatus)1174     fn on_advertising_data_set(&mut self, adv_id: u8, status: AdvertisingStatus);
1175 
1176     #[btif_callback(OnScanResponseDataSet)]
on_scan_response_data_set(&mut self, adv_id: u8, status: AdvertisingStatus)1177     fn on_scan_response_data_set(&mut self, adv_id: u8, status: AdvertisingStatus);
1178 
1179     #[btif_callback(OnAdvertisingParametersUpdated)]
on_advertising_parameters_updated( &mut self, adv_id: u8, tx_power: i8, status: AdvertisingStatus, )1180     fn on_advertising_parameters_updated(
1181         &mut self,
1182         adv_id: u8,
1183         tx_power: i8,
1184         status: AdvertisingStatus,
1185     );
1186 
1187     #[btif_callback(OnPeriodicAdvertisingParametersUpdated)]
on_periodic_advertising_parameters_updated(&mut self, adv_id: u8, status: AdvertisingStatus)1188     fn on_periodic_advertising_parameters_updated(&mut self, adv_id: u8, status: AdvertisingStatus);
1189 
1190     #[btif_callback(OnPeriodicAdvertisingDataSet)]
on_periodic_advertising_data_set(&mut self, adv_id: u8, status: AdvertisingStatus)1191     fn on_periodic_advertising_data_set(&mut self, adv_id: u8, status: AdvertisingStatus);
1192 
1193     #[btif_callback(OnPeriodicAdvertisingEnabled)]
on_periodic_advertising_enabled( &mut self, adv_id: u8, enabled: bool, status: AdvertisingStatus, )1194     fn on_periodic_advertising_enabled(
1195         &mut self,
1196         adv_id: u8,
1197         enabled: bool,
1198         status: AdvertisingStatus,
1199     );
1200 
1201     #[btif_callback(OnOwnAddressRead)]
on_own_address_read(&mut self, adv_id: u8, addr_type: u8, address: RawAddress)1202     fn on_own_address_read(&mut self, adv_id: u8, addr_type: u8, address: RawAddress);
1203 }
1204 
1205 impl BtifGattAdvCallbacks for AdvertiseManagerImpl {
on_advertising_set_started( &mut self, reg_id: i32, advertiser_id: u8, tx_power: i8, status: AdvertisingStatus, )1206     fn on_advertising_set_started(
1207         &mut self,
1208         reg_id: i32,
1209         advertiser_id: u8,
1210         tx_power: i8,
1211         status: AdvertisingStatus,
1212     ) {
1213         debug!(
1214             "on_advertising_set_started(): reg_id = {}, advertiser_id = {}, tx_power = {}, status = {:?}",
1215             reg_id, advertiser_id, tx_power, status
1216         );
1217 
1218         let s = if let Some(s) = self.sets.get_mut(&reg_id) {
1219             s
1220         } else {
1221             error!("AdvertisingSetInfo not found");
1222             // An unknown advertising set has started. Unregister it anyway.
1223             self.gatt.lock().unwrap().advertiser.unregister(advertiser_id);
1224             return;
1225         };
1226 
1227         if s.is_stopped() {
1228             // The advertising set needs to be stopped. This could happen when |unregister_callback|
1229             // is called before an advertising becomes ready.
1230             self.gatt.lock().unwrap().advertiser.unregister(advertiser_id);
1231             self.sets.remove(&reg_id);
1232             return;
1233         }
1234 
1235         s.set_adv_id(Some(advertiser_id.into()));
1236         s.set_enabled(status == AdvertisingStatus::Success);
1237 
1238         if let Some(cb) = self.callbacks.get_by_id_mut(s.callback_id()) {
1239             cb.on_advertising_set_started(reg_id, advertiser_id.into(), tx_power.into(), status);
1240         }
1241 
1242         if status != AdvertisingStatus::Success {
1243             warn!(
1244                 "on_advertising_set_started(): failed! reg_id = {}, status = {:?}",
1245                 reg_id, status
1246             );
1247             self.sets.remove(&reg_id);
1248         }
1249     }
1250 
on_advertising_enabled(&mut self, adv_id: u8, enabled: bool, status: AdvertisingStatus)1251     fn on_advertising_enabled(&mut self, adv_id: u8, enabled: bool, status: AdvertisingStatus) {
1252         debug!(
1253             "on_advertising_enabled(): adv_id = {}, enabled = {}, status = {:?}",
1254             adv_id, enabled, status
1255         );
1256 
1257         let advertiser_id: i32 = adv_id.into();
1258 
1259         if let Some(s) = self.get_mut_by_advertiser_id(advertiser_id) {
1260             s.set_enabled(enabled);
1261         } else {
1262             return;
1263         }
1264 
1265         let s = *self.get_by_advertiser_id(advertiser_id).unwrap();
1266         if let Some(cb) = self.get_callback(&s) {
1267             cb.on_advertising_enabled(advertiser_id, enabled, status);
1268         }
1269 
1270         if self.suspend_mode() == SuspendMode::Suspending && self.enabled_sets().count() == 0 {
1271             self.set_suspend_mode(SuspendMode::Suspended);
1272         }
1273     }
1274 
on_advertising_data_set(&mut self, adv_id: u8, status: AdvertisingStatus)1275     fn on_advertising_data_set(&mut self, adv_id: u8, status: AdvertisingStatus) {
1276         debug!("on_advertising_data_set(): adv_id = {}, status = {:?}", adv_id, status);
1277 
1278         let advertiser_id: i32 = adv_id.into();
1279         if self.get_by_advertiser_id(advertiser_id).is_none() {
1280             return;
1281         }
1282         let s = *self.get_by_advertiser_id(advertiser_id).unwrap();
1283 
1284         if let Some(cb) = self.get_callback(&s) {
1285             cb.on_advertising_data_set(advertiser_id, status);
1286         }
1287     }
1288 
on_scan_response_data_set(&mut self, adv_id: u8, status: AdvertisingStatus)1289     fn on_scan_response_data_set(&mut self, adv_id: u8, status: AdvertisingStatus) {
1290         debug!("on_scan_response_data_set(): adv_id = {}, status = {:?}", adv_id, status);
1291 
1292         let advertiser_id: i32 = adv_id.into();
1293         if self.get_by_advertiser_id(advertiser_id).is_none() {
1294             return;
1295         }
1296         let s = *self.get_by_advertiser_id(advertiser_id).unwrap();
1297 
1298         if let Some(cb) = self.get_callback(&s) {
1299             cb.on_scan_response_data_set(advertiser_id, status);
1300         }
1301     }
1302 
on_advertising_parameters_updated( &mut self, adv_id: u8, tx_power: i8, status: AdvertisingStatus, )1303     fn on_advertising_parameters_updated(
1304         &mut self,
1305         adv_id: u8,
1306         tx_power: i8,
1307         status: AdvertisingStatus,
1308     ) {
1309         debug!(
1310             "on_advertising_parameters_updated(): adv_id = {}, tx_power = {}, status = {:?}",
1311             adv_id, tx_power, status
1312         );
1313 
1314         let advertiser_id: i32 = adv_id.into();
1315         if self.get_by_advertiser_id(advertiser_id).is_none() {
1316             return;
1317         }
1318         let s = *self.get_by_advertiser_id(advertiser_id).unwrap();
1319 
1320         if let Some(cb) = self.get_callback(&s) {
1321             cb.on_advertising_parameters_updated(advertiser_id, tx_power.into(), status);
1322         }
1323     }
1324 
on_periodic_advertising_parameters_updated( &mut self, adv_id: u8, status: AdvertisingStatus, )1325     fn on_periodic_advertising_parameters_updated(
1326         &mut self,
1327         adv_id: u8,
1328         status: AdvertisingStatus,
1329     ) {
1330         debug!(
1331             "on_periodic_advertising_parameters_updated(): adv_id = {}, status = {:?}",
1332             adv_id, status
1333         );
1334 
1335         let advertiser_id: i32 = adv_id.into();
1336         if self.get_by_advertiser_id(advertiser_id).is_none() {
1337             return;
1338         }
1339         let s = *self.get_by_advertiser_id(advertiser_id).unwrap();
1340 
1341         if let Some(cb) = self.get_callback(&s) {
1342             cb.on_periodic_advertising_parameters_updated(advertiser_id, status);
1343         }
1344     }
1345 
on_periodic_advertising_data_set(&mut self, adv_id: u8, status: AdvertisingStatus)1346     fn on_periodic_advertising_data_set(&mut self, adv_id: u8, status: AdvertisingStatus) {
1347         debug!("on_periodic_advertising_data_set(): adv_id = {}, status = {:?}", adv_id, status);
1348 
1349         let advertiser_id: i32 = adv_id.into();
1350         if self.get_by_advertiser_id(advertiser_id).is_none() {
1351             return;
1352         }
1353         let s = *self.get_by_advertiser_id(advertiser_id).unwrap();
1354 
1355         if let Some(cb) = self.get_callback(&s) {
1356             cb.on_periodic_advertising_data_set(advertiser_id, status);
1357         }
1358     }
1359 
on_periodic_advertising_enabled( &mut self, adv_id: u8, enabled: bool, status: AdvertisingStatus, )1360     fn on_periodic_advertising_enabled(
1361         &mut self,
1362         adv_id: u8,
1363         enabled: bool,
1364         status: AdvertisingStatus,
1365     ) {
1366         debug!(
1367             "on_periodic_advertising_enabled(): adv_id = {}, enabled = {}, status = {:?}",
1368             adv_id, enabled, status
1369         );
1370 
1371         let advertiser_id: i32 = adv_id.into();
1372         if self.get_by_advertiser_id(advertiser_id).is_none() {
1373             return;
1374         }
1375         let s = *self.get_by_advertiser_id(advertiser_id).unwrap();
1376 
1377         if let Some(cb) = self.get_callback(&s) {
1378             cb.on_periodic_advertising_enabled(advertiser_id, enabled, status);
1379         }
1380     }
1381 
on_own_address_read(&mut self, adv_id: u8, addr_type: u8, address: RawAddress)1382     fn on_own_address_read(&mut self, adv_id: u8, addr_type: u8, address: RawAddress) {
1383         debug!(
1384             "on_own_address_read(): adv_id = {}, addr_type = {}, address = {}",
1385             adv_id,
1386             addr_type,
1387             DisplayAddress(&address)
1388         );
1389 
1390         let advertiser_id: i32 = adv_id.into();
1391         if self.get_by_advertiser_id(advertiser_id).is_none() {
1392             return;
1393         }
1394         let s = *self.get_by_advertiser_id(advertiser_id).unwrap();
1395 
1396         if let Some(cb) = self.get_callback(&s) {
1397             cb.on_own_address_read(advertiser_id, addr_type.into(), address);
1398         }
1399     }
1400 }
1401 
1402 /// The underlying legacy advertising rotates every SOFTWARE_ROTATION_INTERVAL seconds.
1403 const SOFTWARE_ROTATION_INTERVAL: Duration = Duration::from_secs(2);
1404 
1405 /// The ID of a software rotation advertising.
1406 ///
1407 /// From DBus API's perspective this is used as both Advertiser ID and Register ID.
1408 /// Unlike the extended advertising stack we can't propagate the LibBluetooth Advertiser ID to
1409 /// DBus clients because there can be at most 1 advertiser in LibBluetooth layer at the same time.
1410 pub type SoftwareRotationAdvertierId = i32;
1411 
1412 struct SoftwareRotationAdvertiseInfo {
1413     id: SoftwareRotationAdvertierId,
1414     callback_id: u32,
1415 
1416     advertising_params: AdvertisingSetParameters,
1417     advertising_data: Vec<u8>,
1418     scan_response_data: Vec<u8>,
1419 
1420     /// Filled in on the first time the advertiser started.
1421     tx_power: Option<i32>,
1422 
1423     /// True if it's advertising (from DBus client's perspective), false otherwise.
1424     enabled: bool,
1425     duration: i32,
1426     /// None means no timeout
1427     expire_time: Option<Instant>,
1428 }
1429 
1430 enum SoftwareRotationAdvertiseState {
1431     /// No advertiser is running in LibBluetooth.
1432     Stopped,
1433     /// A StartAdvertisingSet call to LibBluetooth is pending.
1434     Pending(SoftwareRotationAdvertierId),
1435     /// An advertiser is running in LibBluetooth, i.e., an OnAdvertisingSetStarted is received.
1436     /// Parameters: ID, LibBluetooth BLE Advertiser ID, rotation timer handle
1437     Advertising(SoftwareRotationAdvertierId, u8, JoinHandle<()>),
1438 }
1439 
1440 struct SoftwareRotationAdvertiseManagerImpl {
1441     callbacks: Callbacks<dyn IAdvertisingSetCallback + Send>,
1442     suspend_mode: SuspendMode,
1443     gatt: Arc<Mutex<Gatt>>,
1444     adapter: Arc<Mutex<Box<Bluetooth>>>,
1445     tx: Sender<Message>,
1446 
1447     state: SoftwareRotationAdvertiseState,
1448     adv_info: HashMap<SoftwareRotationAdvertierId, SoftwareRotationAdvertiseInfo>,
1449     /// The enabled advertising sets to be rotate.
1450     /// When they are removed from the queue, OnAdvertisingEnabled needs to be sent.
1451     /// Note that the current advertiser running in LibBluetooth must *NOT* be in the queue.
1452     adv_queue: VecDeque<SoftwareRotationAdvertierId>,
1453 }
1454 
1455 impl SoftwareRotationAdvertiseManagerImpl {
new( tx: Sender<Message>, gatt: Arc<Mutex<Gatt>>, adapter: Arc<Mutex<Box<Bluetooth>>>, ) -> Self1456     fn new(
1457         tx: Sender<Message>,
1458         gatt: Arc<Mutex<Gatt>>,
1459         adapter: Arc<Mutex<Box<Bluetooth>>>,
1460     ) -> Self {
1461         Self {
1462             callbacks: Callbacks::new(tx.clone(), Message::AdvertiserCallbackDisconnected),
1463             suspend_mode: SuspendMode::Normal,
1464             gatt,
1465             adapter,
1466             tx,
1467             state: SoftwareRotationAdvertiseState::Stopped,
1468             adv_info: HashMap::new(),
1469             adv_queue: VecDeque::new(),
1470         }
1471     }
1472 }
1473 
1474 impl SoftwareRotationAdvertiseManagerImpl {
1475     /// Updates suspend mode.
set_suspend_mode(&mut self, suspend_mode: SuspendMode)1476     fn set_suspend_mode(&mut self, suspend_mode: SuspendMode) {
1477         if suspend_mode != self.suspend_mode {
1478             self.suspend_mode = suspend_mode.clone();
1479             self.callbacks.for_all_callbacks(|cb| {
1480                 cb.on_suspend_mode_change(suspend_mode.clone());
1481             });
1482         }
1483     }
1484 
get_adapter_name(&self) -> String1485     fn get_adapter_name(&self) -> String {
1486         self.adapter.lock().unwrap().get_name()
1487     }
1488 
1489     /// Returns the ID of the advertiser running in LibBluetooth.
current_id(&self) -> Option<SoftwareRotationAdvertierId>1490     fn current_id(&self) -> Option<SoftwareRotationAdvertierId> {
1491         match &self.state {
1492             SoftwareRotationAdvertiseState::Pending(id) => Some(*id),
1493             SoftwareRotationAdvertiseState::Advertising(id, _, _) => Some(*id),
1494             SoftwareRotationAdvertiseState::Stopped => None,
1495         }
1496     }
1497 
1498     /// Returns the minimum unoccupied ID from 0.
new_id(&mut self) -> SoftwareRotationAdvertierId1499     fn new_id(&mut self) -> SoftwareRotationAdvertierId {
1500         // The advertiser running in LibBluetooth may have been removed in this layer.
1501         // Avoid conflicting with it.
1502         let current_id = self.current_id();
1503         (0..)
1504             .find(|id| !self.adv_info.contains_key(id) && Some(*id) != current_id)
1505             .expect("There must be an unoccupied register ID")
1506     }
1507 
is_pending(&self) -> bool1508     fn is_pending(&self) -> bool {
1509         matches!(&self.state, SoftwareRotationAdvertiseState::Pending(_))
1510     }
1511 
is_stopped(&self) -> bool1512     fn is_stopped(&self) -> bool {
1513         matches!(&self.state, SoftwareRotationAdvertiseState::Stopped)
1514     }
1515 
1516     /// Clears the removed or disabled advertisers from the queue and invokes callback.
refresh_queue(&mut self)1517     fn refresh_queue(&mut self) {
1518         let now = Instant::now();
1519         let adv_info = &mut self.adv_info;
1520         let callbacks = &mut self.callbacks;
1521         self.adv_queue.retain(|id| {
1522             let Some(info) = adv_info.get_mut(id) else {
1523                 // This advertiser has been removed.
1524                 return false;
1525             };
1526             if info.expire_time.map_or(false, |t| t < now) {
1527                 // This advertiser has expired.
1528                 info.enabled = false;
1529                 if let Some(cb) = callbacks.get_by_id_mut(info.callback_id) {
1530                     cb.on_advertising_enabled(info.id, false, AdvertisingStatus::Success);
1531                 }
1532             }
1533             info.enabled
1534         });
1535     }
1536 
stop_current_advertising(&mut self)1537     fn stop_current_advertising(&mut self) {
1538         match &self.state {
1539             SoftwareRotationAdvertiseState::Advertising(id, adv_id, handle) => {
1540                 handle.abort();
1541                 self.gatt.lock().unwrap().advertiser.unregister(*adv_id);
1542                 self.adv_queue.push_back(*id);
1543                 self.state = SoftwareRotationAdvertiseState::Stopped;
1544             }
1545             SoftwareRotationAdvertiseState::Pending(_) => {
1546                 error!("stop_current_advertising: Unexpected Pending state");
1547             }
1548             SoftwareRotationAdvertiseState::Stopped => {}
1549         };
1550     }
1551 
start_next_advertising(&mut self)1552     fn start_next_advertising(&mut self) {
1553         match &self.state {
1554             SoftwareRotationAdvertiseState::Stopped => {
1555                 self.state = loop {
1556                     let Some(id) = self.adv_queue.pop_front() else {
1557                         break SoftwareRotationAdvertiseState::Stopped;
1558                     };
1559                     let Some(info) = self.adv_info.get(&id) else {
1560                         error!("start_next_advertising: Unknown ID, which means queue is not refreshed!");
1561                         continue;
1562                     };
1563                     self.gatt.lock().unwrap().advertiser.start_advertising_set(
1564                         id,
1565                         info.advertising_params.clone().into(),
1566                         info.advertising_data.clone(),
1567                         info.scan_response_data.clone(),
1568                         Default::default(), // Unsupported periodic_parameters
1569                         vec![],             // Unsupported periodic_data
1570                         0,                  // Set no timeout. Timeout is controlled in this layer.
1571                         0,                  // Unsupported max_ext_adv_events
1572                     );
1573                     break SoftwareRotationAdvertiseState::Pending(id);
1574                 }
1575             }
1576             SoftwareRotationAdvertiseState::Pending(_) => {
1577                 error!("start_next_advertising: Unexpected Pending state");
1578             }
1579             SoftwareRotationAdvertiseState::Advertising(_, _, _) => {
1580                 error!("start_next_advertising: Unexpected Advertising state");
1581             }
1582         };
1583     }
1584 
run_rotate(&mut self)1585     fn run_rotate(&mut self) {
1586         if self.is_pending() {
1587             return;
1588         }
1589         let Some(current_id) = self.current_id() else {
1590             // State is Stopped. Try to start next one.
1591             self.refresh_queue();
1592             self.start_next_advertising();
1593             return;
1594         };
1595         // We are Advertising. Checks if the current advertiser is still allowed
1596         // to advertise, or if we should schedule the next one in the queue.
1597         let current_is_enabled = {
1598             let now = Instant::now();
1599             if let Some(info) = self.adv_info.get(&current_id) {
1600                 if info.enabled {
1601                     info.expire_time.map_or(true, |t| t >= now)
1602                 } else {
1603                     false
1604                 }
1605             } else {
1606                 false
1607             }
1608         };
1609         if !current_is_enabled {
1610             // If current advertiser is not allowed to advertise,
1611             // stop it and then let |refresh_queue| handle the callback.
1612             self.stop_current_advertising();
1613             self.refresh_queue();
1614             self.start_next_advertising();
1615         } else {
1616             // Current advertiser is still enabled, refresh the other advertisers in the queue.
1617             self.refresh_queue();
1618             if self.adv_queue.is_empty() {
1619                 // No need to rotate.
1620             } else {
1621                 self.stop_current_advertising();
1622                 self.start_next_advertising();
1623             }
1624         }
1625     }
1626 }
1627 
1628 impl AdvertiseManagerOps for SoftwareRotationAdvertiseManagerImpl {
enter_suspend(&mut self)1629     fn enter_suspend(&mut self) {
1630         if self.suspend_mode != SuspendMode::Normal {
1631             return;
1632         }
1633 
1634         self.set_suspend_mode(SuspendMode::Suspending);
1635         if self.is_pending() {
1636             // We will unregister it on_advertising_set_started and then set mode to suspended.
1637             return;
1638         }
1639         self.stop_current_advertising();
1640         self.set_suspend_mode(SuspendMode::Suspended);
1641     }
1642 
exit_suspend(&mut self)1643     fn exit_suspend(&mut self) {
1644         if self.suspend_mode != SuspendMode::Suspended {
1645             return;
1646         }
1647         self.refresh_queue();
1648         self.start_next_advertising();
1649         self.set_suspend_mode(SuspendMode::Normal);
1650     }
1651 
handle_action(&mut self, action: AdvertiserActions)1652     fn handle_action(&mut self, action: AdvertiserActions) {
1653         match action {
1654             AdvertiserActions::RunRotate => {
1655                 if self.suspend_mode == SuspendMode::Normal {
1656                     self.run_rotate();
1657                 }
1658             }
1659         }
1660     }
1661 }
1662 
1663 /// Generates expire time from now per the definition in IBluetoothAdvertiseManager
1664 ///
1665 /// None means never timeout.
gen_expire_time_from_now(duration: i32) -> Option<Instant>1666 fn gen_expire_time_from_now(duration: i32) -> Option<Instant> {
1667     let duration = clamp(duration, 0, 0xffff) as u64;
1668     if duration != 0 {
1669         Some(Instant::now() + Duration::from_millis(duration * 10))
1670     } else {
1671         None
1672     }
1673 }
1674 
1675 impl IBluetoothAdvertiseManager for SoftwareRotationAdvertiseManagerImpl {
register_callback(&mut self, callback: Box<dyn IAdvertisingSetCallback + Send>) -> u321676     fn register_callback(&mut self, callback: Box<dyn IAdvertisingSetCallback + Send>) -> u32 {
1677         self.callbacks.add_callback(callback)
1678     }
1679 
unregister_callback(&mut self, callback_id: u32) -> bool1680     fn unregister_callback(&mut self, callback_id: u32) -> bool {
1681         self.adv_info.retain(|_, info| info.callback_id != callback_id);
1682         let ret = self.callbacks.remove_callback(callback_id);
1683         if let Some(current_id) = self.current_id() {
1684             if !self.adv_info.contains_key(&current_id) {
1685                 self.run_rotate();
1686             }
1687         }
1688         ret
1689     }
1690 
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, ) -> i321691     fn start_advertising_set(
1692         &mut self,
1693         advertising_params: AdvertisingSetParameters,
1694         advertising_data: AdvertiseData,
1695         scan_response_data: Option<AdvertiseData>,
1696         periodic_parameters: Option<PeriodicAdvertisingParameters>,
1697         periodic_data: Option<AdvertiseData>,
1698         duration: i32,
1699         max_ext_adv_events: i32,
1700         callback_id: u32,
1701     ) -> i32 {
1702         if self.suspend_mode != SuspendMode::Normal {
1703             return INVALID_REG_ID;
1704         }
1705 
1706         let is_legacy = advertising_params.is_legacy;
1707         let device_name = self.get_adapter_name();
1708 
1709         let advertising_data = advertising_data.make_with(&device_name);
1710         if !AdvertiseData::validate_raw_data(is_legacy, &advertising_data) {
1711             warn!("Failed to start advertising set with invalid advertising data");
1712             return INVALID_REG_ID;
1713         }
1714 
1715         let scan_response_data =
1716             scan_response_data.map_or(vec![], |data| data.make_with(&device_name));
1717         if !AdvertiseData::validate_raw_data(is_legacy, &scan_response_data) {
1718             warn!("Failed to start advertising set with invalid scan response data");
1719             return INVALID_REG_ID;
1720         }
1721 
1722         if periodic_parameters.is_some() {
1723             warn!("Periodic parameters is not supported in software rotation stack, ignored");
1724         }
1725         if periodic_data.is_some() {
1726             warn!("Periodic data is not supported in software rotation stack, ignored");
1727         }
1728         if max_ext_adv_events != 0 {
1729             warn!("max_ext_adv_events is not supported in software rotation stack, ignored");
1730         }
1731 
1732         let id = self.new_id();
1733 
1734         // expire_time will be determined on this advertiser is started at the first time.
1735         self.adv_info.insert(
1736             id,
1737             SoftwareRotationAdvertiseInfo {
1738                 id,
1739                 callback_id,
1740                 advertising_params,
1741                 advertising_data,
1742                 scan_response_data,
1743                 tx_power: None,
1744                 enabled: true,
1745                 duration,
1746                 expire_time: None,
1747             },
1748         );
1749         // Schedule it as the next one and rotate.
1750         self.adv_queue.push_front(id);
1751         self.run_rotate();
1752 
1753         id
1754     }
1755 
stop_advertising_set(&mut self, adv_id: i32)1756     fn stop_advertising_set(&mut self, adv_id: i32) {
1757         let current_id = self.current_id();
1758         let Some(info) = self.adv_info.remove(&adv_id) else {
1759             warn!("stop_advertising_set: Unknown adv_id {}", adv_id);
1760             return;
1761         };
1762         if let Some(cb) = self.callbacks.get_by_id_mut(info.callback_id) {
1763             cb.on_advertising_set_stopped(info.id);
1764         }
1765         if current_id == Some(info.id) {
1766             self.run_rotate();
1767         }
1768     }
1769 
get_own_address(&mut self, _adv_id: i32)1770     fn get_own_address(&mut self, _adv_id: i32) {
1771         error!("get_own_address is not supported in software rotation stack");
1772     }
1773 
enable_advertising_set( &mut self, adv_id: i32, enable: bool, duration: i32, max_ext_adv_events: i32, )1774     fn enable_advertising_set(
1775         &mut self,
1776         adv_id: i32,
1777         enable: bool,
1778         duration: i32,
1779         max_ext_adv_events: i32,
1780     ) {
1781         if self.suspend_mode != SuspendMode::Normal {
1782             return;
1783         }
1784 
1785         let current_id = self.current_id();
1786         let Some(info) = self.adv_info.get_mut(&adv_id) else {
1787             warn!("enable_advertising_set: Unknown adv_id {}", adv_id);
1788             return;
1789         };
1790 
1791         if max_ext_adv_events != 0 {
1792             warn!("max_ext_adv_events is not supported in software rotation stack, ignored");
1793         }
1794 
1795         info.enabled = enable;
1796         // We won't really call enable() to LibBluetooth so calculate the expire time right now.
1797         info.expire_time = gen_expire_time_from_now(duration);
1798         // This actually won't be used as the expire_time is already determined.
1799         // Still fill it in to keep the data updated.
1800         info.duration = duration;
1801 
1802         if enable && !self.adv_queue.contains(&info.id) && current_id != Some(info.id) {
1803             // The adv was not enabled and not in the queue. Invoke callback and queue it.
1804             if let Some(cb) = self.callbacks.get_by_id_mut(info.callback_id) {
1805                 cb.on_advertising_enabled(info.id, false, AdvertisingStatus::Success);
1806             }
1807             self.adv_queue.push_back(info.id);
1808             if self.is_stopped() {
1809                 self.start_next_advertising();
1810             }
1811         } else if !enable && current_id == Some(info.id) {
1812             self.run_rotate();
1813         }
1814     }
1815 
set_advertising_data(&mut self, adv_id: i32, data: AdvertiseData)1816     fn set_advertising_data(&mut self, adv_id: i32, data: AdvertiseData) {
1817         if self.suspend_mode != SuspendMode::Normal {
1818             return;
1819         }
1820 
1821         let current_id = self.current_id();
1822         let device_name = self.get_adapter_name();
1823         let Some(info) = self.adv_info.get_mut(&adv_id) else {
1824             warn!("set_advertising_data: Unknown adv_id {}", adv_id);
1825             return;
1826         };
1827         let data = data.make_with(&device_name);
1828         if !AdvertiseData::validate_raw_data(info.advertising_params.is_legacy, &data) {
1829             warn!("set_advertising_data {}: invalid advertise data to update", adv_id);
1830             return;
1831         }
1832         info.advertising_data = data;
1833         if let Some(cb) = self.callbacks.get_by_id_mut(info.callback_id) {
1834             cb.on_advertising_data_set(info.id, AdvertisingStatus::Success);
1835         }
1836 
1837         if current_id == Some(info.id) {
1838             self.run_rotate();
1839         }
1840     }
1841 
set_raw_adv_data(&mut self, adv_id: i32, data: Vec<u8>)1842     fn set_raw_adv_data(&mut self, adv_id: i32, data: Vec<u8>) {
1843         if self.suspend_mode != SuspendMode::Normal {
1844             return;
1845         }
1846 
1847         let current_id = self.current_id();
1848         let Some(info) = self.adv_info.get_mut(&adv_id) else {
1849             warn!("set_raw_adv_data: Unknown adv_id {}", adv_id);
1850             return;
1851         };
1852         if !AdvertiseData::validate_raw_data(info.advertising_params.is_legacy, &data) {
1853             warn!("set_raw_adv_data {}: invalid raw advertise data to update", adv_id);
1854             return;
1855         }
1856         info.advertising_data = data;
1857         if let Some(cb) = self.callbacks.get_by_id_mut(info.callback_id) {
1858             cb.on_advertising_data_set(info.id, AdvertisingStatus::Success);
1859         }
1860 
1861         if current_id == Some(info.id) {
1862             self.run_rotate();
1863         }
1864     }
1865 
set_scan_response_data(&mut self, adv_id: i32, data: AdvertiseData)1866     fn set_scan_response_data(&mut self, adv_id: i32, data: AdvertiseData) {
1867         if self.suspend_mode != SuspendMode::Normal {
1868             return;
1869         }
1870 
1871         let current_id = self.current_id();
1872         let device_name = self.get_adapter_name();
1873         let Some(info) = self.adv_info.get_mut(&adv_id) else {
1874             warn!("set_scan_response_data: Unknown adv_id {}", adv_id);
1875             return;
1876         };
1877         let data = data.make_with(&device_name);
1878         if !AdvertiseData::validate_raw_data(info.advertising_params.is_legacy, &data) {
1879             warn!("set_scan_response_data {}: invalid scan response to update", adv_id);
1880             return;
1881         }
1882         info.scan_response_data = data;
1883         if let Some(cb) = self.callbacks.get_by_id_mut(info.callback_id) {
1884             cb.on_scan_response_data_set(info.id, AdvertisingStatus::Success);
1885         }
1886 
1887         if current_id == Some(info.id) {
1888             self.run_rotate();
1889         }
1890     }
1891 
set_advertising_parameters(&mut self, adv_id: i32, params: AdvertisingSetParameters)1892     fn set_advertising_parameters(&mut self, adv_id: i32, params: AdvertisingSetParameters) {
1893         if self.suspend_mode != SuspendMode::Normal {
1894             return;
1895         }
1896 
1897         let current_id = self.current_id();
1898         let Some(info) = self.adv_info.get_mut(&adv_id) else {
1899             warn!("set_advertising_parameters: Unknown adv_id {}", adv_id);
1900             return;
1901         };
1902         info.advertising_params = params;
1903         let Some(tx_power) = info.tx_power else {
1904             error!("set_advertising_parameters: tx_power is None! Is this called before adv has started?");
1905             return;
1906         };
1907         if let Some(cb) = self.callbacks.get_by_id_mut(info.callback_id) {
1908             cb.on_advertising_parameters_updated(info.id, tx_power, AdvertisingStatus::Success);
1909         }
1910 
1911         if current_id == Some(info.id) {
1912             self.run_rotate();
1913         }
1914     }
1915 
set_periodic_advertising_parameters( &mut self, _adv_id: i32, _parameters: PeriodicAdvertisingParameters, )1916     fn set_periodic_advertising_parameters(
1917         &mut self,
1918         _adv_id: i32,
1919         _parameters: PeriodicAdvertisingParameters,
1920     ) {
1921         error!("set_periodic_advertising_parameters is not supported in software rotation stack");
1922     }
1923 
set_periodic_advertising_data(&mut self, _adv_id: i32, _data: AdvertiseData)1924     fn set_periodic_advertising_data(&mut self, _adv_id: i32, _data: AdvertiseData) {
1925         error!("set_periodic_advertising_data is not supported in software rotation stack");
1926     }
1927 
set_periodic_advertising_enable(&mut self, _adv_id: i32, _enable: bool, _include_adi: bool)1928     fn set_periodic_advertising_enable(&mut self, _adv_id: i32, _enable: bool, _include_adi: bool) {
1929         error!("set_periodic_advertising_enable is not supported in software rotation stack");
1930     }
1931 }
1932 
1933 impl BtifGattAdvCallbacks for SoftwareRotationAdvertiseManagerImpl {
on_advertising_set_started( &mut self, reg_id: i32, adv_id: u8, tx_power: i8, status: AdvertisingStatus, )1934     fn on_advertising_set_started(
1935         &mut self,
1936         reg_id: i32,
1937         adv_id: u8,
1938         tx_power: i8,
1939         status: AdvertisingStatus,
1940     ) {
1941         debug!(
1942             "on_advertising_set_started(): reg_id = {}, advertiser_id = {}, tx_power = {}, status = {:?}",
1943             reg_id, adv_id, tx_power, status
1944         );
1945 
1946         // Unregister if it's unexpected.
1947         match &self.state {
1948             SoftwareRotationAdvertiseState::Pending(pending_id) if pending_id == &reg_id => {}
1949             _ => {
1950                 error!(
1951                     "Unexpected on_advertising_set_started reg_id = {}, adv_id = {}, status = {:?}",
1952                     reg_id, adv_id, status
1953                 );
1954                 if status == AdvertisingStatus::Success {
1955                     self.gatt.lock().unwrap().advertiser.unregister(adv_id);
1956                 }
1957                 return;
1958             }
1959         }
1960         // Switch out from the pending state.
1961         self.state = if status != AdvertisingStatus::Success {
1962             warn!("on_advertising_set_started failed: reg_id = {}, status = {:?}", reg_id, status);
1963             SoftwareRotationAdvertiseState::Stopped
1964         } else {
1965             let txl = self.tx.clone();
1966             SoftwareRotationAdvertiseState::Advertising(
1967                 reg_id,
1968                 adv_id,
1969                 tokio::spawn(async move {
1970                     loop {
1971                         time::sleep(SOFTWARE_ROTATION_INTERVAL).await;
1972                         let _ = txl
1973                             .send(Message::AdvertiserActions(AdvertiserActions::RunRotate))
1974                             .await;
1975                     }
1976                 }),
1977             )
1978         };
1979 
1980         // 1. Handle on_advertising_set_started callback if it's the first time it started
1981         // 2. Stop advertising if it's removed or disabled
1982         // 3. Disable or remove the advertiser if it failed
1983         if let Some(info) = self.adv_info.get_mut(&reg_id) {
1984             if info.tx_power.is_none() {
1985                 // tx_power is none means it's the first time this advertiser started.
1986                 if status != AdvertisingStatus::Success {
1987                     if let Some(cb) = self.callbacks.get_by_id_mut(info.callback_id) {
1988                         cb.on_advertising_set_started(info.id, INVALID_ADV_ID, 0, status);
1989                     }
1990                     self.adv_info.remove(&reg_id);
1991                 } else {
1992                     info.tx_power = Some(tx_power.into());
1993                     info.expire_time = gen_expire_time_from_now(info.duration);
1994                     if let Some(cb) = self.callbacks.get_by_id_mut(info.callback_id) {
1995                         cb.on_advertising_set_started(info.id, info.id, tx_power.into(), status);
1996                     }
1997                 }
1998             } else {
1999                 // Not the first time. This means we are not able to report the failure through
2000                 // on_advertising_set_started if it failed. Disable it instead in that case.
2001                 if status != AdvertisingStatus::Success {
2002                     info.enabled = false;
2003                     // Push to the queue and let refresh_queue handle the disabled callback.
2004                     self.adv_queue.push_back(reg_id);
2005                 } else if !info.enabled {
2006                     self.stop_current_advertising();
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_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_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];
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];
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];
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_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