summaryrefslogtreecommitdiff
path: root/system/gd/rust/linux/client/src
diff options
context:
space:
mode:
Diffstat (limited to 'system/gd/rust/linux/client/src')
-rw-r--r--system/gd/rust/linux/client/src/callbacks.rs99
-rw-r--r--system/gd/rust/linux/client/src/command_handler.rs5
-rw-r--r--system/gd/rust/linux/client/src/dbus_iface.rs95
-rw-r--r--system/gd/rust/linux/client/src/main.rs33
4 files changed, 150 insertions, 82 deletions
diff --git a/system/gd/rust/linux/client/src/callbacks.rs b/system/gd/rust/linux/client/src/callbacks.rs
index 1d663933a7..0eada97d18 100644
--- a/system/gd/rust/linux/client/src/callbacks.rs
+++ b/system/gd/rust/linux/client/src/callbacks.rs
@@ -1,3 +1,7 @@
+use crate::dbus_iface::{
+ export_bluetooth_callback_dbus_obj, export_bluetooth_connection_callback_dbus_obj,
+ export_bluetooth_gatt_callback_dbus_obj, export_bluetooth_manager_callback_dbus_obj,
+};
use crate::ClientContext;
use crate::{console_yellow, print_info};
use bt_topshim::btif::{BtBondState, BtSspVariant};
@@ -7,6 +11,9 @@ use btstack::bluetooth::{
};
use btstack::bluetooth_gatt::{BluetoothGattService, IBluetoothGattCallback, LePhy};
use btstack::RPCProxy;
+use dbus::nonblock::SyncConnection;
+use dbus_crossroads::Crossroads;
+use dbus_projection::DisconnectWatcher;
use manager_service::iface_bluetooth_manager::IBluetoothManagerCallback;
use std::sync::{Arc, Mutex};
@@ -14,11 +21,19 @@ use std::sync::{Arc, Mutex};
pub(crate) struct BtManagerCallback {
objpath: String,
context: Arc<Mutex<ClientContext>>,
+
+ dbus_connection: Arc<SyncConnection>,
+ dbus_crossroads: Arc<Mutex<Crossroads>>,
}
impl BtManagerCallback {
- pub(crate) fn new(objpath: String, context: Arc<Mutex<ClientContext>>) -> Self {
- Self { objpath, context }
+ 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 }
}
}
@@ -50,17 +65,36 @@ impl manager_service::RPCProxy for BtManagerCallback {
fn unregister(&mut self, _id: u32) -> bool {
false
}
+
+ fn export_for_rpc(self: Box<Self>) {
+ let cr = self.dbus_crossroads.clone();
+ export_bluetooth_manager_callback_dbus_obj(
+ self.get_object_id(),
+ self.dbus_connection.clone(),
+ &mut cr.lock().unwrap(),
+ Arc::new(Mutex::new(self)),
+ Arc::new(Mutex::new(DisconnectWatcher::new())),
+ );
+ }
}
/// Callback container for adapter interface callbacks.
pub(crate) struct BtCallback {
objpath: String,
context: Arc<Mutex<ClientContext>>,
+
+ dbus_connection: Arc<SyncConnection>,
+ dbus_crossroads: Arc<Mutex<Crossroads>>,
}
impl BtCallback {
- pub(crate) fn new(objpath: String, context: Arc<Mutex<ClientContext>>) -> Self {
- Self { objpath, context }
+ 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 }
}
}
@@ -179,16 +213,35 @@ impl RPCProxy for BtCallback {
fn unregister(&mut self, _id: u32) -> bool {
false
}
+
+ fn export_for_rpc(self: Box<Self>) {
+ let cr = self.dbus_crossroads.clone();
+ export_bluetooth_callback_dbus_obj(
+ self.get_object_id(),
+ self.dbus_connection.clone(),
+ &mut cr.lock().unwrap(),
+ Arc::new(Mutex::new(self)),
+ Arc::new(Mutex::new(DisconnectWatcher::new())),
+ );
+ }
}
pub(crate) struct BtConnectionCallback {
objpath: String,
_context: Arc<Mutex<ClientContext>>,
+
+ dbus_connection: Arc<SyncConnection>,
+ dbus_crossroads: Arc<Mutex<Crossroads>>,
}
impl BtConnectionCallback {
- pub(crate) fn new(objpath: String, _context: Arc<Mutex<ClientContext>>) -> Self {
- Self { objpath, _context }
+ 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 }
}
}
@@ -214,16 +267,35 @@ impl RPCProxy for BtConnectionCallback {
fn unregister(&mut self, _id: u32) -> bool {
false
}
+
+ fn export_for_rpc(self: Box<Self>) {
+ let cr = self.dbus_crossroads.clone();
+ export_bluetooth_connection_callback_dbus_obj(
+ self.get_object_id(),
+ self.dbus_connection.clone(),
+ &mut cr.lock().unwrap(),
+ Arc::new(Mutex::new(self)),
+ Arc::new(Mutex::new(DisconnectWatcher::new())),
+ );
+ }
}
pub(crate) struct BtGattCallback {
objpath: String,
context: Arc<Mutex<ClientContext>>,
+
+ dbus_connection: Arc<SyncConnection>,
+ dbus_crossroads: Arc<Mutex<Crossroads>>,
}
impl BtGattCallback {
- pub(crate) fn new(objpath: String, context: Arc<Mutex<ClientContext>>) -> Self {
- Self { objpath, context }
+ 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 }
}
}
@@ -367,4 +439,15 @@ impl RPCProxy for BtGattCallback {
fn unregister(&mut self, _id: u32) -> bool {
false
}
+
+ fn export_for_rpc(self: Box<Self>) {
+ let cr = self.dbus_crossroads.clone();
+ export_bluetooth_gatt_callback_dbus_obj(
+ self.get_object_id(),
+ self.dbus_connection.clone(),
+ &mut cr.lock().unwrap(),
+ Arc::new(Mutex::new(self)),
+ Arc::new(Mutex::new(DisconnectWatcher::new())),
+ );
+ }
}
diff --git a/system/gd/rust/linux/client/src/command_handler.rs b/system/gd/rust/linux/client/src/command_handler.rs
index 284654e444..99711c2edd 100644
--- a/system/gd/rust/linux/client/src/command_handler.rs
+++ b/system/gd/rust/linux/client/src/command_handler.rs
@@ -538,11 +538,16 @@ impl CommandHandler {
enforce_arg_len(args, 1, "gatt <commands>", || match &args[0][0..] {
"register-client" => {
+ let dbus_connection = self.context.lock().unwrap().dbus_connection.clone();
+ let dbus_crossroads = self.context.lock().unwrap().dbus_crossroads.clone();
+
self.context.lock().unwrap().gatt_dbus.as_mut().unwrap().register_client(
String::from(GATT_CLIENT_APP_UUID),
Box::new(BtGattCallback::new(
String::from("/org/chromium/bluetooth/client/bluetooth_gatt_callback"),
self.context.clone(),
+ dbus_connection,
+ dbus_crossroads,
)),
false,
);
diff --git a/system/gd/rust/linux/client/src/dbus_iface.rs b/system/gd/rust/linux/client/src/dbus_iface.rs
index 3d7994eb85..dfd79eb924 100644
--- a/system/gd/rust/linux/client/src/dbus_iface.rs
+++ b/system/gd/rust/linux/client/src/dbus_iface.rs
@@ -15,8 +15,6 @@ use btstack::bluetooth_gatt::{
use dbus::arg::{AppendAll, RefArg};
use dbus::nonblock::SyncConnection;
-use dbus_crossroads::Crossroads;
-
use dbus_projection::{impl_dbus_arg_enum, DisconnectWatcher};
use dbus_macros::{
@@ -30,7 +28,7 @@ use manager_service::iface_bluetooth_manager::{
use num_traits::{FromPrimitive, ToPrimitive};
use std::convert::TryInto;
-use std::sync::{Arc, Mutex};
+use std::sync::Arc;
use crate::dbus_arg::{DBusArg, DBusArgError, RefArgToRust};
@@ -98,7 +96,6 @@ pub struct BluetoothDeviceDBus {
struct ClientDBusProxy {
conn: Arc<SyncConnection>,
- cr: Arc<Mutex<Crossroads>>,
bus_name: String,
objpath: dbus::Path<'static>,
interface: String,
@@ -160,6 +157,7 @@ impl btstack::RPCProxy for IBluetoothCallbackDBus {
fn unregister(&mut self, _id: u32) -> bool {
false
}
+ fn export_for_rpc(self: Box<Self>) {}
}
#[generate_dbus_exporter(
@@ -204,6 +202,7 @@ impl btstack::RPCProxy for IBluetoothConnectionCallbackDBus {
fn unregister(&mut self, _id: u32) -> bool {
false
}
+ fn export_for_rpc(self: Box<Self>) {}
}
#[generate_dbus_exporter(
@@ -223,15 +222,10 @@ pub(crate) struct BluetoothDBus {
}
impl BluetoothDBus {
- pub(crate) fn new(
- conn: Arc<SyncConnection>,
- cr: Arc<Mutex<Crossroads>>,
- index: i32,
- ) -> BluetoothDBus {
+ pub(crate) fn new(conn: Arc<SyncConnection>, index: i32) -> BluetoothDBus {
BluetoothDBus {
client_proxy: ClientDBusProxy {
conn: conn.clone(),
- cr: cr,
bus_name: String::from("org.chromium.bluetooth"),
objpath: make_object_path(index, "adapter"),
interface: String::from("org.chromium.bluetooth.Bluetooth"),
@@ -240,37 +234,31 @@ impl BluetoothDBus {
}
}
+trait DBusExportable {}
+
#[generate_dbus_interface_client]
impl IBluetooth for BluetoothDBus {
fn register_callback(&mut self, callback: Box<dyn IBluetoothCallback + Send>) {
- let path_string = callback.get_object_id();
- let path = dbus::Path::new(path_string.clone()).unwrap();
- export_bluetooth_callback_dbus_obj(
- path_string,
- self.client_proxy.conn.clone(),
- &mut self.client_proxy.cr.lock().unwrap(),
- Arc::new(Mutex::new(callback)),
- Arc::new(Mutex::new(DisconnectWatcher::new())),
- );
+ let callback = {
+ let path = dbus::Path::new(callback.get_object_id()).unwrap();
+ callback.export_for_rpc();
+ path
+ };
- self.client_proxy.method_noreturn("RegisterCallback", (path,))
+ self.client_proxy.method_noreturn("RegisterCallback", (callback,))
}
fn register_connection_callback(
&mut self,
callback: Box<dyn IBluetoothConnectionCallback + Send>,
) -> u32 {
- let path_string = callback.get_object_id();
- let path = dbus::Path::new(path_string.clone()).unwrap();
- export_bluetooth_connection_callback_dbus_obj(
- path_string,
- self.client_proxy.conn.clone(),
- &mut self.client_proxy.cr.lock().unwrap(),
- Arc::new(Mutex::new(callback)),
- Arc::new(Mutex::new(DisconnectWatcher::new())),
- );
+ let callback = {
+ let path = dbus::Path::new(callback.get_object_id()).unwrap();
+ callback.export_for_rpc();
+ path
+ };
- self.client_proxy.method("RegisterConnectionCallback", (path,))
+ self.client_proxy.method("RegisterConnectionCallback", (callback,))
}
#[dbus_method("UnregisterConnectionCallback")]
@@ -445,14 +433,10 @@ pub(crate) struct BluetoothManagerDBus {
}
impl BluetoothManagerDBus {
- pub(crate) fn new(
- conn: Arc<SyncConnection>,
- cr: Arc<Mutex<Crossroads>>,
- ) -> BluetoothManagerDBus {
+ pub(crate) fn new(conn: Arc<SyncConnection>) -> BluetoothManagerDBus {
BluetoothManagerDBus {
client_proxy: ClientDBusProxy {
conn: conn.clone(),
- cr: cr,
bus_name: String::from("org.chromium.bluetooth.Manager"),
objpath: dbus::Path::new("/org/chromium/bluetooth/Manager").unwrap(),
interface: String::from("org.chromium.bluetooth.Manager"),
@@ -486,17 +470,13 @@ impl IBluetoothManager for BluetoothManagerDBus {
// `generate_dbus_interface_client` doesn't support callback types yet.
// TODO(b/200732080): Support autogenerate code for callback types.
fn register_callback(&mut self, callback: Box<dyn IBluetoothManagerCallback + Send>) {
- let path_string = callback.get_object_id();
- let path = dbus::Path::new(path_string.clone()).unwrap();
- export_bluetooth_manager_callback_dbus_obj(
- path_string,
- self.client_proxy.conn.clone(),
- &mut self.client_proxy.cr.lock().unwrap(),
- Arc::new(Mutex::new(callback)),
- Arc::new(Mutex::new(DisconnectWatcher::new())),
- );
+ let callback = {
+ let path = dbus::Path::new(callback.get_object_id()).unwrap();
+ callback.export_for_rpc();
+ path
+ };
- self.client_proxy.method_noreturn("RegisterCallback", (path,))
+ self.client_proxy.method_noreturn("RegisterCallback", (callback,))
}
#[dbus_method("GetFlossEnabled")]
@@ -529,6 +509,7 @@ impl manager_service::RPCProxy for IBluetoothManagerCallbackDBus {
fn unregister(&mut self, _id: u32) -> bool {
false
}
+ fn export_for_rpc(self: Box<Self>) {}
}
#[generate_dbus_exporter(
@@ -548,15 +529,10 @@ pub(crate) struct BluetoothGattDBus {
}
impl BluetoothGattDBus {
- pub(crate) fn new(
- conn: Arc<SyncConnection>,
- cr: Arc<Mutex<Crossroads>>,
- index: i32,
- ) -> BluetoothGattDBus {
+ pub(crate) fn new(conn: Arc<SyncConnection>, index: i32) -> BluetoothGattDBus {
BluetoothGattDBus {
client_proxy: ClientDBusProxy {
conn: conn.clone(),
- cr: cr,
bus_name: String::from("org.chromium.bluetooth"),
objpath: make_object_path(index, "gatt"),
interface: String::from("org.chromium.bluetooth.BluetoothGatt"),
@@ -589,17 +565,13 @@ impl IBluetoothGatt for BluetoothGattDBus {
callback: Box<dyn IBluetoothGattCallback + Send>,
eatt_support: bool,
) {
- let path_string = callback.get_object_id();
- let path = dbus::Path::new(path_string.clone()).unwrap();
- export_bluetooth_gatt_callback_dbus_obj(
- path_string,
- self.client_proxy.conn.clone(),
- &mut self.client_proxy.cr.lock().unwrap(),
- Arc::new(Mutex::new(callback)),
- Arc::new(Mutex::new(DisconnectWatcher::new())),
- );
+ let callback = {
+ let path = dbus::Path::new(callback.get_object_id()).unwrap();
+ callback.export_for_rpc();
+ path
+ };
- self.client_proxy.method_noreturn("RegisterClient", (app_uuid, path, eatt_support))
+ self.client_proxy.method_noreturn("RegisterClient", (app_uuid, callback, eatt_support))
}
#[dbus_method("UnregisterClient")]
@@ -760,6 +732,7 @@ impl btstack::RPCProxy for IBluetoothGattCallbackDBus {
fn unregister(&mut self, _id: u32) -> bool {
false
}
+ fn export_for_rpc(self: Box<Self>) {}
}
#[generate_dbus_exporter(
diff --git a/system/gd/rust/linux/client/src/main.rs b/system/gd/rust/linux/client/src/main.rs
index 65116bbcd6..bea9d6c7a3 100644
--- a/system/gd/rust/linux/client/src/main.rs
+++ b/system/gd/rust/linux/client/src/main.rs
@@ -82,8 +82,7 @@ impl ClientContext {
) -> ClientContext {
// Manager interface is almost always available but adapter interface
// requires that the specific adapter is enabled.
- let manager_dbus =
- BluetoothManagerDBus::new(dbus_connection.clone(), dbus_crossroads.clone());
+ let manager_dbus = BluetoothManagerDBus::new(dbus_connection.clone());
ClientContext {
adapters: HashMap::new(),
@@ -128,12 +127,11 @@ impl ClientContext {
// Creates adapter proxy, registers callbacks and initializes address.
fn create_adapter_proxy(&mut self, idx: i32) {
let conn = self.dbus_connection.clone();
- let cr = self.dbus_crossroads.clone();
- let dbus = BluetoothDBus::new(conn.clone(), cr.clone(), idx);
+ let dbus = BluetoothDBus::new(conn.clone(), idx);
self.adapter_dbus = Some(dbus);
- let gatt_dbus = BluetoothGattDBus::new(conn.clone(), cr.clone(), idx);
+ let gatt_dbus = BluetoothGattDBus::new(conn.clone(), idx);
self.gatt_dbus = Some(gatt_dbus);
// Trigger callback registration in the foreground
@@ -212,7 +210,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let (tx, rx) = mpsc::channel::<ForegroundActions>(10);
// Create the context needed for handling commands
- let context = Arc::new(Mutex::new(ClientContext::new(conn, cr, tx.clone())));
+ let context =
+ Arc::new(Mutex::new(ClientContext::new(conn.clone(), cr.clone(), tx.clone())));
// Check if manager interface is valid. We only print some help text before failing on the
// first actual access to the interface (so we can also capture the actual reason the
@@ -228,6 +227,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
context.lock().unwrap().manager_dbus.register_callback(Box::new(BtManagerCallback::new(
String::from("/org/chromium/bluetooth/client/bluetooth_manager_callback"),
context.clone(),
+ conn.clone(),
+ cr.clone(),
)));
// Check if the default adapter is enabled. If yes, we should create the adapter proxy
@@ -312,13 +313,17 @@ async fn start_interactive_shell(
let conn_cb_objpath: String =
format!("/org/chromium/bluetooth/client/{}/bluetooth_conn_callback", adapter);
- context
- .lock()
- .unwrap()
- .adapter_dbus
- .as_mut()
- .unwrap()
- .register_callback(Box::new(BtCallback::new(cb_objpath, context.clone())));
+ let dbus_connection = context.lock().unwrap().dbus_connection.clone();
+ let dbus_crossroads = context.lock().unwrap().dbus_crossroads.clone();
+
+ context.lock().unwrap().adapter_dbus.as_mut().unwrap().register_callback(Box::new(
+ BtCallback::new(
+ cb_objpath,
+ context.clone(),
+ dbus_connection.clone(),
+ dbus_crossroads.clone(),
+ ),
+ ));
context
.lock()
.unwrap()
@@ -328,6 +333,8 @@ async fn start_interactive_shell(
.register_connection_callback(Box::new(BtConnectionCallback::new(
conn_cb_objpath,
context.clone(),
+ dbus_connection.clone(),
+ dbus_crossroads.clone(),
)));
context.lock().unwrap().adapter_ready = true;
let adapter_address = context.lock().unwrap().update_adapter_address();