Floss: Define suspend interface for LE Scan
This defines interfaces needed to implement suspend/resume for LE Scan:
* Internal methods `scan_enter_suspend` and `scan_exit_suspend` to be
called by suspend module.
* StartScan and StopScan returning BtStatus to indicate the request
being blocked in suspend mode.
* `SuspendMode` property so that clients can optionally wait for suspend
to be over rather than retrying arbitrarily.
Bug: 224603540
Tag: #floss
Test: Manual - Build Floss on Linux
Change-Id: Iaaa4dc362d30de491616e9279e6a9d9a9fd35812
diff --git a/system/gd/rust/linux/client/src/callbacks.rs b/system/gd/rust/linux/client/src/callbacks.rs
index 09f884f..a57bf8e 100644
--- a/system/gd/rust/linux/client/src/callbacks.rs
+++ b/system/gd/rust/linux/client/src/callbacks.rs
@@ -21,7 +21,7 @@
};
use btstack::suspend::ISuspendCallback;
use btstack::uuid::UuidWrapper;
-use btstack::RPCProxy;
+use btstack::{RPCProxy, SuspendMode};
use dbus::nonblock::SyncConnection;
use dbus_crossroads::Crossroads;
use dbus_projection::DisconnectWatcher;
@@ -327,6 +327,10 @@
print_info!("Scan result: {:#?}", scan_result);
}
}
+
+ fn on_suspend_mode_change(&self, _suspend_mode: SuspendMode) {
+ // No-op, not interesting for btclient.
+ }
}
impl RPCProxy for ScannerCallback {
diff --git a/system/gd/rust/linux/client/src/dbus_iface.rs b/system/gd/rust/linux/client/src/dbus_iface.rs
index 1eaa740..24fa53b 100644
--- a/system/gd/rust/linux/client/src/dbus_iface.rs
+++ b/system/gd/rust/linux/client/src/dbus_iface.rs
@@ -22,7 +22,7 @@
BluetoothServerSocket, BluetoothSocket, CallbackId, IBluetoothSocketManager,
IBluetoothSocketManagerCallbacks, SocketId, SocketResult,
};
-use btstack::RPCProxy;
+use btstack::{RPCProxy, SuspendMode};
use btstack::suspend::{ISuspend, ISuspendCallback, SuspendType};
@@ -68,6 +68,7 @@
impl_dbus_arg_enum!(Profile);
impl_dbus_arg_enum!(ScanType);
impl_dbus_arg_enum!(SocketType);
+impl_dbus_arg_enum!(SuspendMode);
impl_dbus_arg_enum!(SuspendType);
impl_dbus_arg_from_into!(Uuid, Vec<u8>);
@@ -242,6 +243,11 @@
fn on_scan_result(&self, scan_result: ScanResult) {
dbus_generated!()
}
+
+ #[dbus_method("OnSuspendModeChange")]
+ fn on_suspend_mode_change(&self, suspend_mode: SuspendMode) {
+ dbus_generated!()
+ }
}
// Implements RPC-friendly wrapper methods for calling IBluetooth, generated by
@@ -771,12 +777,22 @@
}
#[dbus_method("StartScan")]
- fn start_scan(&mut self, _scanner_id: u8, _settings: ScanSettings, _filters: Vec<ScanFilter>) {
+ fn start_scan(
+ &mut self,
+ _scanner_id: u8,
+ _settings: ScanSettings,
+ _filters: Vec<ScanFilter>,
+ ) -> BtStatus {
dbus_generated!()
}
#[dbus_method("StopScan")]
- fn stop_scan(&mut self, _scanner_id: u8) {
+ fn stop_scan(&mut self, _scanner_id: u8) -> BtStatus {
+ dbus_generated!()
+ }
+
+ #[dbus_method("GetScanSuspendMode")]
+ fn get_scan_suspend_mode(&self) -> SuspendMode {
dbus_generated!()
}
diff --git a/system/gd/rust/linux/service/src/iface_bluetooth_gatt.rs b/system/gd/rust/linux/service/src/iface_bluetooth_gatt.rs
index 2b8ba57..0f4db89 100644
--- a/system/gd/rust/linux/service/src/iface_bluetooth_gatt.rs
+++ b/system/gd/rust/linux/service/src/iface_bluetooth_gatt.rs
@@ -1,4 +1,6 @@
-use bt_topshim::{btif::Uuid128Bit, profiles::gatt::GattStatus};
+use bt_topshim::profiles::gatt::GattStatus;
+
+use bt_topshim::btif::{BtStatus, Uuid128Bit};
use btstack::bluetooth_adv::{
AdvertiseData, AdvertisingSetParameters, IAdvertisingSetCallback, PeriodicAdvertisingParameters,
@@ -8,7 +10,7 @@
GattWriteRequestStatus, GattWriteType, IBluetoothGatt, IBluetoothGattCallback,
IScannerCallback, LePhy, RSSISettings, ScanFilter, ScanResult, ScanSettings, ScanType,
};
-use btstack::RPCProxy;
+use btstack::{RPCProxy, SuspendMode};
use dbus::arg::RefArg;
@@ -165,6 +167,11 @@
fn on_scan_result(&self, scan_result: ScanResult) {
dbus_generated!()
}
+
+ #[dbus_method("OnSuspendModeChange")]
+ fn on_suspend_mode_change(&self, suspend_mode: SuspendMode) {
+ dbus_generated!()
+ }
}
#[dbus_propmap(BluetoothGattDescriptor)]
@@ -227,6 +234,7 @@
impl_dbus_arg_enum!(GattWriteType);
impl_dbus_arg_enum!(LePhy);
impl_dbus_arg_enum!(ScanType);
+impl_dbus_arg_enum!(SuspendMode);
#[dbus_propmap(ScanFilter)]
struct ScanFilterDBus {}
@@ -362,12 +370,22 @@
}
#[dbus_method("StartScan")]
- fn start_scan(&mut self, scanner_id: u8, settings: ScanSettings, filters: Vec<ScanFilter>) {
+ fn start_scan(
+ &mut self,
+ scanner_id: u8,
+ settings: ScanSettings,
+ filters: Vec<ScanFilter>,
+ ) -> BtStatus {
dbus_generated!()
}
#[dbus_method("StopScan")]
- fn stop_scan(&mut self, scanner_id: u8) {
+ fn stop_scan(&mut self, scanner_id: u8) -> BtStatus {
+ dbus_generated!()
+ }
+
+ #[dbus_method("GetScanSuspendMode")]
+ fn get_scan_suspend_mode(&self) -> SuspendMode {
dbus_generated!()
}
diff --git a/system/gd/rust/linux/stack/src/bluetooth_gatt.rs b/system/gd/rust/linux/stack/src/bluetooth_gatt.rs
index a382783..6a08e8f 100644
--- a/system/gd/rust/linux/stack/src/bluetooth_gatt.rs
+++ b/system/gd/rust/linux/stack/src/bluetooth_gatt.rs
@@ -3,7 +3,7 @@
use btif_macros::{btif_callback, btif_callbacks_dispatcher};
use bt_topshim::bindings::root::bluetooth::Uuid;
-use bt_topshim::btif::{BluetoothInterface, RawAddress, Uuid128Bit};
+use bt_topshim::btif::{BluetoothInterface, BtStatus, RawAddress, Uuid128Bit};
use bt_topshim::profiles::gatt::{
BtGattDbElement, BtGattNotifyParams, BtGattReadParams, Gatt, GattAdvCallbacks,
GattAdvCallbacksDispatcher, GattAdvInbandCallbacksDispatcher, GattClientCallbacks,
@@ -20,7 +20,7 @@
};
use crate::callbacks::Callbacks;
use crate::uuid::parse_uuid_string;
-use crate::{Message, RPCProxy};
+use crate::{Message, RPCProxy, SuspendMode};
use log::{debug, warn};
use num_traits::cast::{FromPrimitive, ToPrimitive};
use num_traits::clamp;
@@ -169,10 +169,18 @@
fn unregister_scanner(&mut self, scanner_id: u8) -> bool;
/// Activate scan of the given scanner id.
- fn start_scan(&mut self, scanner_id: u8, settings: ScanSettings, filters: Vec<ScanFilter>);
+ fn start_scan(
+ &mut self,
+ scanner_id: u8,
+ settings: ScanSettings,
+ filters: Vec<ScanFilter>,
+ ) -> BtStatus;
/// Deactivate scan of the given scanner id.
- fn stop_scan(&mut self, scanner_id: u8);
+ fn stop_scan(&mut self, scanner_id: u8) -> BtStatus;
+
+ /// Returns the current suspend mode.
+ fn get_scan_suspend_mode(&self) -> SuspendMode;
// Advertising
@@ -533,6 +541,9 @@
/// shared among all scanner callbacks, clients may receive more advertisements than what is
/// requested to be filtered in.
fn on_scan_result(&self, scan_result: ScanResult);
+
+ /// When LE Scan module changes suspend mode due to system suspend/resume.
+ fn on_suspend_mode_change(&self, suspend_mode: SuspendMode);
}
#[derive(Debug, FromPrimitive, ToPrimitive)]
@@ -749,6 +760,26 @@
self.scanner_callbacks.remove_callback(callback_id)
}
+ /// Enters suspend mode for LE Scan.
+ ///
+ /// This "pauses" all operations managed by this module to prepare for system suspend. A
+ /// callback is triggered to let clients know that this module is in suspend mode and some
+ /// subsequent API calls will be blocked in this mode.
+ pub fn scan_enter_suspend(&mut self) {
+ // TODO(b/224603540): Implement
+ todo!()
+ }
+
+ /// Exits suspend mode for LE Scan.
+ ///
+ /// To be called after system resume/wake up. This "unpauses" the operations that were "paused"
+ /// due to suspend. A callback is triggered to let clients when this module has exited suspend
+ /// mode.
+ pub fn scan_exit_suspend(&mut self) {
+ // TODO(b/224603540): Implement
+ todo!()
+ }
+
// Update the topshim's scan state depending on the states of registered scanners. Scan is
// enabled if there is at least 1 active registered scanner.
fn update_scan(&mut self) {
@@ -834,7 +865,12 @@
true
}
- fn start_scan(&mut self, scanner_id: u8, _settings: ScanSettings, _filters: Vec<ScanFilter>) {
+ fn start_scan(
+ &mut self,
+ scanner_id: u8,
+ _settings: ScanSettings,
+ _filters: Vec<ScanFilter>,
+ ) -> BtStatus {
// 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.
@@ -843,21 +879,29 @@
scanner.is_active = true;
} else {
log::warn!("Scanner {} not found", scanner_id);
- return;
+ return BtStatus::Fail;
}
self.update_scan();
+ BtStatus::Success
}
- fn stop_scan(&mut self, scanner_id: u8) {
+ fn stop_scan(&mut self, scanner_id: u8) -> BtStatus {
if let Some(scanner) = self.find_scanner_by_id(scanner_id) {
scanner.is_active = false;
} else {
log::warn!("Scanner {} not found", scanner_id);
- return;
+ // Clients can assume success of the removal since the scanner does not exist.
+ return BtStatus::Success;
}
self.update_scan();
+ BtStatus::Success
+ }
+
+ fn get_scan_suspend_mode(&self) -> SuspendMode {
+ // TODO(b/224603540): Implement.
+ return SuspendMode::Normal;
}
// Advertising
diff --git a/system/gd/rust/linux/stack/src/lib.rs b/system/gd/rust/linux/stack/src/lib.rs
index e9ffbea..56abe76 100644
--- a/system/gd/rust/linux/stack/src/lib.rs
+++ b/system/gd/rust/linux/stack/src/lib.rs
@@ -78,6 +78,18 @@
SocketManagerCallbackDisconnected(u32),
}
+/// Represents suspend mode of a module.
+///
+/// Being in suspend mode means that the module pauses some activities if required for suspend and
+/// some subsequent API calls will be blocked with a retryable error.
+#[derive(FromPrimitive, ToPrimitive)]
+pub enum SuspendMode {
+ Normal = 0,
+ Suspending = 1,
+ Suspended = 2,
+ Resuming = 3,
+}
+
/// Umbrella class for the Bluetooth stack.
pub struct Stack {}