Loading system/gd/rust/linux/client/src/callbacks.rs +105 −2 Original line number Diff line number Diff line Loading @@ -2,11 +2,11 @@ use crate::dbus_iface::{ export_advertising_set_callback_dbus_intf, export_bluetooth_callback_dbus_intf, export_bluetooth_connection_callback_dbus_intf, export_bluetooth_gatt_callback_dbus_intf, export_bluetooth_manager_callback_dbus_intf, export_scanner_callback_dbus_intf, export_suspend_callback_dbus_intf, export_socket_callback_dbus_intf, export_suspend_callback_dbus_intf, }; use crate::ClientContext; use crate::{console_red, console_yellow, print_error, print_info}; use bt_topshim::btif::{BtBondState, BtPropertyType, BtSspVariant, Uuid128Bit}; use bt_topshim::btif::{BtBondState, BtPropertyType, BtSspVariant, BtStatus, Uuid128Bit}; use bt_topshim::profiles::gatt::GattStatus; use btstack::bluetooth::{ BluetoothDevice, IBluetooth, IBluetoothCallback, IBluetoothConnectionCallback, Loading @@ -15,6 +15,10 @@ use btstack::bluetooth_adv::IAdvertisingSetCallback; use btstack::bluetooth_gatt::{ BluetoothGattService, IBluetoothGattCallback, IScannerCallback, LePhy, ScanResult, }; use btstack::socket_manager::{ BluetoothServerSocket, BluetoothSocket, IBluetoothSocketManager, IBluetoothSocketManagerCallbacks, SocketId, }; use btstack::suspend::ISuspendCallback; use btstack::uuid::UuidWrapper; use btstack::RPCProxy; Loading Loading @@ -665,6 +669,105 @@ impl RPCProxy for BtGattCallback { } } pub(crate) struct BtSocketManagerCallback { objpath: String, context: Arc<Mutex<ClientContext>>, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, } impl BtSocketManagerCallback { 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 IBluetoothSocketManagerCallbacks for BtSocketManagerCallback { fn on_incoming_socket_ready(&mut self, socket: BluetoothServerSocket, status: BtStatus) { if status != BtStatus::Success { print_error!( "Incoming socket {} failed to be ready, type = {:?}, flags = {}, status = {:?}", socket.id, socket.sock_type, socket.flags, status, ); return; } print_info!( "Socket {} ready, details: {:?}, flags = {}, psm = {:?}, channel = {:?}, name = {:?}, uuid = {:?}", socket.id, socket.sock_type, socket.flags, socket.psm, socket.channel, socket.name, socket.uuid, ); let callback_id = self.context.lock().unwrap().socket_manager_callback_id.clone().unwrap(); self.context.lock().unwrap().run_callback(Box::new(move |context| { let status = context .lock() .unwrap() .socket_manager_dbus .as_mut() .unwrap() .close(callback_id, socket.id); if status != BtStatus::Success { print_error!("Failed to close socket {}, status = {:?}", socket.id, status); return; } print_info!("Requested for closing socket {}", socket.id); })); } fn on_incoming_socket_closed(&mut self, listener_id: SocketId, reason: BtStatus) { print_info!("Socket {} closed, reason = {:?}", listener_id, reason); } fn on_handle_incoming_connection( &mut self, listener_id: SocketId, connection: BluetoothSocket, ) { todo!(); } fn on_outgoing_connection_result( &mut self, connecting_id: SocketId, result: BtStatus, socket: Option<BluetoothSocket>, ) { todo!(); } } impl RPCProxy for BtSocketManagerCallback { fn get_object_id(&self) -> String { self.objpath.clone() } fn export_for_rpc(self: Box<Self>) { let cr = self.dbus_crossroads.clone(); let iface = export_socket_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))); } } /// Callback container for suspend interface callbacks. pub(crate) struct SuspendCallback { objpath: String, Loading system/gd/rust/linux/client/src/command_handler.rs +48 −1 Original line number Diff line number Diff line Loading @@ -5,10 +5,11 @@ use std::sync::{Arc, Mutex}; use crate::callbacks::BtGattCallback; use crate::ClientContext; use crate::{console_red, console_yellow, print_error, print_info}; use bt_topshim::btif::{BtConnectionState, BtTransport}; use bt_topshim::btif::{BtConnectionState, BtStatus, BtTransport}; use btstack::bluetooth::{BluetoothDevice, IBluetooth, IBluetoothQA}; use btstack::bluetooth_adv::{AdvertiseData, AdvertisingSetParameters}; use btstack::bluetooth_gatt::{IBluetoothGatt, RSSISettings, ScanSettings, ScanType}; use btstack::socket_manager::{IBluetoothSocketManager, SocketResult}; use btstack::uuid::{Profile, UuidHelper, UuidWrapper}; use manager_service::iface_bluetooth_manager::IBluetoothManager; Loading Loading @@ -165,6 +166,14 @@ fn build_commands() -> HashMap<String, CommandOption> { function_pointer: CommandHandler::cmd_advertise, }, ); command_options.insert( String::from("socket"), CommandOption { rules: vec![String::from("socket test")], description: String::from("Socket manager utilities."), function_pointer: CommandHandler::cmd_socket, }, ); command_options.insert( String::from("get-address"), CommandOption { Loading Loading @@ -964,6 +973,44 @@ impl CommandHandler { }); } fn cmd_socket(&mut self, args: &Vec<String>) { if !self.context.lock().unwrap().adapter_ready { self.adapter_not_ready(); return; } let callback_id = match self.context.lock().unwrap().socket_manager_callback_id.clone() { Some(id) => id, None => { return; } }; enforce_arg_len(args, 1, "socket <test>", || match &args[0][0..] { "test" => { let SocketResult { status, id } = self .context .lock() .unwrap() .socket_manager_dbus .as_mut() .unwrap() .listen_using_l2cap_channel(callback_id); if status != BtStatus::Success { print_error!( "Failed to request for listening using l2cap channel, status = {:?}", status, ); return; } print_info!("Requested for listening using l2cap channel on socket {}", id); } _ => { println!("Invalid argument '{}'", args[0]); } }); } /// Get the list of rules of supported commands pub fn get_command_rule_list(&self) -> Vec<String> { self.command_options.values().flat_map(|cmd| cmd.rules.clone()).collect() Loading system/gd/rust/linux/client/src/dbus_iface.rs +20 −8 Original line number Diff line number Diff line Loading @@ -1285,24 +1285,36 @@ pub struct SocketResultDBus { id: u64, } pub(crate) struct BluetoothSocketManagerDBusRPC { client_proxy: ClientDBusProxy, } pub(crate) struct BluetoothSocketManagerDBus { client_proxy: ClientDBusProxy, pub rpc: BluetoothSocketManagerDBusRPC, } impl BluetoothSocketManagerDBus { pub(crate) fn _new(conn: Arc<SyncConnection>, index: i32) -> Self { BluetoothSocketManagerDBus { 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, "adapter"), String::from("org.chromium.bluetooth.SocketManager"), ), ) } pub(crate) fn new(conn: Arc<SyncConnection>, index: i32) -> Self { BluetoothSocketManagerDBus { client_proxy: Self::make_client_proxy(conn.clone(), index), rpc: BluetoothSocketManagerDBusRPC { client_proxy: Self::make_client_proxy(conn.clone(), index), }, } } } #[generate_dbus_interface_client] #[generate_dbus_interface_client(BluetoothSocketManagerDBusRPC)] impl IBluetoothSocketManager for BluetoothSocketManagerDBus { #[dbus_method("RegisterCallback")] fn register_callback( Loading system/gd/rust/linux/client/src/main.rs +35 −3 Original line number Diff line number Diff line Loading @@ -8,12 +8,13 @@ use dbus_crossroads::Crossroads; use tokio::sync::mpsc; use crate::callbacks::{ AdvertisingSetCallback, BtCallback, BtConnectionCallback, BtManagerCallback, ScannerCallback, SuspendCallback, AdvertisingSetCallback, BtCallback, BtConnectionCallback, BtManagerCallback, BtSocketManagerCallback, ScannerCallback, SuspendCallback, }; use crate::command_handler::CommandHandler; use crate::dbus_iface::{ BluetoothDBus, BluetoothGattDBus, BluetoothManagerDBus, BluetoothQADBus, SuspendDBus, BluetoothDBus, BluetoothGattDBus, BluetoothManagerDBus, BluetoothQADBus, BluetoothSocketManagerDBus, SuspendDBus, }; use crate::editor::AsyncEditor; use bt_topshim::topstack; Loading Loading @@ -79,6 +80,9 @@ pub(crate) struct ClientContext { /// Proxy for suspend interface. pub(crate) suspend_dbus: Option<SuspendDBus>, /// Proxy for socket manager interface. pub(crate) socket_manager_dbus: Option<BluetoothSocketManagerDBus>, /// Channel to send actions to take in the foreground fg: mpsc::Sender<ForegroundActions>, Loading @@ -99,6 +103,9 @@ pub(crate) struct ClientContext { /// Advertising sets started/registered. Map from reg_id to advertiser_id. adv_sets: HashMap<i32, Option<i32>>, /// Identifies the callback to receive IBluetoothSocketManagerCallback method calls. socket_manager_callback_id: Option<u32>, } impl ClientContext { Loading Loading @@ -127,6 +134,7 @@ impl ClientContext { qa_dbus: None, gatt_dbus: None, suspend_dbus: None, socket_manager_dbus: None, fg: tx, dbus_connection, dbus_crossroads, Loading @@ -134,6 +142,7 @@ impl ClientContext { advertiser_callback_id: None, active_scanner_ids: HashSet::new(), adv_sets: HashMap::new(), socket_manager_callback_id: None, } } Loading Loading @@ -169,6 +178,9 @@ impl ClientContext { let gatt_dbus = BluetoothGattDBus::new(conn.clone(), idx); self.gatt_dbus = Some(gatt_dbus); let socket_manager_dbus = BluetoothSocketManagerDBus::new(conn.clone(), idx); self.socket_manager_dbus = Some(socket_manager_dbus); self.suspend_dbus = Some(SuspendDBus::new(conn.clone(), idx)); // Trigger callback registration in the foreground Loading Loading @@ -393,6 +405,8 @@ async fn start_interactive_shell( format!("/org/chromium/bluetooth/client/{}/scanner_callback", adapter); let advertiser_cb_objpath: String = format!("/org/chromium/bluetooth/client/{}/advertising_set_callback", adapter); let socket_manager_cb_objpath: String = format!("/org/chromium/bluetooth/client/{}/socket_manager_callback", adapter); let dbus_connection = context.lock().unwrap().dbus_connection.clone(); let dbus_crossroads = context.lock().unwrap().dbus_crossroads.clone(); Loading Loading @@ -463,6 +477,24 @@ async fn start_interactive_shell( .expect("D-Bus error on IBluetoothGatt::RegisterAdvertiserCallback"); context.lock().unwrap().advertiser_callback_id = Some(advertiser_callback_id); let socket_manager_callback_id = context .lock() .unwrap() .socket_manager_dbus .as_mut() .unwrap() .rpc .register_callback(Box::new(BtSocketManagerCallback::new( socket_manager_cb_objpath.clone(), context.clone(), dbus_connection.clone(), dbus_crossroads.clone(), ))) .await .expect("D-Bus error on IBluetoothSocketManager::RegisterCallback"); context.lock().unwrap().socket_manager_callback_id = Some(socket_manager_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 Loading
system/gd/rust/linux/client/src/callbacks.rs +105 −2 Original line number Diff line number Diff line Loading @@ -2,11 +2,11 @@ use crate::dbus_iface::{ export_advertising_set_callback_dbus_intf, export_bluetooth_callback_dbus_intf, export_bluetooth_connection_callback_dbus_intf, export_bluetooth_gatt_callback_dbus_intf, export_bluetooth_manager_callback_dbus_intf, export_scanner_callback_dbus_intf, export_suspend_callback_dbus_intf, export_socket_callback_dbus_intf, export_suspend_callback_dbus_intf, }; use crate::ClientContext; use crate::{console_red, console_yellow, print_error, print_info}; use bt_topshim::btif::{BtBondState, BtPropertyType, BtSspVariant, Uuid128Bit}; use bt_topshim::btif::{BtBondState, BtPropertyType, BtSspVariant, BtStatus, Uuid128Bit}; use bt_topshim::profiles::gatt::GattStatus; use btstack::bluetooth::{ BluetoothDevice, IBluetooth, IBluetoothCallback, IBluetoothConnectionCallback, Loading @@ -15,6 +15,10 @@ use btstack::bluetooth_adv::IAdvertisingSetCallback; use btstack::bluetooth_gatt::{ BluetoothGattService, IBluetoothGattCallback, IScannerCallback, LePhy, ScanResult, }; use btstack::socket_manager::{ BluetoothServerSocket, BluetoothSocket, IBluetoothSocketManager, IBluetoothSocketManagerCallbacks, SocketId, }; use btstack::suspend::ISuspendCallback; use btstack::uuid::UuidWrapper; use btstack::RPCProxy; Loading Loading @@ -665,6 +669,105 @@ impl RPCProxy for BtGattCallback { } } pub(crate) struct BtSocketManagerCallback { objpath: String, context: Arc<Mutex<ClientContext>>, dbus_connection: Arc<SyncConnection>, dbus_crossroads: Arc<Mutex<Crossroads>>, } impl BtSocketManagerCallback { 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 IBluetoothSocketManagerCallbacks for BtSocketManagerCallback { fn on_incoming_socket_ready(&mut self, socket: BluetoothServerSocket, status: BtStatus) { if status != BtStatus::Success { print_error!( "Incoming socket {} failed to be ready, type = {:?}, flags = {}, status = {:?}", socket.id, socket.sock_type, socket.flags, status, ); return; } print_info!( "Socket {} ready, details: {:?}, flags = {}, psm = {:?}, channel = {:?}, name = {:?}, uuid = {:?}", socket.id, socket.sock_type, socket.flags, socket.psm, socket.channel, socket.name, socket.uuid, ); let callback_id = self.context.lock().unwrap().socket_manager_callback_id.clone().unwrap(); self.context.lock().unwrap().run_callback(Box::new(move |context| { let status = context .lock() .unwrap() .socket_manager_dbus .as_mut() .unwrap() .close(callback_id, socket.id); if status != BtStatus::Success { print_error!("Failed to close socket {}, status = {:?}", socket.id, status); return; } print_info!("Requested for closing socket {}", socket.id); })); } fn on_incoming_socket_closed(&mut self, listener_id: SocketId, reason: BtStatus) { print_info!("Socket {} closed, reason = {:?}", listener_id, reason); } fn on_handle_incoming_connection( &mut self, listener_id: SocketId, connection: BluetoothSocket, ) { todo!(); } fn on_outgoing_connection_result( &mut self, connecting_id: SocketId, result: BtStatus, socket: Option<BluetoothSocket>, ) { todo!(); } } impl RPCProxy for BtSocketManagerCallback { fn get_object_id(&self) -> String { self.objpath.clone() } fn export_for_rpc(self: Box<Self>) { let cr = self.dbus_crossroads.clone(); let iface = export_socket_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))); } } /// Callback container for suspend interface callbacks. pub(crate) struct SuspendCallback { objpath: String, Loading
system/gd/rust/linux/client/src/command_handler.rs +48 −1 Original line number Diff line number Diff line Loading @@ -5,10 +5,11 @@ use std::sync::{Arc, Mutex}; use crate::callbacks::BtGattCallback; use crate::ClientContext; use crate::{console_red, console_yellow, print_error, print_info}; use bt_topshim::btif::{BtConnectionState, BtTransport}; use bt_topshim::btif::{BtConnectionState, BtStatus, BtTransport}; use btstack::bluetooth::{BluetoothDevice, IBluetooth, IBluetoothQA}; use btstack::bluetooth_adv::{AdvertiseData, AdvertisingSetParameters}; use btstack::bluetooth_gatt::{IBluetoothGatt, RSSISettings, ScanSettings, ScanType}; use btstack::socket_manager::{IBluetoothSocketManager, SocketResult}; use btstack::uuid::{Profile, UuidHelper, UuidWrapper}; use manager_service::iface_bluetooth_manager::IBluetoothManager; Loading Loading @@ -165,6 +166,14 @@ fn build_commands() -> HashMap<String, CommandOption> { function_pointer: CommandHandler::cmd_advertise, }, ); command_options.insert( String::from("socket"), CommandOption { rules: vec![String::from("socket test")], description: String::from("Socket manager utilities."), function_pointer: CommandHandler::cmd_socket, }, ); command_options.insert( String::from("get-address"), CommandOption { Loading Loading @@ -964,6 +973,44 @@ impl CommandHandler { }); } fn cmd_socket(&mut self, args: &Vec<String>) { if !self.context.lock().unwrap().adapter_ready { self.adapter_not_ready(); return; } let callback_id = match self.context.lock().unwrap().socket_manager_callback_id.clone() { Some(id) => id, None => { return; } }; enforce_arg_len(args, 1, "socket <test>", || match &args[0][0..] { "test" => { let SocketResult { status, id } = self .context .lock() .unwrap() .socket_manager_dbus .as_mut() .unwrap() .listen_using_l2cap_channel(callback_id); if status != BtStatus::Success { print_error!( "Failed to request for listening using l2cap channel, status = {:?}", status, ); return; } print_info!("Requested for listening using l2cap channel on socket {}", id); } _ => { println!("Invalid argument '{}'", args[0]); } }); } /// Get the list of rules of supported commands pub fn get_command_rule_list(&self) -> Vec<String> { self.command_options.values().flat_map(|cmd| cmd.rules.clone()).collect() Loading
system/gd/rust/linux/client/src/dbus_iface.rs +20 −8 Original line number Diff line number Diff line Loading @@ -1285,24 +1285,36 @@ pub struct SocketResultDBus { id: u64, } pub(crate) struct BluetoothSocketManagerDBusRPC { client_proxy: ClientDBusProxy, } pub(crate) struct BluetoothSocketManagerDBus { client_proxy: ClientDBusProxy, pub rpc: BluetoothSocketManagerDBusRPC, } impl BluetoothSocketManagerDBus { pub(crate) fn _new(conn: Arc<SyncConnection>, index: i32) -> Self { BluetoothSocketManagerDBus { 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, "adapter"), String::from("org.chromium.bluetooth.SocketManager"), ), ) } pub(crate) fn new(conn: Arc<SyncConnection>, index: i32) -> Self { BluetoothSocketManagerDBus { client_proxy: Self::make_client_proxy(conn.clone(), index), rpc: BluetoothSocketManagerDBusRPC { client_proxy: Self::make_client_proxy(conn.clone(), index), }, } } } #[generate_dbus_interface_client] #[generate_dbus_interface_client(BluetoothSocketManagerDBusRPC)] impl IBluetoothSocketManager for BluetoothSocketManagerDBus { #[dbus_method("RegisterCallback")] fn register_callback( Loading
system/gd/rust/linux/client/src/main.rs +35 −3 Original line number Diff line number Diff line Loading @@ -8,12 +8,13 @@ use dbus_crossroads::Crossroads; use tokio::sync::mpsc; use crate::callbacks::{ AdvertisingSetCallback, BtCallback, BtConnectionCallback, BtManagerCallback, ScannerCallback, SuspendCallback, AdvertisingSetCallback, BtCallback, BtConnectionCallback, BtManagerCallback, BtSocketManagerCallback, ScannerCallback, SuspendCallback, }; use crate::command_handler::CommandHandler; use crate::dbus_iface::{ BluetoothDBus, BluetoothGattDBus, BluetoothManagerDBus, BluetoothQADBus, SuspendDBus, BluetoothDBus, BluetoothGattDBus, BluetoothManagerDBus, BluetoothQADBus, BluetoothSocketManagerDBus, SuspendDBus, }; use crate::editor::AsyncEditor; use bt_topshim::topstack; Loading Loading @@ -79,6 +80,9 @@ pub(crate) struct ClientContext { /// Proxy for suspend interface. pub(crate) suspend_dbus: Option<SuspendDBus>, /// Proxy for socket manager interface. pub(crate) socket_manager_dbus: Option<BluetoothSocketManagerDBus>, /// Channel to send actions to take in the foreground fg: mpsc::Sender<ForegroundActions>, Loading @@ -99,6 +103,9 @@ pub(crate) struct ClientContext { /// Advertising sets started/registered. Map from reg_id to advertiser_id. adv_sets: HashMap<i32, Option<i32>>, /// Identifies the callback to receive IBluetoothSocketManagerCallback method calls. socket_manager_callback_id: Option<u32>, } impl ClientContext { Loading Loading @@ -127,6 +134,7 @@ impl ClientContext { qa_dbus: None, gatt_dbus: None, suspend_dbus: None, socket_manager_dbus: None, fg: tx, dbus_connection, dbus_crossroads, Loading @@ -134,6 +142,7 @@ impl ClientContext { advertiser_callback_id: None, active_scanner_ids: HashSet::new(), adv_sets: HashMap::new(), socket_manager_callback_id: None, } } Loading Loading @@ -169,6 +178,9 @@ impl ClientContext { let gatt_dbus = BluetoothGattDBus::new(conn.clone(), idx); self.gatt_dbus = Some(gatt_dbus); let socket_manager_dbus = BluetoothSocketManagerDBus::new(conn.clone(), idx); self.socket_manager_dbus = Some(socket_manager_dbus); self.suspend_dbus = Some(SuspendDBus::new(conn.clone(), idx)); // Trigger callback registration in the foreground Loading Loading @@ -393,6 +405,8 @@ async fn start_interactive_shell( format!("/org/chromium/bluetooth/client/{}/scanner_callback", adapter); let advertiser_cb_objpath: String = format!("/org/chromium/bluetooth/client/{}/advertising_set_callback", adapter); let socket_manager_cb_objpath: String = format!("/org/chromium/bluetooth/client/{}/socket_manager_callback", adapter); let dbus_connection = context.lock().unwrap().dbus_connection.clone(); let dbus_crossroads = context.lock().unwrap().dbus_crossroads.clone(); Loading Loading @@ -463,6 +477,24 @@ async fn start_interactive_shell( .expect("D-Bus error on IBluetoothGatt::RegisterAdvertiserCallback"); context.lock().unwrap().advertiser_callback_id = Some(advertiser_callback_id); let socket_manager_callback_id = context .lock() .unwrap() .socket_manager_dbus .as_mut() .unwrap() .rpc .register_callback(Box::new(BtSocketManagerCallback::new( socket_manager_cb_objpath.clone(), context.clone(), dbus_connection.clone(), dbus_crossroads.clone(), ))) .await .expect("D-Bus error on IBluetoothSocketManager::RegisterCallback"); context.lock().unwrap().socket_manager_callback_id = Some(socket_manager_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