Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4e7ab0d8 authored by Archie Pusaka's avatar Archie Pusaka Committed by Automerger Merge Worker
Browse files

Merge "Floss: Always set scan parameters for LE scan" into main am: 9681d797 am: 6db97456

parents 0dec2f3c 6db97456
Loading
Loading
Loading
Loading
+59 −21
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@ use num_traits::clamp;
use rand::rngs::SmallRng;
use rand::{RngCore, SeedableRng};
use std::collections::{HashMap, HashSet};
use std::convert::TryInto;
use std::convert::{TryFrom, TryInto};
use std::sync::{Arc, Mutex, MutexGuard};
use tokio::sync::mpsc::Sender;
use tokio::time;
@@ -1145,7 +1145,7 @@ impl Default for GattWriteType {
    }
}

#[derive(Debug, FromPrimitive, ToPrimitive)]
#[derive(Debug, FromPrimitive, ToPrimitive, Clone)]
#[repr(u32)]
/// Scan type configuration.
pub enum ScanType {
@@ -1163,13 +1163,31 @@ impl Default for ScanType {
///
/// This configuration is general and supported on all Bluetooth hardware, irrelevant of the
/// hardware filter offload (APCF or MSFT).
#[derive(Debug, Default)]
#[derive(Debug, Clone)]
pub struct ScanSettings {
    pub interval: i32,
    pub window: i32,
    pub scan_type: ScanType,
}

impl ScanSettings {
    fn extract_scan_parameters(self) -> Option<(u16, u16)> {
        let interval = u16::try_from(self.interval);
        if interval.is_err() {
            println!("Invalid scan interval {}", self.interval);
            return None;
        }

        let window = u16::try_from(self.window);
        if window.is_err() {
            println!("Invalid scan window {}", self.window);
            return None;
        }

        return Some((interval.unwrap(), window.unwrap()));
    }
}

/// Represents scan result
#[derive(Debug)]
pub struct ScanResult {
@@ -1313,13 +1331,22 @@ impl GattAsyncIntf {
    ///
    /// Note: this does not need to be async, but declared as async for consistency in this struct.
    /// May be converted into real async in the future if btif supports it.
    async fn update_scan(&mut self) {
    async fn update_scan(&mut self, scanner_id: u8, scan_settings: Option<ScanSettings>) {
        if self.scanners.lock().unwrap().values().find(|scanner| scanner.is_active).is_some() {
            // Toggle the scan off and on so that we reset the scan parameters based on whether
            // we have active scanners using hardware filtering.
            // TODO(b/266752123): We can do more bookkeeping to optimize when we really need to
            // toggle. Also improve toggling API into 1 operation that guarantees correct ordering.
            self.gatt.as_ref().unwrap().lock().unwrap().scanner.stop_scan();
            if let Some(settings) = scan_settings {
                if let Some((scan_interval, scan_window)) = settings.extract_scan_parameters() {
                    self.gatt.as_ref().unwrap().lock().unwrap().scanner.set_scan_parameters(
                        scanner_id,
                        scan_interval,
                        scan_window,
                    );
                }
            }
            self.gatt.as_ref().unwrap().lock().unwrap().scanner.start_scan();
        } else {
            self.gatt.as_ref().unwrap().lock().unwrap().scanner.stop_scan();
@@ -1681,7 +1708,10 @@ impl BluetoothGatt {
                }
            }

            gatt_async.update_scan().await;
            let scan_settings = Self::find_scanner_by_id(&mut scanners.lock().unwrap(), scanner_id)
                .map_or(None, |s| s.scan_settings.clone());

            gatt_async.update_scan(scanner_id, scan_settings).await;
        });

        BtStatus::Success
@@ -1768,22 +1798,13 @@ impl BluetoothGatt {
    /// Start an active scan on given scanner id. This will look up and assign
    /// the correct ScanSettings for it as well.
    pub(crate) fn start_active_scan(&mut self, scanner_id: u8) -> BtStatus {
        let interval: u16 = sysprop::get_i32(sysprop::PropertyI32::LeInquiryScanInterval)
            .try_into()
            .expect("Bad value configured for LeInquiryScanInterval");
        let window: u16 = sysprop::get_i32(sysprop::PropertyI32::LeInquiryScanWindow)
            .try_into()
            .expect("Bad value configured for LeInquiryScanWindow");

        self.gatt
            .as_ref()
            .unwrap()
            .lock()
            .unwrap()
            .scanner
            .set_scan_parameters(scanner_id, interval, window);
        let settings = ScanSettings {
            interval: sysprop::get_i32(sysprop::PropertyI32::LeInquiryScanInterval),
            window: sysprop::get_i32(sysprop::PropertyI32::LeInquiryScanWindow),
            scan_type: ScanType::Active,
        };

        self.start_scan(scanner_id, ScanSettings::default(), /*filter=*/ None)
        self.start_scan(scanner_id, settings, /*filter=*/ None)
    }

    pub(crate) fn stop_active_scan(&mut self, scanner_id: u8) -> BtStatus {
@@ -1817,6 +1838,8 @@ struct ScannerInfo {
    monitor_handle: Option<u8>,
    // Used by start_scan() to determine if it is called because of system resuming.
    is_suspended: bool,
    // The scan parameters to use
    scan_settings: Option<ScanSettings>,
}

impl ScannerInfo {
@@ -1828,6 +1851,7 @@ impl ScannerInfo {
            filter: None,
            monitor_handle: None,
            is_suspended: false,
            scan_settings: None,
        }
    }
}
@@ -1918,6 +1942,16 @@ impl IBluetoothGatt for BluetoothGatt {
            return BtStatus::Busy;
        }

        // We're supposed to directly use the settings provided by the input parameter, but
        // currently UI is sending temporary variables instead. Therefore, load some preset values
        // known to work.
        // TODO(b/217274013): Fix UI plumbing and directly use the provided settings.
        let settings = ScanSettings {
            interval: sysprop::get_i32(sysprop::PropertyI32::LeInquiryScanInterval),
            window: sysprop::get_i32(sysprop::PropertyI32::LeInquiryScanWindow),
            scan_type: ScanType::Active,
        };

        // Multiplexing scanners happens at this layer. The implementations of start_scan
        // and stop_scan maintains the state of all registered scanners and based on the states
        // update the scanning and/or filter states of libbluetooth.
@@ -1927,6 +1961,7 @@ impl IBluetoothGatt for BluetoothGatt {
            if let Some(scanner) = Self::find_scanner_by_id(&mut scanners_lock, scanner_id) {
                scanner.is_active = true;
                scanner.filter = filter.clone();
                scanner.scan_settings = Some(settings);
            } else {
                log::warn!("Scanner {} not found", scanner_id);
                return BtStatus::Fail;
@@ -1987,7 +2022,10 @@ impl IBluetoothGatt for BluetoothGatt {
                }
            }

            gatt_async.update_scan().await;
            let scan_settings = Self::find_scanner_by_id(&mut scanners.lock().unwrap(), scanner_id)
                .map_or(None, |s| s.scan_settings.clone());

            gatt_async.update_scan(scanner_id, scan_settings).await;
        });

        BtStatus::Success