Loading system/gd/rust/linux/service/src/main.rs +25 −5 Original line number Diff line number Diff line Loading @@ -20,7 +20,7 @@ use btstack::{ battery_manager::BatteryManager, battery_provider_manager::BatteryProviderManager, battery_service::BatteryService, bluetooth::{Bluetooth, IBluetooth}, bluetooth::{Bluetooth, IBluetooth, SigData}, bluetooth_admin::BluetoothAdmin, bluetooth_gatt::BluetoothGatt, bluetooth_logging::BluetoothLogging, Loading Loading @@ -49,6 +49,8 @@ const ADMIN_SETTINGS_FILE_PATH: &str = "/var/lib/bluetooth/admin_policy.json"; // The maximum ACL disconnect timeout is 3.5s defined by BTA_DM_DISABLE_TIMER_MS // and BTA_DM_DISABLE_TIMER_RETRIAL_MS const STACK_TURN_OFF_TIMEOUT_MS: Duration = Duration::from_millis(4000); // Time bt_stack_manager waits for cleanup const STACK_CLEANUP_TIMEOUT_MS: Duration = Duration::from_millis(1000); const VERBOSE_ONLY_LOG_TAGS: &[&str] = &[ "bt_bta_av", // AV apis Loading Loading @@ -135,7 +137,12 @@ fn main() -> Result<(), Box<dyn Error>> { init_flags.push(String::from("INIT_classic_discovery_only=true")); let (tx, rx) = Stack::create_channel(); let sig_notifier = Arc::new((Mutex::new(false), Condvar::new())); let sig_notifier = Arc::new(SigData { enabled: Mutex::new(false), enabled_notify: Condvar::new(), thread_attached: Mutex::new(false), thread_notify: Condvar::new(), }); let intf = Arc::new(Mutex::new(get_btinterface().unwrap())); let bluetooth_gatt = Loading Loading @@ -424,7 +431,7 @@ fn main() -> Result<(), Box<dyn Error>> { lazy_static! { /// Data needed for signal handling. static ref SIG_DATA: Mutex<Option<(Sender<Message>, Arc<(Mutex<bool>, Condvar)>)>> = Mutex::new(None); static ref SIG_DATA: Mutex<Option<(Sender<Message>, Arc<(SigData)>)>> = Mutex::new(None); } extern "C" fn handle_sigterm(_signum: i32) { Loading @@ -437,10 +444,23 @@ extern "C" fn handle_sigterm(_signum: i32) { let _ = txl.send(Message::Shutdown).await; }); let guard = notifier.0.lock().unwrap(); let guard = notifier.enabled.lock().unwrap(); if *guard { log::debug!("Waiting for stack to turn off for {:?}", STACK_TURN_OFF_TIMEOUT_MS); let _ = notifier.1.wait_timeout(guard, STACK_TURN_OFF_TIMEOUT_MS); let _ = notifier.enabled_notify.wait_timeout(guard, STACK_TURN_OFF_TIMEOUT_MS); } log::debug!("SIGTERM cleaning up the stack."); let txl = tx.clone(); tokio::spawn(async move { // Send the cleanup message here. let _ = txl.send(Message::Cleanup).await; }); let guard = notifier.thread_attached.lock().unwrap(); if *guard { log::debug!("Waiting for stack to clean up for {:?}", STACK_CLEANUP_TIMEOUT_MS); let _ = notifier.thread_notify.wait_timeout(guard, STACK_CLEANUP_TIMEOUT_MS); } } Loading system/gd/rust/linux/stack/src/bluetooth.rs +35 −8 Original line number Diff line number Diff line Loading @@ -4,8 +4,8 @@ use bt_topshim::btif::{ BaseCallbacks, BaseCallbacksDispatcher, BluetoothInterface, BluetoothProperty, BtAclState, BtBondState, BtConnectionDirection, BtConnectionState, BtDeviceType, BtDiscMode, BtDiscoveryState, BtHciErrorCode, BtPinCode, BtPropertyType, BtScanMode, BtSspVariant, BtState, BtStatus, BtTransport, BtVendorProductInfo, DisplayAddress, RawAddress, ToggleableProfile, Uuid, Uuid128Bit, BtStatus, BtThreadEvent, BtTransport, BtVendorProductInfo, DisplayAddress, RawAddress, ToggleableProfile, Uuid, Uuid128Bit, }; use bt_topshim::{ metrics, Loading Loading @@ -382,6 +382,15 @@ impl BluetoothDeviceContext { } } /// Structure to track all the signals for SIGTERM. pub struct SigData { pub enabled: Mutex<bool>, pub enabled_notify: Condvar, pub thread_attached: Mutex<bool>, pub thread_notify: Condvar, } /// The interface for adapter callbacks registered through `IBluetooth::register_callback`. pub trait IBluetoothCallback: RPCProxy { /// When any adapter property changes. Loading Loading @@ -500,7 +509,7 @@ pub struct Bluetooth { discoverable_timeout: Option<JoinHandle<()>>, /// Used to notify signal handler that we have turned off the stack. sig_notifier: Arc<(Mutex<bool>, Condvar)>, sig_notifier: Arc<(SigData)>, } impl Bluetooth { Loading @@ -509,7 +518,7 @@ impl Bluetooth { adapter_index: i32, hci_index: i32, tx: Sender<Message>, sig_notifier: Arc<(Mutex<bool>, Condvar)>, sig_notifier: Arc<(SigData)>, intf: Arc<Mutex<BluetoothInterface>>, bluetooth_admin: Arc<Mutex<Box<BluetoothAdmin>>>, bluetooth_gatt: Arc<Mutex<Box<BluetoothGatt>>>, Loading Loading @@ -1173,6 +1182,9 @@ pub(crate) trait BtifBluetoothCallbacks { min_16_digit: bool, ) { } #[btif_callback(ThreadEvent)] fn thread_event(&mut self, event: BtThreadEvent) {} } #[btif_callbacks_dispatcher(dispatch_hid_host_callbacks, HHCallbacks)] Loading Loading @@ -1240,8 +1252,8 @@ impl BtifBluetoothCallbacks for Bluetooth { } // Let the signal notifier know we are turned off. *self.sig_notifier.0.lock().unwrap() = false; self.sig_notifier.1.notify_all(); *self.sig_notifier.enabled.lock().unwrap() = false; self.sig_notifier.enabled_notify.notify_all(); } BtState::On => { Loading @@ -1265,8 +1277,8 @@ impl BtifBluetoothCallbacks for Bluetooth { self.set_connectable(true); // Notify the signal notifier that we are turned on. *self.sig_notifier.0.lock().unwrap() = true; self.sig_notifier.1.notify_all(); *self.sig_notifier.enabled.lock().unwrap() = true; self.sig_notifier.enabled_notify.notify_all(); // Signal that the stack is up and running. match self.create_pid_file() { Loading Loading @@ -1726,6 +1738,21 @@ impl BtifBluetoothCallbacks for Bluetooth { None => (), }; } fn thread_event(&mut self, event: BtThreadEvent) { match event { BtThreadEvent::Associate => { // Let the signal notifier know stack is initialized. *self.sig_notifier.thread_attached.lock().unwrap() = true; self.sig_notifier.thread_notify.notify_all(); } BtThreadEvent::Disassociate => { // Let the signal notifier know stack is done. *self.sig_notifier.thread_attached.lock().unwrap() = false; self.sig_notifier.thread_notify.notify_all(); } } } } struct BleDiscoveryCallbacks { Loading system/gd/rust/linux/stack/src/lib.rs +4 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ use bt_topshim::{ pub enum Message { // Shuts down the stack. Shutdown, Cleanup, // Adapter is enabled and ready. AdapterReady, Loading Loading @@ -196,6 +197,9 @@ impl Stack { match m.unwrap() { Message::Shutdown => { bluetooth.lock().unwrap().disable(); } Message::Cleanup => { bluetooth.lock().unwrap().cleanup(); } Loading system/gd/rust/topshim/src/btif.rs +17 −2 Original line number Diff line number Diff line Loading @@ -330,6 +330,19 @@ impl Into<u32> for BtDiscMode { } } #[derive(Clone, Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)] #[repr(u32)] pub enum BtThreadEvent { Associate = 0, Disassociate, } impl From<bindings::bt_cb_thread_evt> for BtThreadEvent { fn from(item: bindings::bt_cb_thread_evt) -> Self { BtThreadEvent::from_u32(item).unwrap_or(BtThreadEvent::Associate) } } #[derive(Clone, Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)] #[repr(u32)] pub enum BtIoCap { Loading Loading @@ -883,8 +896,8 @@ pub enum BaseCallbacks { BtConnectionDirection, u16, ), ThreadEvent(BtThreadEvent), // Unimplemented so far: // thread_evt_cb // dut_mode_recv_cb // le_test_mode_cb // energy_info_cb Loading Loading @@ -944,6 +957,8 @@ cb_variant!(BaseCb, le_address_associate_cb -> BaseCallbacks::LeAddressAssociate let _1 = unsafe { *(_1 as *const RawAddress) }; }); cb_variant!(BaseCb, thread_evt_cb -> BaseCallbacks::ThreadEvent, u32 -> BtThreadEvent); cb_variant!(BaseCb, acl_state_cb -> BaseCallbacks::AclState, u32 -> BtStatus, *mut RawAddress, bindings::bt_acl_state_t -> BtAclState, i32 -> BtTransport, bindings::bt_hci_error_code_t -> BtHciErrorCode, bindings::bt_conn_direction_t -> BtConnectionDirection, u16 -> u16, { let _1 = unsafe { *(_1 as *const RawAddress) }; Loading Loading @@ -1072,7 +1087,7 @@ impl BluetoothInterface { address_consolidate_cb: Some(address_consolidate_cb), le_address_associate_cb: Some(le_address_associate_cb), acl_state_changed_cb: Some(acl_state_cb), thread_evt_cb: None, thread_evt_cb: Some(thread_evt_cb), dut_mode_recv_cb: None, le_test_mode_cb: None, energy_info_cb: None, Loading Loading
system/gd/rust/linux/service/src/main.rs +25 −5 Original line number Diff line number Diff line Loading @@ -20,7 +20,7 @@ use btstack::{ battery_manager::BatteryManager, battery_provider_manager::BatteryProviderManager, battery_service::BatteryService, bluetooth::{Bluetooth, IBluetooth}, bluetooth::{Bluetooth, IBluetooth, SigData}, bluetooth_admin::BluetoothAdmin, bluetooth_gatt::BluetoothGatt, bluetooth_logging::BluetoothLogging, Loading Loading @@ -49,6 +49,8 @@ const ADMIN_SETTINGS_FILE_PATH: &str = "/var/lib/bluetooth/admin_policy.json"; // The maximum ACL disconnect timeout is 3.5s defined by BTA_DM_DISABLE_TIMER_MS // and BTA_DM_DISABLE_TIMER_RETRIAL_MS const STACK_TURN_OFF_TIMEOUT_MS: Duration = Duration::from_millis(4000); // Time bt_stack_manager waits for cleanup const STACK_CLEANUP_TIMEOUT_MS: Duration = Duration::from_millis(1000); const VERBOSE_ONLY_LOG_TAGS: &[&str] = &[ "bt_bta_av", // AV apis Loading Loading @@ -135,7 +137,12 @@ fn main() -> Result<(), Box<dyn Error>> { init_flags.push(String::from("INIT_classic_discovery_only=true")); let (tx, rx) = Stack::create_channel(); let sig_notifier = Arc::new((Mutex::new(false), Condvar::new())); let sig_notifier = Arc::new(SigData { enabled: Mutex::new(false), enabled_notify: Condvar::new(), thread_attached: Mutex::new(false), thread_notify: Condvar::new(), }); let intf = Arc::new(Mutex::new(get_btinterface().unwrap())); let bluetooth_gatt = Loading Loading @@ -424,7 +431,7 @@ fn main() -> Result<(), Box<dyn Error>> { lazy_static! { /// Data needed for signal handling. static ref SIG_DATA: Mutex<Option<(Sender<Message>, Arc<(Mutex<bool>, Condvar)>)>> = Mutex::new(None); static ref SIG_DATA: Mutex<Option<(Sender<Message>, Arc<(SigData)>)>> = Mutex::new(None); } extern "C" fn handle_sigterm(_signum: i32) { Loading @@ -437,10 +444,23 @@ extern "C" fn handle_sigterm(_signum: i32) { let _ = txl.send(Message::Shutdown).await; }); let guard = notifier.0.lock().unwrap(); let guard = notifier.enabled.lock().unwrap(); if *guard { log::debug!("Waiting for stack to turn off for {:?}", STACK_TURN_OFF_TIMEOUT_MS); let _ = notifier.1.wait_timeout(guard, STACK_TURN_OFF_TIMEOUT_MS); let _ = notifier.enabled_notify.wait_timeout(guard, STACK_TURN_OFF_TIMEOUT_MS); } log::debug!("SIGTERM cleaning up the stack."); let txl = tx.clone(); tokio::spawn(async move { // Send the cleanup message here. let _ = txl.send(Message::Cleanup).await; }); let guard = notifier.thread_attached.lock().unwrap(); if *guard { log::debug!("Waiting for stack to clean up for {:?}", STACK_CLEANUP_TIMEOUT_MS); let _ = notifier.thread_notify.wait_timeout(guard, STACK_CLEANUP_TIMEOUT_MS); } } Loading
system/gd/rust/linux/stack/src/bluetooth.rs +35 −8 Original line number Diff line number Diff line Loading @@ -4,8 +4,8 @@ use bt_topshim::btif::{ BaseCallbacks, BaseCallbacksDispatcher, BluetoothInterface, BluetoothProperty, BtAclState, BtBondState, BtConnectionDirection, BtConnectionState, BtDeviceType, BtDiscMode, BtDiscoveryState, BtHciErrorCode, BtPinCode, BtPropertyType, BtScanMode, BtSspVariant, BtState, BtStatus, BtTransport, BtVendorProductInfo, DisplayAddress, RawAddress, ToggleableProfile, Uuid, Uuid128Bit, BtStatus, BtThreadEvent, BtTransport, BtVendorProductInfo, DisplayAddress, RawAddress, ToggleableProfile, Uuid, Uuid128Bit, }; use bt_topshim::{ metrics, Loading Loading @@ -382,6 +382,15 @@ impl BluetoothDeviceContext { } } /// Structure to track all the signals for SIGTERM. pub struct SigData { pub enabled: Mutex<bool>, pub enabled_notify: Condvar, pub thread_attached: Mutex<bool>, pub thread_notify: Condvar, } /// The interface for adapter callbacks registered through `IBluetooth::register_callback`. pub trait IBluetoothCallback: RPCProxy { /// When any adapter property changes. Loading Loading @@ -500,7 +509,7 @@ pub struct Bluetooth { discoverable_timeout: Option<JoinHandle<()>>, /// Used to notify signal handler that we have turned off the stack. sig_notifier: Arc<(Mutex<bool>, Condvar)>, sig_notifier: Arc<(SigData)>, } impl Bluetooth { Loading @@ -509,7 +518,7 @@ impl Bluetooth { adapter_index: i32, hci_index: i32, tx: Sender<Message>, sig_notifier: Arc<(Mutex<bool>, Condvar)>, sig_notifier: Arc<(SigData)>, intf: Arc<Mutex<BluetoothInterface>>, bluetooth_admin: Arc<Mutex<Box<BluetoothAdmin>>>, bluetooth_gatt: Arc<Mutex<Box<BluetoothGatt>>>, Loading Loading @@ -1173,6 +1182,9 @@ pub(crate) trait BtifBluetoothCallbacks { min_16_digit: bool, ) { } #[btif_callback(ThreadEvent)] fn thread_event(&mut self, event: BtThreadEvent) {} } #[btif_callbacks_dispatcher(dispatch_hid_host_callbacks, HHCallbacks)] Loading Loading @@ -1240,8 +1252,8 @@ impl BtifBluetoothCallbacks for Bluetooth { } // Let the signal notifier know we are turned off. *self.sig_notifier.0.lock().unwrap() = false; self.sig_notifier.1.notify_all(); *self.sig_notifier.enabled.lock().unwrap() = false; self.sig_notifier.enabled_notify.notify_all(); } BtState::On => { Loading @@ -1265,8 +1277,8 @@ impl BtifBluetoothCallbacks for Bluetooth { self.set_connectable(true); // Notify the signal notifier that we are turned on. *self.sig_notifier.0.lock().unwrap() = true; self.sig_notifier.1.notify_all(); *self.sig_notifier.enabled.lock().unwrap() = true; self.sig_notifier.enabled_notify.notify_all(); // Signal that the stack is up and running. match self.create_pid_file() { Loading Loading @@ -1726,6 +1738,21 @@ impl BtifBluetoothCallbacks for Bluetooth { None => (), }; } fn thread_event(&mut self, event: BtThreadEvent) { match event { BtThreadEvent::Associate => { // Let the signal notifier know stack is initialized. *self.sig_notifier.thread_attached.lock().unwrap() = true; self.sig_notifier.thread_notify.notify_all(); } BtThreadEvent::Disassociate => { // Let the signal notifier know stack is done. *self.sig_notifier.thread_attached.lock().unwrap() = false; self.sig_notifier.thread_notify.notify_all(); } } } } struct BleDiscoveryCallbacks { Loading
system/gd/rust/linux/stack/src/lib.rs +4 −0 Original line number Diff line number Diff line Loading @@ -64,6 +64,7 @@ use bt_topshim::{ pub enum Message { // Shuts down the stack. Shutdown, Cleanup, // Adapter is enabled and ready. AdapterReady, Loading Loading @@ -196,6 +197,9 @@ impl Stack { match m.unwrap() { Message::Shutdown => { bluetooth.lock().unwrap().disable(); } Message::Cleanup => { bluetooth.lock().unwrap().cleanup(); } Loading
system/gd/rust/topshim/src/btif.rs +17 −2 Original line number Diff line number Diff line Loading @@ -330,6 +330,19 @@ impl Into<u32> for BtDiscMode { } } #[derive(Clone, Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)] #[repr(u32)] pub enum BtThreadEvent { Associate = 0, Disassociate, } impl From<bindings::bt_cb_thread_evt> for BtThreadEvent { fn from(item: bindings::bt_cb_thread_evt) -> Self { BtThreadEvent::from_u32(item).unwrap_or(BtThreadEvent::Associate) } } #[derive(Clone, Debug, FromPrimitive, ToPrimitive, PartialEq, PartialOrd)] #[repr(u32)] pub enum BtIoCap { Loading Loading @@ -883,8 +896,8 @@ pub enum BaseCallbacks { BtConnectionDirection, u16, ), ThreadEvent(BtThreadEvent), // Unimplemented so far: // thread_evt_cb // dut_mode_recv_cb // le_test_mode_cb // energy_info_cb Loading Loading @@ -944,6 +957,8 @@ cb_variant!(BaseCb, le_address_associate_cb -> BaseCallbacks::LeAddressAssociate let _1 = unsafe { *(_1 as *const RawAddress) }; }); cb_variant!(BaseCb, thread_evt_cb -> BaseCallbacks::ThreadEvent, u32 -> BtThreadEvent); cb_variant!(BaseCb, acl_state_cb -> BaseCallbacks::AclState, u32 -> BtStatus, *mut RawAddress, bindings::bt_acl_state_t -> BtAclState, i32 -> BtTransport, bindings::bt_hci_error_code_t -> BtHciErrorCode, bindings::bt_conn_direction_t -> BtConnectionDirection, u16 -> u16, { let _1 = unsafe { *(_1 as *const RawAddress) }; Loading Loading @@ -1072,7 +1087,7 @@ impl BluetoothInterface { address_consolidate_cb: Some(address_consolidate_cb), le_address_associate_cb: Some(le_address_associate_cb), acl_state_changed_cb: Some(acl_state_cb), thread_evt_cb: None, thread_evt_cb: Some(thread_evt_cb), dut_mode_recv_cb: None, le_test_mode_cb: None, energy_info_cb: None, Loading