Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b0deb0dd authored by Abhishek Pandit-Subedi's avatar Abhishek Pandit-Subedi Committed by Abhishek Pandit-Subedi
Browse files

floss: Implement ConnectAllEnabledProfiles + Disconnect

Add implementation for ConnectAllEnabledProfiles and
DisconnectAllEnabledProfiles. Currently, we only support connecting to
HID and HOGP devices.

Bug: 196887265
Tag: #floss
Test: btclient on ChromeOS with HID device

Change-Id: I4c754fd635779fd04607cdba97ec51754db49bf3
parent 3d679ab6
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
use crate::ClientContext;
use crate::{console_yellow, print_info};
use bt_topshim::btif::BtSspVariant;
use bt_topshim::btif::{BtBondState, BtSspVariant};
use bt_topshim::profiles::gatt::GattStatus;
use btstack::bluetooth::{BluetoothDevice, IBluetoothCallback, IBluetoothConnectionCallback};
use btstack::bluetooth_gatt::{BluetoothGattService, IBluetoothGattCallback, LePhy};
@@ -109,6 +109,14 @@ 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);

        // If bonded, we should also automatically connect all enabled profiles
        if BtBondState::Bonded == state.into() {
            self.context.lock().unwrap().connect_all_enabled_profiles(BluetoothDevice {
                address,
                name: String::from("Classic device"),
            });
        }
    }
}

+79 −52
Original line number Diff line number Diff line
@@ -7,9 +7,9 @@ use num_traits::cast::FromPrimitive;
use crate::callbacks::BtGattCallback;
use crate::ClientContext;
use crate::{console_red, console_yellow, print_error, print_info};
use bt_topshim::btif::Uuid128Bit;
use btstack::bluetooth::{BluetoothDevice, BluetoothTransport, IBluetooth};
use btstack::bluetooth_gatt::IBluetoothGatt;
use btstack::uuid::UuidHelper;
use manager_service::iface_bluetooth_manager::IBluetoothManager;

const INDENT_CHAR: &str = " ";
@@ -49,20 +49,6 @@ impl<T: Display> Display for DisplayList<T> {
    }
}

struct DisplayUuid128Bit(Uuid128Bit);

// UUID128Bit should have a standard output display format
impl Display for DisplayUuid128Bit {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
        write!(f, "{:02x}{:02x}{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02X}{:02X}{:02X}{:02X}{:02X}{:02X}",
            self.0[0], self.0[1], self.0[2], self.0[3],
            self.0[4], self.0[5],
            self.0[6], self.0[7],
            self.0[8], self.0[9],
            self.0[10], self.0[11], self.0[12], self.0[13], self.0[14], self.0[15])
    }
}

fn enforce_arg_len<F>(args: &Vec<String>, min_len: usize, msg: &str, mut action: F)
where
    F: FnMut(),
@@ -280,10 +266,7 @@ impl CommandHandler {
                print_info!(
                    "Uuids: {}",
                    DisplayList(
                        uuids
                            .iter()
                            .map(|&x| DisplayUuid128Bit(x))
                            .collect::<Vec<DisplayUuid128Bit>>()
                        uuids.iter().map(|&x| UuidHelper::to_string(&x)).collect::<Vec<String>>()
                    )
                );
            }
