Loading system/gd/rust/linux/client/src/callbacks.rs +5 −23 Original line number Diff line number Diff line Loading @@ -32,29 +32,7 @@ impl IBluetoothManagerCallback for BtManagerCallback { } fn on_hci_enabled_changed(&self, hci_interface: i32, enabled: bool) { print_info!("hci{} enabled = {}", hci_interface, enabled); self.context .lock() .unwrap() .adapters .entry(hci_interface) .and_modify(|v| *v = enabled) .or_insert(enabled); // When the default adapter's state is updated, we need to modify a few more things. // Only do this if we're not repeating the previous state. let prev_enabled = self.context.lock().unwrap().enabled; let default_adapter = self.context.lock().unwrap().default_adapter; if hci_interface == default_adapter && prev_enabled != enabled { self.context.lock().unwrap().enabled = enabled; self.context.lock().unwrap().adapter_ready = false; if enabled { self.context.lock().unwrap().create_adapter_proxy(hci_interface); } else { self.context.lock().unwrap().adapter_dbus = None; } } self.context.lock().unwrap().set_adapter_enabled(hci_interface, enabled); } } Loading Loading @@ -124,6 +102,10 @@ impl IBluetoothCallback for BtCallback { ); } } fn on_bond_state_changed(&self, status: u32, address: String, state: u32) { print_info!("Bonding state changed: [{}] state: {}, Status = {}", address, state, status); } } impl RPCProxy for BtCallback { Loading system/gd/rust/linux/client/src/command_handler.rs +33 −9 Original line number Diff line number Diff line Loading @@ -112,10 +112,10 @@ fn build_commands() -> HashMap<String, CommandOption> { }, ); command_options.insert( String::from("list-devices"), String::from("list"), CommandOption { description: String::from( "List known remote devices from most recent discovery session.", "List bonded or found remote devices. Use: list <bonded|found>", ), function_pointer: CommandHandler::cmd_list_devices, }, Loading Loading @@ -239,10 +239,8 @@ impl CommandHandler { return; } let address = self.context.lock().unwrap().adapter_dbus.as_ref().unwrap().get_address(); let address = self.context.lock().unwrap().update_adapter_address(); print_info!("Local address = {}", &address); // Cache address for adapter show self.context.lock().unwrap().adapter_address = Some(address); } fn cmd_discovery(&mut self, args: &Vec<String>) { Loading Loading @@ -378,11 +376,37 @@ impl CommandHandler { self.command_options.keys().map(|key| String::from(key)).collect::<Vec<String>>() } fn cmd_list_devices(&mut self, _args: &Vec<String>) { fn cmd_list_devices(&mut self, args: &Vec<String>) { if !self.context.lock().unwrap().adapter_ready { self.adapter_not_ready(); return; } enforce_arg_len(args, 1, "list <bonded|found>", || match &args[0][0..] { "bonded" => { print_info!("Known bonded devices:"); let devices = self .context .lock() .unwrap() .adapter_dbus .as_ref() .unwrap() .get_bonded_devices(); for device in devices.iter() { print_info!("[{:17}] {}", device.address, device.name); } } "found" => { print_info!("Devices found in most recent discovery session:"); for (key, val) in self.context.lock().unwrap().found_devices.iter() { print_info!("[{:18}] {}", key, val.name); print_info!("[{:17}] {}", key, val.name); } } _ => { println!("Invalid argument '{}'", args[0]); } }); } } Loading system/gd/rust/linux/client/src/dbus_iface.rs +20 −0 Original line number Diff line number Diff line Loading @@ -169,6 +169,9 @@ impl IBluetoothCallback for IBluetoothCallbackDBus { passkey: u32, ) { } #[dbus_method("OnBondStateChanged")] fn on_bond_state_changed(&self, status: u32, address: String, state: u32) {} } pub(crate) struct BluetoothDBus { Loading Loading @@ -240,6 +243,23 @@ impl IBluetooth for BluetoothDBus { ), ) } fn cancel_bond_process(&self, device: BluetoothDevice) -> bool { self.client_proxy.method("CancelBondProcess", (BluetoothDevice::to_dbus(device).unwrap(),)) } fn remove_bond(&self, device: BluetoothDevice) -> bool { self.client_proxy.method("RemoveBond", (BluetoothDevice::to_dbus(device).unwrap(),)) } fn get_bonded_devices(&self) -> Vec<BluetoothDevice> { let props: Vec<dbus::arg::PropMap> = self.client_proxy.method("GetBondedDevices", ()); <Vec<BluetoothDevice> as DBusArg>::from_dbus(props, None, None, None).unwrap() } fn get_bond_state(&self, device: BluetoothDevice) -> u32 { self.client_proxy.method("GetBondState", (BluetoothDevice::to_dbus(device).unwrap(),)) } } #[dbus_propmap(AdapterWithEnabled)] Loading system/gd/rust/linux/client/src/main.rs +38 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,27 @@ impl ClientContext { } } // Sets required values for the adapter when enabling or disabling fn set_adapter_enabled(&mut self, hci_interface: i32, enabled: bool) { print_info!("hci{} enabled = {}", hci_interface, enabled); self.adapters.entry(hci_interface).and_modify(|v| *v = enabled).or_insert(enabled); // When the default adapter's state is updated, we need to modify a few more things. // Only do this if we're not repeating the previous state. let prev_enabled = self.enabled; let default_adapter = self.default_adapter; if hci_interface == default_adapter && prev_enabled != enabled { self.enabled = enabled; self.adapter_ready = false; if enabled { self.create_adapter_proxy(hci_interface); } else { self.adapter_dbus = None; } } } // Creates adapter proxy, registers callbacks and initializes address. fn create_adapter_proxy(&mut self, idx: i32) { let conn = self.dbus_connection.clone(); Loading @@ -117,6 +138,14 @@ impl ClientContext { let _ = fg.send(ForegroundActions::RegisterAdapterCallback(objpath)).await; }); } // Foreground-only: Updates the adapter address. fn update_adapter_address(&mut self) -> String { let address = self.adapter_dbus.as_ref().unwrap().get_address(); self.adapter_address = Some(address.clone()); address } } /// Actions to take on the foreground loop. This allows us to queue actions in Loading Loading @@ -171,6 +200,13 @@ fn main() -> Result<(), Box<dyn std::error::Error>> { context.clone(), ))); // Check if the default adapter is enabled. If yes, we should create the adapter proxy // right away. let default_adapter = context.lock().unwrap().default_adapter; if context.lock().unwrap().manager_dbus.get_adapter_enabled(default_adapter) { context.lock().unwrap().set_adapter_enabled(default_adapter, true); } let mut handler = CommandHandler::new(context.clone()); let args: Vec<String> = std::env::args().collect(); Loading Loading @@ -233,6 +269,8 @@ async fn start_interactive_shell( .unwrap() .register_callback(Box::new(BtCallback::new(objpath, context.clone()))); context.lock().unwrap().adapter_ready = true; let adapter_address = context.lock().unwrap().update_adapter_address(); print_info!("Adapter {} is ready", adapter_address); } ForegroundActions::Readline(result) => match result { Err(_err) => { Loading system/gd/rust/linux/dbus_projection/dbus_macros/src/lib.rs +1 −3 Original line number Diff line number Diff line Loading @@ -33,9 +33,7 @@ pub fn dbus_method(_attr: TokenStream, item: TokenStream) -> TokenStream { /// Generates a function to export a Rust object to D-Bus. /// /// Example: /// ``` /// #[generate_dbus_exporter(export_foo_dbus_obj, "org.example.FooInterface")] /// ``` /// /// This generates a method called `export_foo_dbus_obj` that will export a Rust object into a /// D-Bus object having interface `org.example.FooInterface`. Loading Loading
system/gd/rust/linux/client/src/callbacks.rs +5 −23 Original line number Diff line number Diff line Loading @@ -32,29 +32,7 @@ impl IBluetoothManagerCallback for BtManagerCallback { } fn on_hci_enabled_changed(&self, hci_interface: i32, enabled: bool) { print_info!("hci{} enabled = {}", hci_interface, enabled); self.context .lock() .unwrap() .adapters .entry(hci_interface) .and_modify(|v| *v = enabled) .or_insert(enabled); // When the default adapter's state is updated, we need to modify a few more things. // Only do this if we're not repeating the previous state. let prev_enabled = self.context.lock().unwrap().enabled; let default_adapter = self.context.lock().unwrap().default_adapter; if hci_interface == default_adapter && prev_enabled != enabled { self.context.lock().unwrap().enabled = enabled; self.context.lock().unwrap().adapter_ready = false; if enabled { self.context.lock().unwrap().create_adapter_proxy(hci_interface); } else { self.context.lock().unwrap().adapter_dbus = None; } } self.context.lock().unwrap().set_adapter_enabled(hci_interface, enabled); } } Loading Loading @@ -124,6 +102,10 @@ impl IBluetoothCallback for BtCallback { ); } } fn on_bond_state_changed(&self, status: u32, address: String, state: u32) { print_info!("Bonding state changed: [{}] state: {}, Status = {}", address, state, status); } } impl RPCProxy for BtCallback { Loading
system/gd/rust/linux/client/src/command_handler.rs +33 −9 Original line number Diff line number Diff line Loading @@ -112,10 +112,10 @@ fn build_commands() -> HashMap<String, CommandOption> { }, ); command_options.insert( String::from("list-devices"), String::from("list"), CommandOption { description: String::from( "List known remote devices from most recent discovery session.", "List bonded or found remote devices. Use: list <bonded|found>", ), function_pointer: CommandHandler::cmd_list_devices, }, Loading Loading @@ -239,10 +239,8 @@ impl CommandHandler { return; } let address = self.context.lock().unwrap().adapter_dbus.as_ref().unwrap().get_address(); let address = self.context.lock().unwrap().update_adapter_address(); print_info!("Local address = {}", &address); // Cache address for adapter show self.context.lock().unwrap().adapter_address = Some(address); } fn cmd_discovery(&mut self, args: &Vec<String>) { Loading Loading @@ -378,11 +376,37 @@ impl CommandHandler { self.command_options.keys().map(|key| String::from(key)).collect::<Vec<String>>() } fn cmd_list_devices(&mut self, _args: &Vec<String>) { fn cmd_list_devices(&mut self, args: &Vec<String>) { if !self.context.lock().unwrap().adapter_ready { self.adapter_not_ready(); return; } enforce_arg_len(args, 1, "list <bonded|found>", || match &args[0][0..] { "bonded" => { print_info!("Known bonded devices:"); let devices = self .context .lock() .unwrap() .adapter_dbus .as_ref() .unwrap() .get_bonded_devices(); for device in devices.iter() { print_info!("[{:17}] {}", device.address, device.name); } } "found" => { print_info!("Devices found in most recent discovery session:"); for (key, val) in self.context.lock().unwrap().found_devices.iter() { print_info!("[{:18}] {}", key, val.name); print_info!("[{:17}] {}", key, val.name); } } _ => { println!("Invalid argument '{}'", args[0]); } }); } } Loading
system/gd/rust/linux/client/src/dbus_iface.rs +20 −0 Original line number Diff line number Diff line Loading @@ -169,6 +169,9 @@ impl IBluetoothCallback for IBluetoothCallbackDBus { passkey: u32, ) { } #[dbus_method("OnBondStateChanged")] fn on_bond_state_changed(&self, status: u32, address: String, state: u32) {} } pub(crate) struct BluetoothDBus { Loading Loading @@ -240,6 +243,23 @@ impl IBluetooth for BluetoothDBus { ), ) } fn cancel_bond_process(&self, device: BluetoothDevice) -> bool { self.client_proxy.method("CancelBondProcess", (BluetoothDevice::to_dbus(device).unwrap(),)) } fn remove_bond(&self, device: BluetoothDevice) -> bool { self.client_proxy.method("RemoveBond", (BluetoothDevice::to_dbus(device).unwrap(),)) } fn get_bonded_devices(&self) -> Vec<BluetoothDevice> { let props: Vec<dbus::arg::PropMap> = self.client_proxy.method("GetBondedDevices", ()); <Vec<BluetoothDevice> as DBusArg>::from_dbus(props, None, None, None).unwrap() } fn get_bond_state(&self, device: BluetoothDevice) -> u32 { self.client_proxy.method("GetBondState", (BluetoothDevice::to_dbus(device).unwrap(),)) } } #[dbus_propmap(AdapterWithEnabled)] Loading
system/gd/rust/linux/client/src/main.rs +38 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,27 @@ impl ClientContext { } } // Sets required values for the adapter when enabling or disabling fn set_adapter_enabled(&mut self, hci_interface: i32, enabled: bool) { print_info!("hci{} enabled = {}", hci_interface, enabled); self.adapters.entry(hci_interface).and_modify(|v| *v = enabled).or_insert(enabled); // When the default adapter's state is updated, we need to modify a few more things. // Only do this if we're not repeating the previous state. let prev_enabled = self.enabled; let default_adapter = self.default_adapter; if hci_interface == default_adapter && prev_enabled != enabled { self.enabled = enabled; self.adapter_ready = false; if enabled { self.create_adapter_proxy(hci_interface); } else { self.adapter_dbus = None; } } } // Creates adapter proxy, registers callbacks and initializes address. fn create_adapter_proxy(&mut self, idx: i32) { let conn = self.dbus_connection.clone(); Loading @@ -117,6 +138,14 @@ impl ClientContext { let _ = fg.send(ForegroundActions::RegisterAdapterCallback(objpath)).await; }); } // Foreground-only: Updates the adapter address. fn update_adapter_address(&mut self) -> String { let address = self.adapter_dbus.as_ref().unwrap().get_address(); self.adapter_address = Some(address.clone()); address } } /// Actions to take on the foreground loop. This allows us to queue actions in Loading Loading @@ -171,6 +200,13 @@ fn main() -> Result<(), Box<dyn std::error::Error>> { context.clone(), ))); // Check if the default adapter is enabled. If yes, we should create the adapter proxy // right away. let default_adapter = context.lock().unwrap().default_adapter; if context.lock().unwrap().manager_dbus.get_adapter_enabled(default_adapter) { context.lock().unwrap().set_adapter_enabled(default_adapter, true); } let mut handler = CommandHandler::new(context.clone()); let args: Vec<String> = std::env::args().collect(); Loading Loading @@ -233,6 +269,8 @@ async fn start_interactive_shell( .unwrap() .register_callback(Box::new(BtCallback::new(objpath, context.clone()))); context.lock().unwrap().adapter_ready = true; let adapter_address = context.lock().unwrap().update_adapter_address(); print_info!("Adapter {} is ready", adapter_address); } ForegroundActions::Readline(result) => match result { Err(_err) => { Loading
system/gd/rust/linux/dbus_projection/dbus_macros/src/lib.rs +1 −3 Original line number Diff line number Diff line Loading @@ -33,9 +33,7 @@ pub fn dbus_method(_attr: TokenStream, item: TokenStream) -> TokenStream { /// Generates a function to export a Rust object to D-Bus. /// /// Example: /// ``` /// #[generate_dbus_exporter(export_foo_dbus_obj, "org.example.FooInterface")] /// ``` /// /// This generates a method called `export_foo_dbus_obj` that will export a Rust object into a /// D-Bus object having interface `org.example.FooInterface`. Loading