Loading system/gd/rust/linux/client/src/callbacks.rs +59 −3 Original line number Diff line number Diff line use crate::dbus_iface::{ export_bluetooth_callback_dbus_intf, export_bluetooth_connection_callback_dbus_intf, export_bluetooth_gatt_callback_dbus_intf, export_bluetooth_manager_callback_dbus_intf, export_suspend_callback_dbus_intf, export_scanner_callback_dbus_intf, export_suspend_callback_dbus_intf, }; use crate::ClientContext; use crate::{console_yellow, print_info}; use crate::{console_red, console_yellow, print_error, print_info}; use bt_topshim::btif::{BtBondState, BtPropertyType, BtSspVariant}; use bt_topshim::profiles::gatt::GattStatus; use btstack::bluetooth::{ BluetoothDevice, IBluetooth, IBluetoothCallback, IBluetoothConnectionCallback, }; use btstack::bluetooth_gatt::{BluetoothGattService, IBluetoothGattCallback, LePhy}; use btstack::bluetooth_gatt::{ BluetoothGattService, IBluetoothGattCallback, IScannerCallback, LePhy, }; use btstack::suspend::ISuspendCallback; use btstack::RPCProxy; use dbus::nonblock::SyncConnection; Loading Loading @@ -293,6 +295,60 @@ impl RPCProxy for BtConnectionCallback { } } pub(crate) struct ScannerCallback { objpath: String, _context: Arc<Mutex<ClientContext>>, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, } impl ScannerCallback { pub(crate) fn new( objpath: String, _context: Arc<Mutex<ClientContext>>, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, ) -> Self { Self { objpath, _context, dbus_connection, dbus_crossroads } } } impl IScannerCallback for ScannerCallback { fn on_scanner_registered(&self, status: u8, scanner_id: u8) { if status != 0 { print_error!("Failed registering scanner, status = {}", status); return; } print_info!("Scanner callback registered, id = {}", scanner_id); } } impl RPCProxy for ScannerCallback { fn register_disconnect(&mut self, _f: Box<dyn Fn(u32) + Send>) -> u32 { 0 } fn get_object_id(&self) -> String { self.objpath.clone() } fn unregister(&mut self, _id: u32) -> bool { false } fn export_for_rpc(self: Box<Self>) { let cr = self.dbus_crossroads.clone(); let iface = export_scanner_callback_dbus_intf( self.dbus_connection.clone(), &mut cr.lock().unwrap(), Arc::new(Mutex::new(DisconnectWatcher::new())), ); cr.lock().unwrap().insert(self.get_object_id(), &[iface], Arc::new(Mutex::new(self))); } } pub(crate) struct BtGattCallback { objpath: String, context: Arc<Mutex<ClientContext>>, Loading system/gd/rust/linux/client/src/command_handler.rs +51 −1 Original line number Diff line number Diff line Loading @@ -8,7 +8,7 @@ use crate::{console_red, console_yellow, print_error, print_info}; use bt_topshim::btif::BtTransport; use btstack::bluetooth::{BluetoothDevice, IBluetooth}; use btstack::bluetooth_gatt::IBluetoothGatt; use btstack::uuid::{Profile, UuidHelper}; use btstack::uuid::{Profile, UuidHelper, UuidWrapper}; use manager_service::iface_bluetooth_manager::IBluetoothManager; const INDENT_CHAR: &str = " "; Loading Loading @@ -126,6 +126,13 @@ fn build_commands() -> HashMap<String, CommandOption> { function_pointer: CommandHandler::cmd_gatt, }, ); command_options.insert( String::from("le-scan"), CommandOption { description: String::from("LE scanning utilities."), function_pointer: CommandHandler::cmd_le_scan, }, ); command_options.insert( String::from("get-address"), CommandOption { Loading Loading @@ -663,6 +670,49 @@ impl CommandHandler { }); } fn cmd_le_scan(&mut self, args: &Vec<String>) { if !self.context.lock().unwrap().adapter_ready { self.adapter_not_ready(); return; } enforce_arg_len(args, 1, "le-scan <commands>", || match &args[0][0..] { "register-scanner" => { let scanner_callback_id = self.context.lock().unwrap().scanner_callback_id; if let Some(id) = scanner_callback_id { let uuid = self .context .lock() .unwrap() .gatt_dbus .as_mut() .unwrap() .register_scanner(id); print_info!("Scanner to be registered with UUID = {}", UuidWrapper(&uuid)); } else { print_error!("Cannot register scanner before registering scanner callback"); } } "unregister-scanner" => { if args.len() < 2 { println!("usage: le-scan unregister-scanner <scanner-id>"); return; } let scanner_id = String::from(&args[1]).parse::<u8>(); if let Ok(id) = scanner_id { self.context.lock().unwrap().gatt_dbus.as_mut().unwrap().unregister_scanner(id); } else { print_error!("Failed parsing scanner id"); } } _ => { println!("Invalid argument '{}'", args[0]); } }); } /// Get the list of currently supported commands pub fn get_command_list(&self) -> Vec<String> { self.command_options.keys().map(|key| String::from(key)).collect::<Vec<String>>() Loading system/gd/rust/linux/client/src/dbus_iface.rs +53 −7 Original line number Diff line number Diff line Loading @@ -186,6 +186,30 @@ impl IBluetoothConnectionCallback for IBluetoothConnectionCallbackDBus { fn on_device_disconnected(&self, remote_device: BluetoothDevice) {} } struct IScannerCallbackDBus {} impl RPCProxy for IScannerCallbackDBus { fn register_disconnect(&mut self, _f: Box<dyn Fn(u32) + Send>) -> u32 { 0 } fn get_object_id(&self) -> String { String::from("") } fn unregister(&mut self, _id: u32) -> bool { false } fn export_for_rpc(self: Box<Self>) {} } #[generate_dbus_exporter( export_scanner_callback_dbus_intf, "org.chromium.bluetooth.ScannerCallback" )] impl IScannerCallback for IScannerCallbackDBus { #[dbus_method("OnScannerRegistered")] fn on_scanner_registered(&self, status: u8, scanner_id: u8) {} } // Implements RPC-friendly wrapper methods for calling IBluetooth, generated by // `generate_dbus_interface_client` below. pub(crate) struct BluetoothDBusRPC { Loading Loading @@ -527,24 +551,36 @@ impl IBluetoothManagerCallback for IBluetoothManagerCallbackDBus { fn on_hci_enabled_changed(&self, hci_interface: i32, enabled: bool) {} } pub(crate) struct BluetoothGattDBusRPC { client_proxy: ClientDBusProxy, } pub(crate) struct BluetoothGattDBus { client_proxy: ClientDBusProxy, pub rpc: BluetoothGattDBusRPC, } impl BluetoothGattDBus { pub(crate) fn new(conn: Arc<SyncConnection>, index: i32) -> BluetoothGattDBus { BluetoothGattDBus { client_proxy: ClientDBusProxy::new( conn.clone(), fn make_client_proxy(conn: Arc<SyncConnection>, index: i32) -> ClientDBusProxy { ClientDBusProxy::new( conn, String::from("org.chromium.bluetooth"), make_object_path(index, "gatt"), String::from("org.chromium.bluetooth.BluetoothGatt"), ), ) } pub(crate) fn new(conn: Arc<SyncConnection>, index: i32) -> BluetoothGattDBus { BluetoothGattDBus { client_proxy: Self::make_client_proxy(conn.clone(), index), rpc: BluetoothGattDBusRPC { client_proxy: Self::make_client_proxy(conn.clone(), index), }, } } } #[generate_dbus_interface_client] #[generate_dbus_interface_client(BluetoothGattDBusRPC)] impl IBluetoothGatt for BluetoothGattDBus { #[dbus_method("RegisterScannerCallback")] fn register_scanner_callback(&mut self, _callback: Box<dyn IScannerCallback + Send>) -> u32 { Loading @@ -556,6 +592,16 @@ impl IBluetoothGatt for BluetoothGattDBus { dbus_generated!() } #[dbus_method("RegisterScanner")] fn register_scanner(&mut self, callback_id: u32) -> Uuid128Bit { dbus_generated!() } #[dbus_method("UnregisterScanner")] fn unregister_scanner(&mut self, scanner_id: u8) -> bool { dbus_generated!() } fn start_scan(&self, _scanner_id: i32, _settings: ScanSettings, _filters: Vec<ScanFilter>) { dbus_generated!() } Loading system/gd/rust/linux/client/src/main.rs +25 −1 Original line number Diff line number Diff line Loading @@ -7,7 +7,9 @@ use dbus::nonblock::SyncConnection; use dbus_crossroads::Crossroads; use tokio::sync::mpsc; use crate::callbacks::{BtCallback, BtConnectionCallback, BtManagerCallback, SuspendCallback}; use crate::callbacks::{ BtCallback, BtConnectionCallback, BtManagerCallback, ScannerCallback, SuspendCallback, }; use crate::command_handler::CommandHandler; use crate::dbus_iface::{BluetoothDBus, BluetoothGattDBus, BluetoothManagerDBus, SuspendDBus}; use crate::editor::AsyncEditor; Loading Loading @@ -76,6 +78,9 @@ pub(crate) struct ClientContext { /// Internal DBus crossroads object. dbus_crossroads: Arc<Mutex<Crossroads>>, /// Identifies the callback to receive IScannerCallback method calls. scanner_callback_id: Option<u32>, } impl ClientContext { Loading Loading @@ -105,6 +110,7 @@ impl ClientContext { fg: tx, dbus_connection, dbus_crossroads, scanner_callback_id: None, } } Loading Loading @@ -367,6 +373,24 @@ async fn start_interactive_shell( .await .expect("D-Bus error on IBluetooth::RegisterConnectionCallback"); // Register callback listener for le-scan`commands. let scanner_callback_id = context .lock() .unwrap() .gatt_dbus .as_mut() .unwrap() .rpc .register_scanner_callback(Box::new(ScannerCallback::new( cb_objpath.clone(), context.clone(), dbus_connection.clone(), dbus_crossroads.clone(), ))) .await .expect("D-Bus error on IBluetoothGatt::RegisterScannerCallback"); context.lock().unwrap().scanner_callback_id = Some(scanner_callback_id); // When adapter is ready, Suspend API is also ready. Register as an observer. // TODO(b/224606285): Implement suspend debug utils in btclient. context.lock().unwrap().suspend_dbus.as_mut().unwrap().register_callback(Box::new( Loading system/gd/rust/linux/service/src/iface_bluetooth_gatt.rs +11 −1 Original line number Diff line number Diff line Loading @@ -142,7 +142,7 @@ struct ScannerCallbackDBus {} #[dbus_proxy_obj(ScannerCallback, "org.chromium.bluetooth.ScannerCallback")] impl IScannerCallback for ScannerCallbackDBus { #[dbus_method("OnScannerRegistered")] fn on_scanner_registered(&self, status: i32, scanner_id: i32) { fn on_scanner_registered(&self, status: u8, scanner_id: u8) { dbus_generated!() } } Loading Loading @@ -212,6 +212,16 @@ impl IBluetoothGatt for IBluetoothGattDBus { dbus_generated!() } #[dbus_method("RegisterScanner")] fn register_scanner(&mut self, callback_id: u32) -> Uuid128Bit { dbus_generated!() } #[dbus_method("UnregisterScanner")] fn unregister_scanner(&mut self, scanner_id: u8) -> bool { dbus_generated!() } #[dbus_method("StartScan")] fn start_scan(&self, scanner_id: i32, settings: ScanSettings, filters: Vec<ScanFilter>) { dbus_generated!() Loading Loading
system/gd/rust/linux/client/src/callbacks.rs +59 −3 Original line number Diff line number Diff line use crate::dbus_iface::{ export_bluetooth_callback_dbus_intf, export_bluetooth_connection_callback_dbus_intf, export_bluetooth_gatt_callback_dbus_intf, export_bluetooth_manager_callback_dbus_intf, export_suspend_callback_dbus_intf, export_scanner_callback_dbus_intf, export_suspend_callback_dbus_intf, }; use crate::ClientContext; use crate::{console_yellow, print_info}; use crate::{console_red, console_yellow, print_error, print_info}; use bt_topshim::btif::{BtBondState, BtPropertyType, BtSspVariant}; use bt_topshim::profiles::gatt::GattStatus; use btstack::bluetooth::{ BluetoothDevice, IBluetooth, IBluetoothCallback, IBluetoothConnectionCallback, }; use btstack::bluetooth_gatt::{BluetoothGattService, IBluetoothGattCallback, LePhy}; use btstack::bluetooth_gatt::{ BluetoothGattService, IBluetoothGattCallback, IScannerCallback, LePhy, }; use btstack::suspend::ISuspendCallback; use btstack::RPCProxy; use dbus::nonblock::SyncConnection; Loading Loading @@ -293,6 +295,60 @@ impl RPCProxy for BtConnectionCallback { } } pub(crate) struct ScannerCallback { objpath: String, _context: Arc<Mutex<ClientContext>>, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, } impl ScannerCallback { pub(crate) fn new( objpath: String, _context: Arc<Mutex<ClientContext>>, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, ) -> Self { Self { objpath, _context, dbus_connection, dbus_crossroads } } } impl IScannerCallback for ScannerCallback { fn on_scanner_registered(&self, status: u8, scanner_id: u8) { if status != 0 { print_error!("Failed registering scanner, status = {}", status); return; } print_info!("Scanner callback registered, id = {}", scanner_id); } } impl RPCProxy for ScannerCallback { fn register_disconnect(&mut self, _f: Box<dyn Fn(u32) + Send>) -> u32 { 0 } fn get_object_id(&self) -> String { self.objpath.clone() } fn unregister(&mut self, _id: u32) -> bool { false } fn export_for_rpc(self: Box<Self>) { let cr = self.dbus_crossroads.clone(); let iface = export_scanner_callback_dbus_intf( self.dbus_connection.clone(), &mut cr.lock().unwrap(), Arc::new(Mutex::new(DisconnectWatcher::new())), ); cr.lock().unwrap().insert(self.get_object_id(), &[iface], Arc::new(Mutex::new(self))); } } pub(crate) struct BtGattCallback { objpath: String, context: Arc<Mutex<ClientContext>>, Loading
system/gd/rust/linux/client/src/command_handler.rs +51 −1 Original line number Diff line number Diff line Loading @@ -8,7 +8,7 @@ use crate::{console_red, console_yellow, print_error, print_info}; use bt_topshim::btif::BtTransport; use btstack::bluetooth::{BluetoothDevice, IBluetooth}; use btstack::bluetooth_gatt::IBluetoothGatt; use btstack::uuid::{Profile, UuidHelper}; use btstack::uuid::{Profile, UuidHelper, UuidWrapper}; use manager_service::iface_bluetooth_manager::IBluetoothManager; const INDENT_CHAR: &str = " "; Loading Loading @@ -126,6 +126,13 @@ fn build_commands() -> HashMap<String, CommandOption> { function_pointer: CommandHandler::cmd_gatt, }, ); command_options.insert( String::from("le-scan"), CommandOption { description: String::from("LE scanning utilities."), function_pointer: CommandHandler::cmd_le_scan, }, ); command_options.insert( String::from("get-address"), CommandOption { Loading Loading @@ -663,6 +670,49 @@ impl CommandHandler { }); } fn cmd_le_scan(&mut self, args: &Vec<String>) { if !self.context.lock().unwrap().adapter_ready { self.adapter_not_ready(); return; } enforce_arg_len(args, 1, "le-scan <commands>", || match &args[0][0..] { "register-scanner" => { let scanner_callback_id = self.context.lock().unwrap().scanner_callback_id; if let Some(id) = scanner_callback_id { let uuid = self .context .lock() .unwrap() .gatt_dbus .as_mut() .unwrap() .register_scanner(id); print_info!("Scanner to be registered with UUID = {}", UuidWrapper(&uuid)); } else { print_error!("Cannot register scanner before registering scanner callback"); } } "unregister-scanner" => { if args.len() < 2 { println!("usage: le-scan unregister-scanner <scanner-id>"); return; } let scanner_id = String::from(&args[1]).parse::<u8>(); if let Ok(id) = scanner_id { self.context.lock().unwrap().gatt_dbus.as_mut().unwrap().unregister_scanner(id); } else { print_error!("Failed parsing scanner id"); } } _ => { println!("Invalid argument '{}'", args[0]); } }); } /// Get the list of currently supported commands pub fn get_command_list(&self) -> Vec<String> { self.command_options.keys().map(|key| String::from(key)).collect::<Vec<String>>() Loading
system/gd/rust/linux/client/src/dbus_iface.rs +53 −7 Original line number Diff line number Diff line Loading @@ -186,6 +186,30 @@ impl IBluetoothConnectionCallback for IBluetoothConnectionCallbackDBus { fn on_device_disconnected(&self, remote_device: BluetoothDevice) {} } struct IScannerCallbackDBus {} impl RPCProxy for IScannerCallbackDBus { fn register_disconnect(&mut self, _f: Box<dyn Fn(u32) + Send>) -> u32 { 0 } fn get_object_id(&self) -> String { String::from("") } fn unregister(&mut self, _id: u32) -> bool { false } fn export_for_rpc(self: Box<Self>) {} } #[generate_dbus_exporter( export_scanner_callback_dbus_intf, "org.chromium.bluetooth.ScannerCallback" )] impl IScannerCallback for IScannerCallbackDBus { #[dbus_method("OnScannerRegistered")] fn on_scanner_registered(&self, status: u8, scanner_id: u8) {} } // Implements RPC-friendly wrapper methods for calling IBluetooth, generated by // `generate_dbus_interface_client` below. pub(crate) struct BluetoothDBusRPC { Loading Loading @@ -527,24 +551,36 @@ impl IBluetoothManagerCallback for IBluetoothManagerCallbackDBus { fn on_hci_enabled_changed(&self, hci_interface: i32, enabled: bool) {} } pub(crate) struct BluetoothGattDBusRPC { client_proxy: ClientDBusProxy, } pub(crate) struct BluetoothGattDBus { client_proxy: ClientDBusProxy, pub rpc: BluetoothGattDBusRPC, } impl BluetoothGattDBus { pub(crate) fn new(conn: Arc<SyncConnection>, index: i32) -> BluetoothGattDBus { BluetoothGattDBus { client_proxy: ClientDBusProxy::new( conn.clone(), fn make_client_proxy(conn: Arc<SyncConnection>, index: i32) -> ClientDBusProxy { ClientDBusProxy::new( conn, String::from("org.chromium.bluetooth"), make_object_path(index, "gatt"), String::from("org.chromium.bluetooth.BluetoothGatt"), ), ) } pub(crate) fn new(conn: Arc<SyncConnection>, index: i32) -> BluetoothGattDBus { BluetoothGattDBus { client_proxy: Self::make_client_proxy(conn.clone(), index), rpc: BluetoothGattDBusRPC { client_proxy: Self::make_client_proxy(conn.clone(), index), }, } } } #[generate_dbus_interface_client] #[generate_dbus_interface_client(BluetoothGattDBusRPC)] impl IBluetoothGatt for BluetoothGattDBus { #[dbus_method("RegisterScannerCallback")] fn register_scanner_callback(&mut self, _callback: Box<dyn IScannerCallback + Send>) -> u32 { Loading @@ -556,6 +592,16 @@ impl IBluetoothGatt for BluetoothGattDBus { dbus_generated!() } #[dbus_method("RegisterScanner")] fn register_scanner(&mut self, callback_id: u32) -> Uuid128Bit { dbus_generated!() } #[dbus_method("UnregisterScanner")] fn unregister_scanner(&mut self, scanner_id: u8) -> bool { dbus_generated!() } fn start_scan(&self, _scanner_id: i32, _settings: ScanSettings, _filters: Vec<ScanFilter>) { dbus_generated!() } Loading
system/gd/rust/linux/client/src/main.rs +25 −1 Original line number Diff line number Diff line Loading @@ -7,7 +7,9 @@ use dbus::nonblock::SyncConnection; use dbus_crossroads::Crossroads; use tokio::sync::mpsc; use crate::callbacks::{BtCallback, BtConnectionCallback, BtManagerCallback, SuspendCallback}; use crate::callbacks::{ BtCallback, BtConnectionCallback, BtManagerCallback, ScannerCallback, SuspendCallback, }; use crate::command_handler::CommandHandler; use crate::dbus_iface::{BluetoothDBus, BluetoothGattDBus, BluetoothManagerDBus, SuspendDBus}; use crate::editor::AsyncEditor; Loading Loading @@ -76,6 +78,9 @@ pub(crate) struct ClientContext { /// Internal DBus crossroads object. dbus_crossroads: Arc<Mutex<Crossroads>>, /// Identifies the callback to receive IScannerCallback method calls. scanner_callback_id: Option<u32>, } impl ClientContext { Loading Loading @@ -105,6 +110,7 @@ impl ClientContext { fg: tx, dbus_connection, dbus_crossroads, scanner_callback_id: None, } } Loading Loading @@ -367,6 +373,24 @@ async fn start_interactive_shell( .await .expect("D-Bus error on IBluetooth::RegisterConnectionCallback"); // Register callback listener for le-scan`commands. let scanner_callback_id = context .lock() .unwrap() .gatt_dbus .as_mut() .unwrap() .rpc .register_scanner_callback(Box::new(ScannerCallback::new( cb_objpath.clone(), context.clone(), dbus_connection.clone(), dbus_crossroads.clone(), ))) .await .expect("D-Bus error on IBluetoothGatt::RegisterScannerCallback"); context.lock().unwrap().scanner_callback_id = Some(scanner_callback_id); // When adapter is ready, Suspend API is also ready. Register as an observer. // TODO(b/224606285): Implement suspend debug utils in btclient. context.lock().unwrap().suspend_dbus.as_mut().unwrap().register_callback(Box::new( Loading
system/gd/rust/linux/service/src/iface_bluetooth_gatt.rs +11 −1 Original line number Diff line number Diff line Loading @@ -142,7 +142,7 @@ struct ScannerCallbackDBus {} #[dbus_proxy_obj(ScannerCallback, "org.chromium.bluetooth.ScannerCallback")] impl IScannerCallback for ScannerCallbackDBus { #[dbus_method("OnScannerRegistered")] fn on_scanner_registered(&self, status: i32, scanner_id: i32) { fn on_scanner_registered(&self, status: u8, scanner_id: u8) { dbus_generated!() } } Loading Loading @@ -212,6 +212,16 @@ impl IBluetoothGatt for IBluetoothGattDBus { dbus_generated!() } #[dbus_method("RegisterScanner")] fn register_scanner(&mut self, callback_id: u32) -> Uuid128Bit { dbus_generated!() } #[dbus_method("UnregisterScanner")] fn unregister_scanner(&mut self, scanner_id: u8) -> bool { dbus_generated!() } #[dbus_method("StartScan")] fn start_scan(&self, scanner_id: i32, settings: ScanSettings, filters: Vec<ScanFilter>) { dbus_generated!() Loading