@@ -377,7 +360,50 @@ impl CommandHandler {
            return;
        }

        enforce_arg_len(args, 2, "device <info> <address>", || match &args[0][0..] {
        enforce_arg_len(args, 2, "device <connect|disconnect|info> <address>", || {
            match &args[0][0..] {
                "connect" => {
                    let device = BluetoothDevice {
                        address: String::from(&args[1]),
                        name: String::from("Classic Device"),
                    };

                    let success = self
                        .context
                        .lock()
                        .unwrap()
                        .adapter_dbus
                        .as_ref()
                        .unwrap()
                        .connect_all_enabled_profiles(device.clone());

                    if success {
                        println!("Connecting to {}", &device.address);
                    } else {
                        println!("Can't connect to {}", &device.address);
                    }
                }
                "disconnect" => {
                    let device = BluetoothDevice {
                        address: String::from(&args[1]),
                        name: String::from("Classic Device"),
                    };

                    let success = self
                        .context
                        .lock()
                        .unwrap()
                        .adapter_dbus
                        .as_ref()
                        .unwrap()
                        .disconnect_all_enabled_profiles(device.clone());

                    if success {
                        println!("Disconnecting from {}", &device.address);
                    } else {
                        println!("Can't disconnect from {}", &device.address);
                    }
                }
                "info" => {
                    let device = BluetoothDevice {
                        address: String::from(&args[1]),
@@ -403,14 +429,15 @@ impl CommandHandler {
                        DisplayList(
                            uuids
                                .iter()
                            .map(|&x| DisplayUuid128Bit(x))
                            .collect::<Vec<DisplayUuid128Bit>>()
                                .map(|&x| UuidHelper::to_string(&x))
                                .collect::<Vec<String>>()
                        )
                    );
                }
                _ => {
                    println!("Invalid argument '{}'", args[0]);
                }
            }
        });
    }

+10 −0
Original line number Diff line number Diff line
@@ -356,6 +356,16 @@ impl IBluetooth for BluetoothDBus {
            (BluetoothDevice::to_dbus(device).unwrap(), Uuid128Bit::to_dbus(uuid).unwrap()),
        )
    }

    fn connect_all_enabled_profiles(&self, device: BluetoothDevice) -> bool {
        self.client_proxy
            .method("ConnectAllEnabledProfiles", (BluetoothDevice::to_dbus(device).unwrap(),))
    }

    fn disconnect_all_enabled_profiles(&self, device: BluetoothDevice) -> bool {
        self.client_proxy
            .method("DisconnectAllEnabledProfiles", (BluetoothDevice::to_dbus(device).unwrap(),))
    }
}

#[dbus_propmap(AdapterWithEnabled)]
+23 −2
Original line number Diff line number Diff line
@@ -146,11 +146,19 @@ impl ClientContext {

        address
    }

    fn connect_all_enabled_profiles(&mut self, device: BluetoothDevice) {
        let fg = self.fg.clone();
        tokio::spawn(async move {
            let _ = fg.send(ForegroundActions::ConnectAllEnabledProfiles(device)).await;
        });
    }
}

/// Actions to take on the foreground loop. This allows us to queue actions in
/// callbacks that get run in the foreground context.
enum ForegroundActions {
    ConnectAllEnabledProfiles(BluetoothDevice), // Connect all enabled profiles for this device
    RegisterAdapterCallback(String),            // Register callbacks for this adapter
    Readline(rustyline::Result<String>),        // Readline result from rustyline
}
@@ -259,6 +267,19 @@ async fn start_interactive_shell(
        }

        match m.unwrap() {
            ForegroundActions::ConnectAllEnabledProfiles(device) => {
                if context.lock().unwrap().adapter_ready {
                    context
                        .lock()
                        .unwrap()
                        .adapter_dbus
                        .as_mut()
                        .unwrap()
                        .connect_all_enabled_profiles(device);
                } else {
                    println!("Adapter isn't ready to connect profiles.");
                }
            }
            // Once adapter is ready, register callbacks, get the address and mark it as ready
            ForegroundActions::RegisterAdapterCallback(adapter) => {
                let cb_objpath: String =
+10 −0
Original line number Diff line number Diff line
@@ -185,4 +185,14 @@ impl IBluetooth for IBluetoothDBus {
    fn sdp_search(&self, _device: BluetoothDevice, _uuid: Uuid128Bit) -> bool {
        true
    }

    #[dbus_method("ConnectAllEnabledProfiles")]
    fn connect_all_enabled_profiles(&self, _device: BluetoothDevice) -> bool {
        true
    }

    #[dbus_method("DisconnectAllEnabledProfiles")]
    fn disconnect_all_enabled_profiles(&self, _device: BluetoothDevice) -> bool {
        true
    }
}
Loading