From d2a2927ea5057c3b9d3c07a40ab453d488c54dcf Mon Sep 17 00:00:00 2001 From: Martin Brabham <optedoblivion@google.com> Date: Wed, 12 Oct 2022 19:46:33 +0000 Subject: [PATCH] Fix suspend/resume synchronization Bug: 189495534 Test: system/gd/cert/run --clean --topshim SuspendTest Tag: #floss Change-Id: I159a721786863fb5bebe8d7165808efeb287136b --- system/bta/dm/bta_dm_api.cc | 42 +++++++ system/bta/include/bta_api.h | 33 ++++++ system/btif/src/btif_dm.cc | 10 +- system/gd/rust/linux/client/src/callbacks.rs | 2 +- system/gd/rust/linux/client/src/dbus_iface.rs | 6 +- system/gd/rust/linux/mgmt/src/dbus_iface.rs | 6 +- .../linux/mgmt/src/powerd_suspend_manager.rs | 17 +-- .../rust/linux/service/src/iface_bluetooth.rs | 6 +- system/gd/rust/linux/stack/src/lib.rs | 7 +- system/gd/rust/linux/stack/src/suspend.rs | 109 ++++++++++++------ system/main/shim/acl.cc | 44 +++++++ system/main/shim/acl.h | 6 + system/main/shim/btm_api.cc | 5 +- system/stack/include/hci_error_code.h | 1 + 14 files changed, 236 insertions(+), 58 deletions(-) diff --git a/system/bta/dm/bta_dm_api.cc b/system/bta/dm/bta_dm_api.cc index 01b497c367d..6be4aba7f9c 100644 --- a/system/bta/dm/bta_dm_api.cc +++ b/system/bta/dm/bta_dm_api.cc @@ -676,6 +676,34 @@ void BTA_DmClearEventFilter(void) { do_in_main_thread(FROM_HERE, base::Bind(bta_dm_clear_event_filter)); } +/******************************************************************************* + * + * Function BTA_DmClearEventMask + * + * Description This function clears the event mask + * + * Returns void + * + ******************************************************************************/ +void BTA_DmClearEventMask(void) { + APPL_TRACE_API("BTA_DmClearEventMask"); + do_in_main_thread(FROM_HERE, base::Bind(bta_dm_clear_event_mask)); +} + +/******************************************************************************* + * + * Function BTA_DmClearEventMask + * + * Description This function clears the filter accept list + * + * Returns void + * + ******************************************************************************/ +void BTA_DmClearFilterAcceptList(void) { + APPL_TRACE_API("BTA_DmClearFilterAcceptList"); + do_in_main_thread(FROM_HERE, base::Bind(bta_dm_clear_filter_accept_list)); +} + /******************************************************************************* * * Function BTA_DmLeRand @@ -690,6 +718,20 @@ void BTA_DmLeRand(LeRandCallback cb) { do_in_main_thread(FROM_HERE, base::Bind(bta_dm_le_rand, cb)); } +/******************************************************************************* + * + * Function BTA_DmDisconnectAllAcls + * + * Description This function will disconnect all LE and Classic ACLs. + * + * Returns void + * + ******************************************************************************/ +void BTA_DmDisconnectAllAcls() { + APPL_TRACE_API("BTA_DmLeRand"); + do_in_main_thread(FROM_HERE, base::Bind(bta_dm_disconnect_all_acls)); +} + void BTA_DmSetEventFilterConnectionSetupAllDevices() { APPL_TRACE_API("BTA_DmSetEventFilterConnectionSetupAllDevices"); do_in_main_thread( diff --git a/system/bta/include/bta_api.h b/system/bta/include/bta_api.h index f7cad22c537..58c4c28551a 100644 --- a/system/bta/include/bta_api.h +++ b/system/bta/include/bta_api.h @@ -1222,6 +1222,39 @@ extern void BTA_VendorInit(void); ******************************************************************************/ extern void BTA_DmClearEventFilter(void); +/******************************************************************************* + * + * Function BTA_DmClearEventMask + * + * Description This function clears the event mask + * + * Returns void + * + ******************************************************************************/ +extern void BTA_DmClearEventMask(void); + +/******************************************************************************* + * + * Function BTA_DmDisconnectAllAcls + * + * Description This function will disconnect all LE and Classic ACLs. + * + * Returns void + * + ******************************************************************************/ +extern void BTA_DmDisconnectAllAcls(void); + +/******************************************************************************* + * + * Function BTA_DmClearFilterAcceptList + * + * Description This function clears the filter accept list + * + * Returns void + * + ******************************************************************************/ +extern void BTA_DmClearFilterAcceptList(void); + using LeRandCallback = base::Callback<void(uint64_t)>; /******************************************************************************* * diff --git a/system/btif/src/btif_dm.cc b/system/btif/src/btif_dm.cc index 6362729c58c..9b6e1d04e8c 100644 --- a/system/btif/src/btif_dm.cc +++ b/system/btif/src/btif_dm.cc @@ -3521,27 +3521,27 @@ bool btif_get_address_type(const RawAddress& bda, tBLE_ADDR_TYPE* p_addr_type) { void btif_dm_clear_event_filter() { LOG_VERBOSE("%s: called", __func__); - bta_dm_clear_event_filter(); + BTA_DmClearEventFilter(); } void btif_dm_clear_event_mask() { LOG_VERBOSE("%s: called", __func__); - bta_dm_clear_event_mask(); + BTA_DmClearEventMask(); } void btif_dm_clear_filter_accept_list() { LOG_VERBOSE("%s: called", __func__); - bta_dm_clear_filter_accept_list(); + BTA_DmClearFilterAcceptList(); } void btif_dm_disconnect_all_acls() { LOG_VERBOSE("%s: called", __func__); - bta_dm_disconnect_all_acls(); + BTA_DmDisconnectAllAcls(); } void btif_dm_le_rand(LeRandCallback callback) { LOG_VERBOSE("%s: called", __func__); - bta_dm_le_rand(callback); + BTA_DmLeRand(callback); } void btif_dm_set_event_filter_connection_setup_all_devices() { diff --git a/system/gd/rust/linux/client/src/callbacks.rs b/system/gd/rust/linux/client/src/callbacks.rs index cc5d9840faa..003b68dfa8b 100644 --- a/system/gd/rust/linux/client/src/callbacks.rs +++ b/system/gd/rust/linux/client/src/callbacks.rs @@ -797,7 +797,7 @@ impl SuspendCallback { impl ISuspendCallback for SuspendCallback { // TODO(b/224606285): Implement suspend utils in btclient. fn on_callback_registered(&self, _callback_id: u32) {} - fn on_suspend_ready(&self, _suspend_id: u32) {} + fn on_suspend_ready(&self, _suspend_id: i32) {} fn on_resumed(&self, _suspend_id: i32) {} } diff --git a/system/gd/rust/linux/client/src/dbus_iface.rs b/system/gd/rust/linux/client/src/dbus_iface.rs index ef4d62a6262..03cac4de477 100644 --- a/system/gd/rust/linux/client/src/dbus_iface.rs +++ b/system/gd/rust/linux/client/src/dbus_iface.rs @@ -1453,12 +1453,12 @@ impl ISuspend for SuspendDBus { } #[dbus_method("Suspend")] - fn suspend(&mut self, _suspend_type: SuspendType) { + fn suspend(&mut self, _suspend_type: SuspendType, suspend_id: i32) { dbus_generated!() } #[dbus_method("Resume")] - fn resume(&self) -> bool { + fn resume(&mut self) -> bool { dbus_generated!() } } @@ -1475,7 +1475,7 @@ impl ISuspendCallback for ISuspendCallbackDBus { #[dbus_method("OnCallbackRegistered")] fn on_callback_registered(&self, callback_id: u32) {} #[dbus_method("OnSuspendReady")] - fn on_suspend_ready(&self, suspend_id: u32) {} + fn on_suspend_ready(&self, suspend_id: i32) {} #[dbus_method("OnResumed")] fn on_resumed(&self, suspend_id: i32) {} } diff --git a/system/gd/rust/linux/mgmt/src/dbus_iface.rs b/system/gd/rust/linux/mgmt/src/dbus_iface.rs index 95ce28e0387..1dbe461c0d5 100644 --- a/system/gd/rust/linux/mgmt/src/dbus_iface.rs +++ b/system/gd/rust/linux/mgmt/src/dbus_iface.rs @@ -55,12 +55,12 @@ impl ISuspend for SuspendDBus { } #[dbus_method("Suspend")] - fn suspend(&mut self, _suspend_type: SuspendType) { + fn suspend(&mut self, _suspend_type: SuspendType, suspend_id: i32) { dbus_generated!() } #[dbus_method("Resume")] - fn resume(&self) -> bool { + fn resume(&mut self) -> bool { dbus_generated!() } } @@ -78,7 +78,7 @@ impl ISuspendCallback for ISuspendCallbackDBus { #[dbus_method("OnCallbackRegistered")] fn on_callback_registered(&self, callback_id: u32) {} #[dbus_method("OnSuspendReady")] - fn on_suspend_ready(&self, suspend_id: u32) {} + fn on_suspend_ready(&self, suspend_id: i32) {} #[dbus_method("OnResumed")] fn on_resumed(&self, suspend_id: i32) {} } diff --git a/system/gd/rust/linux/mgmt/src/powerd_suspend_manager.rs b/system/gd/rust/linux/mgmt/src/powerd_suspend_manager.rs index cbddb9c38c2..4f8acb06e45 100644 --- a/system/gd/rust/linux/mgmt/src/powerd_suspend_manager.rs +++ b/system/gd/rust/linux/mgmt/src/powerd_suspend_manager.rs @@ -115,7 +115,7 @@ impl ISuspendCallback for SuspendCallback { log::debug!("Suspend callback registered, callback_id = {}", callback_id); } - fn on_suspend_ready(&self, suspend_id: u32) { + fn on_suspend_ready(&self, suspend_id: i32) { // Received when adapter is ready to suspend. Tell powerd that suspend is ready. log::debug!("Suspend ready, adapter suspend_id = {}", suspend_id); @@ -446,11 +446,14 @@ impl PowerdSuspendManager { let mut suspend_dbus_rpc = adapter_suspend_dbus.rpc.clone(); tokio::spawn(async move { let result = suspend_dbus_rpc - .suspend(match suspend_imminent.get_reason() { - SuspendImminent_Reason::IDLE => SuspendType::AllowWakeFromHid, - SuspendImminent_Reason::LID_CLOSED => SuspendType::NoWakesAllowed, - SuspendImminent_Reason::OTHER => SuspendType::Other, - }) + .suspend( + match suspend_imminent.get_reason() { + SuspendImminent_Reason::IDLE => SuspendType::AllowWakeFromHid, + SuspendImminent_Reason::LID_CLOSED => SuspendType::NoWakesAllowed, + SuspendImminent_Reason::OTHER => SuspendType::Other, + }, + suspend_imminent.get_suspend_id(), + ) .await; log::debug!("Adapter suspend call, success = {}", result.is_ok()); @@ -485,7 +488,7 @@ impl PowerdSuspendManager { self.context.lock().unwrap().pending_suspend_imminent = None; if let Some(adapter_suspend_dbus) = &self.context.lock().unwrap().adapter_suspend_dbus { - let suspend_dbus_rpc = adapter_suspend_dbus.rpc.clone(); + let mut suspend_dbus_rpc = adapter_suspend_dbus.rpc.clone(); tokio::spawn(async move { let result = suspend_dbus_rpc.resume().await; log::debug!("Adapter resume call, success = {}", result.unwrap_or(false)); diff --git a/system/gd/rust/linux/service/src/iface_bluetooth.rs b/system/gd/rust/linux/service/src/iface_bluetooth.rs index 4cd8237e71c..58104315840 100644 --- a/system/gd/rust/linux/service/src/iface_bluetooth.rs +++ b/system/gd/rust/linux/service/src/iface_bluetooth.rs @@ -564,12 +564,12 @@ impl ISuspend for ISuspendDBus { } #[dbus_method("Suspend")] - fn suspend(&mut self, suspend_type: SuspendType) { + fn suspend(&mut self, suspend_type: SuspendType, suspend_id: i32) { dbus_generated!() } #[dbus_method("Resume")] - fn resume(&self) -> bool { + fn resume(&mut self) -> bool { dbus_generated!() } } @@ -584,7 +584,7 @@ impl ISuspendCallback for SuspendCallbackDBus { dbus_generated!() } #[dbus_method("OnSuspendReady")] - fn on_suspend_ready(&self, suspend_id: u32) { + fn on_suspend_ready(&self, suspend_id: i32) { dbus_generated!() } #[dbus_method("OnResumed")] diff --git a/system/gd/rust/linux/stack/src/lib.rs b/system/gd/rust/linux/stack/src/lib.rs index 92074482780..50b34be6197 100644 --- a/system/gd/rust/linux/stack/src/lib.rs +++ b/system/gd/rust/linux/stack/src/lib.rs @@ -79,7 +79,8 @@ pub enum Message { // Suspend related SuspendCallbackRegistered(u32), SuspendCallbackDisconnected(u32), - SuspendReady(u32), + SuspendReady(i32), + ResumeReady(i32), // Scanner related ScannerCallbackDisconnected(u32), @@ -228,6 +229,10 @@ impl Stack { suspend.lock().unwrap().suspend_ready(suspend_id); } + Message::ResumeReady(suspend_id) => { + suspend.lock().unwrap().resume_ready(suspend_id); + } + Message::ScannerCallbackDisconnected(id) => { bluetooth_gatt.lock().unwrap().remove_scanner_callback(id); } diff --git a/system/gd/rust/linux/stack/src/suspend.rs b/system/gd/rust/linux/stack/src/suspend.rs index a12c399674e..a85c18f308a 100644 --- a/system/gd/rust/linux/stack/src/suspend.rs +++ b/system/gd/rust/linux/stack/src/suspend.rs @@ -29,12 +29,12 @@ pub trait ISuspend { /// /// Returns a positive number identifying the suspend if it can be started. If there is already /// a suspend, that active suspend id is returned. - fn suspend(&mut self, suspend_type: SuspendType); + fn suspend(&mut self, suspend_type: SuspendType, suspend_id: i32); /// Undoes previous suspend preparation identified by `suspend_id`. /// /// Returns true if suspend can be resumed, and false if there is no suspend to resume. - fn resume(&self) -> bool; + fn resume(&mut self) -> bool; } /// Suspend events. @@ -43,7 +43,7 @@ pub trait ISuspendCallback: RPCProxy { fn on_callback_registered(&self, callback_id: u32); /// Triggered when the stack is ready for suspend and tell the observer the id of the suspend. - fn on_suspend_ready(&self, suspend_id: u32); + fn on_suspend_ready(&self, suspend_id: i32); /// Triggered when the stack has resumed the previous suspend. fn on_resumed(&self, suspend_id: i32); @@ -59,6 +59,20 @@ pub enum SuspendType { struct SuspendState { le_rand_expected: bool, + suspend_expected: bool, + resume_expected: bool, + suspend_id: Option<i32>, +} + +impl SuspendState { + pub fn new() -> SuspendState { + Self { + le_rand_expected: false, + suspend_expected: false, + resume_expected: false, + suspend_id: None, + } + } } /// Implementation of the suspend API. @@ -90,7 +104,7 @@ impl Suspend { is_connected_suspend: false, was_a2dp_connected: false, suspend_timeout_joinhandle: None, - suspend_state: Arc::new(Mutex::new(SuspendState { le_rand_expected: false })), + suspend_state: Arc::new(Mutex::new(SuspendState::new())), } } @@ -105,11 +119,17 @@ impl Suspend { self.callbacks.remove_callback(id) } - pub(crate) fn suspend_ready(&self, suspend_id: u32) { + pub(crate) fn suspend_ready(&self, suspend_id: i32) { self.callbacks.for_all_callbacks(|callback| { callback.on_suspend_ready(suspend_id); }); } + + pub(crate) fn resume_ready(&self, suspend_id: i32) { + self.callbacks.for_all_callbacks(|callback| { + callback.on_resumed(suspend_id); + }); + } } impl ISuspend for Suspend { @@ -128,37 +148,30 @@ impl ISuspend for Suspend { self.remove_callback(callback_id) } - fn suspend(&mut self, suspend_type: SuspendType) { - // self.was_a2dp_connected = TODO(230604670): check if A2DP is connected - // self.current_advertiser_ids = TODO(224603198): save all advertiser ids + fn suspend(&mut self, suspend_type: SuspendType, suspend_id: i32) { self.intf.lock().unwrap().clear_event_mask(); self.intf.lock().unwrap().clear_event_filter(); self.intf.lock().unwrap().clear_filter_accept_list(); - // self.gatt.lock().unwrap().advertising_disable(); TODO(224602924): suspend all adv. + // TODO(224602924): How do we get the advertising ids? + self.gatt.lock().unwrap().stop_advertising_set(0); + // TODO(224602924): How do we get the scanning ids? self.gatt.lock().unwrap().stop_scan(0); self.intf.lock().unwrap().disconnect_all_acls(); // Handle wakeful cases (Connected/Other) // Treat Other the same as Connected match suspend_type { - SuspendType::AllowWakeFromHid => { - // TODO(231345733): API For allowing classic HID only - // TODO(230604670): check if A2DP is connected - // TODO(224603198): save all advertiser information - } - SuspendType::NoWakesAllowed => { - self.intf.lock().unwrap().clear_event_filter(); - self.intf.lock().unwrap().clear_event_mask(); - } - _ => { + SuspendType::AllowWakeFromHid | SuspendType::Other => { self.intf.lock().unwrap().allow_wake_by_hid(); + // self.was_a2dp_connected = TODO(230604670): check if A2DP is connected + // TODO(230604670): check if A2DP is connected } + _ => {} } - self.intf.lock().unwrap().clear_filter_accept_list(); - self.intf.lock().unwrap().disconnect_all_acls(); - - self.bt.lock().unwrap().le_rand(); self.suspend_state.lock().unwrap().le_rand_expected = true; + self.suspend_state.lock().unwrap().suspend_expected = true; + self.suspend_state.lock().unwrap().suspend_id = Some(suspend_id); + self.bt.lock().unwrap().le_rand(); if let Some(join_handle) = &self.suspend_timeout_joinhandle { join_handle.abort(); @@ -172,27 +185,42 @@ impl ISuspend for Suspend { log::error!("Suspend did not complete in 2 seconds, continuing anyway."); suspend_state.lock().unwrap().le_rand_expected = false; + suspend_state.lock().unwrap().suspend_expected = false; + suspend_state.lock().unwrap().suspend_id = None; tokio::spawn(async move { - let _result = tx.send(Message::SuspendReady(1)).await; + let _result = tx.send(Message::SuspendReady(suspend_id)).await; }); })); } - fn resume(&self) -> bool { + fn resume(&mut self) -> bool { self.intf.lock().unwrap().set_default_event_mask(); self.intf.lock().unwrap().set_event_filter_inquiry_result_all_devices(); self.intf.lock().unwrap().set_event_filter_connection_setup_all_devices(); if self.is_connected_suspend { if self.was_a2dp_connected { - // TODO(230604670): self.intf.lock().unwrap().restore_filter_accept_list(); // TODO(230604670): reconnect to a2dp device } // TODO(224603198): start all advertising again } - self.callbacks.for_all_callbacks(|callback| { - callback.on_resumed(1); - }); + self.suspend_state.lock().unwrap().le_rand_expected = true; + self.suspend_state.lock().unwrap().resume_expected = true; + self.bt.lock().unwrap().le_rand(); + + let tx = self.tx.clone(); + let suspend_state = self.suspend_state.clone(); + let suspend_id = self.suspend_state.lock().unwrap().suspend_id.unwrap(); + self.suspend_timeout_joinhandle = Some(tokio::spawn(async move { + tokio::time::sleep(tokio::time::Duration::from_millis(2000)).await; + log::error!("Resume did not complete in 2 seconds, continuing anyway."); + + suspend_state.lock().unwrap().le_rand_expected = false; + suspend_state.lock().unwrap().resume_expected = false; + tokio::spawn(async move { + let _result = tx.send(Message::ResumeReady(suspend_id)).await; + }); + })); true } @@ -206,15 +234,30 @@ impl BtifBluetoothCallbacks for Suspend { log::warn!("Unexpected LE Rand callback, ignoring."); return; } + self.suspend_state.lock().unwrap().le_rand_expected = false; if let Some(join_handle) = &self.suspend_timeout_joinhandle { join_handle.abort(); self.suspend_timeout_joinhandle = None; } - let tx = self.tx.clone(); - tokio::spawn(async move { - let _result = tx.send(Message::SuspendReady(1)).await; - }); + let suspend_id = self.suspend_state.lock().unwrap().suspend_id.unwrap(); + + if self.suspend_state.lock().unwrap().suspend_expected { + self.suspend_state.lock().unwrap().suspend_expected = false; + let tx = self.tx.clone(); + tokio::spawn(async move { + let _result = tx.send(Message::SuspendReady(suspend_id)).await; + }); + } + + self.suspend_state.lock().unwrap().suspend_id = Some(suspend_id); + if self.suspend_state.lock().unwrap().resume_expected { + self.suspend_state.lock().unwrap().resume_expected = false; + let tx = self.tx.clone(); + tokio::spawn(async move { + let _result = tx.send(Message::ResumeReady(suspend_id)).await; + }); + } } } diff --git a/system/main/shim/acl.cc b/system/main/shim/acl.cc index b23fde01468..58f9b3200f0 100644 --- a/system/main/shim/acl.cc +++ b/system/main/shim/acl.cc @@ -840,6 +840,15 @@ struct shim::legacy::Acl::impl { handle_to_le_connection_map_[handle]->EnqueuePacket(std::move(packet)); } + void DisconnectClassicConnections(std::promise<void> promise) { + LOG_INFO("Disconnect gd acl shim classic connections"); + for (auto& connection : handle_to_classic_connection_map_) { + disconnect_classic(connection.first, HCI_ERR_REMOTE_POWER_OFF, + "Suspend disconnect"); + } + promise.set_value(); + } + void ShutdownClassicConnections(std::promise<void> promise) { LOG_INFO("Shutdown gd acl shim classic connections"); for (auto& connection : handle_to_classic_connection_map_) { @@ -849,6 +858,15 @@ struct shim::legacy::Acl::impl { promise.set_value(); } + void DisconnectLeConnections(std::promise<void> promise) { + LOG_INFO("Disconnect gd acl shim le connections"); + for (auto& connection : handle_to_le_connection_map_) { + disconnect_le(connection.first, HCI_ERR_REMOTE_POWER_OFF, + "Suspend disconnect"); + } + promise.set_value(); + } + void ShutdownLeConnections(std::promise<void> promise) { LOG_INFO("Shutdown gd acl shim le connections"); for (auto& connection : handle_to_le_connection_map_) { @@ -995,6 +1013,10 @@ struct shim::legacy::Acl::impl { LOG_DEBUG("Cleared entire Le address acceptlist count:%zu", count); } + void le_rand(LeRandCallback cb ) { + controller_get_interface()->le_rand(cb); + } + void AddToAddressResolution(const hci::AddressWithType& address_with_type, const std::array<uint8_t, 16>& peer_irk, const std::array<uint8_t, 16>& local_irk) { @@ -1650,6 +1672,24 @@ void shim::legacy::Acl::DumpConnectionHistory(int fd) const { pimpl_->DumpConnectionHistory(fd); } +void shim::legacy::Acl::DisconnectAllForSuspend() { + if (CheckForOrphanedAclConnections()) { + std::promise<void> disconnect_promise; + auto disconnect_future = disconnect_promise.get_future(); + handler_->CallOn(pimpl_.get(), &Acl::impl::DisconnectClassicConnections, + std::move(disconnect_promise)); + disconnect_future.wait(); + + disconnect_promise = std::promise<void>(); + + disconnect_future = disconnect_promise.get_future(); + handler_->CallOn(pimpl_.get(), &Acl::impl::DisconnectLeConnections, + std::move(disconnect_promise)); + disconnect_future.wait(); + LOG_WARN("Disconnected open ACL connections"); + } +} + void shim::legacy::Acl::Shutdown() { if (CheckForOrphanedAclConnections()) { std::promise<void> shutdown_promise; @@ -1694,6 +1734,10 @@ void shim::legacy::Acl::ClearFilterAcceptList() { handler_->CallOn(pimpl_.get(), &Acl::impl::clear_acceptlist); } +void shim::legacy::Acl::LeRand(LeRandCallback cb) { + handler_->CallOn(pimpl_.get(), &Acl::impl::le_rand, cb); +} + void shim::legacy::Acl::AddToAddressResolution( const hci::AddressWithType& address_with_type, const std::array<uint8_t, 16>& peer_irk, diff --git a/system/main/shim/acl.h b/system/main/shim/acl.h index 53ae43eac66..a4ede403548 100644 --- a/system/main/shim/acl.h +++ b/system/main/shim/acl.h @@ -32,6 +32,8 @@ #include "stack/include/bt_types.h" #include "types/raw_address.h" +using LeRandCallback = base::Callback<void(uint64_t)>; + namespace bluetooth { namespace shim { namespace legacy { @@ -106,14 +108,18 @@ class Acl : public hci::acl_manager::ConnectionCallbacks, void Dump(int fd) const; void DumpConnectionHistory(int fd) const; + void DisconnectAllForSuspend(); void Shutdown(); void FinalShutdown(); + void LeRand(LeRandCallback cb); void ClearFilterAcceptList(); void AddDeviceToFilterAcceptList( const hci::AddressWithType& address_with_type); + void ClearEventFilter(); + protected: void on_incoming_acl_credits(uint16_t handle, uint16_t credits); void write_data_sync(uint16_t hci_handle, diff --git a/system/main/shim/btm_api.cc b/system/main/shim/btm_api.cc index 720e9d5e81d..ef1f2378028 100644 --- a/system/main/shim/btm_api.cc +++ b/system/main/shim/btm_api.cc @@ -1349,12 +1349,13 @@ tBTM_STATUS bluetooth::shim::BTM_ClearFilterAcceptList() { } tBTM_STATUS bluetooth::shim::BTM_DisconnectAllAcls() { - Stack::GetInstance()->GetAcl()->Shutdown(); + Stack::GetInstance()->GetAcl()->DisconnectAllForSuspend(); +// Stack::GetInstance()->GetAcl()->Shutdown(); return BTM_SUCCESS; } tBTM_STATUS bluetooth::shim::BTM_LeRand(LeRandCallback cb) { - controller_get_interface()->le_rand(cb); + Stack::GetInstance()->GetAcl()->LeRand(cb); return BTM_SUCCESS; } diff --git a/system/stack/include/hci_error_code.h b/system/stack/include/hci_error_code.h index bbff6a61c25..c2abb8d340d 100644 --- a/system/stack/include/hci_error_code.h +++ b/system/stack/include/hci_error_code.h @@ -44,6 +44,7 @@ typedef enum : uint8_t { HCI_ERR_HOST_TIMEOUT = 0x10, // stack/btm/btm_ble_gap, HCI_ERR_ILLEGAL_PARAMETER_FMT = 0x12, HCI_ERR_PEER_USER = 0x13, + HCI_ERR_REMOTE_POWER_OFF = 0x15, HCI_ERR_CONN_CAUSE_LOCAL_HOST = 0x16, HCI_ERR_REPEATED_ATTEMPTS = 0x17, HCI_ERR_PAIRING_NOT_ALLOWED = 0x18, -- GitLab