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

Commit 134fe61c authored by Sarvesh Kalwit's avatar Sarvesh Kalwit
Browse files

floss: Support adding/removing/clearing GATT Services in btclient

Support the ability to add, remove, and clear GATT Service on a GATT
Server via btclient.

Bug: 323943663
Test: m -j && manually with btclient
Flag: Exempt, Floss-only change

Change-Id: I355be197e1467106194d28a2749c1335c197e7f9
parent 02e8b484
Loading
Loading
Loading
Loading
+42 −2
Original line number Diff line number Diff line
@@ -9,12 +9,14 @@ use crate::bt_gatt::AuthReq;
use crate::callbacks::{BtGattCallback, BtGattServerCallback};
use crate::ClientContext;
use crate::{console_red, console_yellow, print_error, print_info};
use bt_topshim::btif::{BtConnectionState, BtDiscMode, BtStatus, BtTransport, INVALID_RSSI};
use bt_topshim::btif::{BtConnectionState, BtDiscMode, BtStatus, BtTransport, Uuid, INVALID_RSSI};
use bt_topshim::profiles::hid_host::BthhReportType;
use bt_topshim::profiles::sdp::{BtSdpMpsRecord, BtSdpRecord};
use bt_topshim::profiles::{gatt::LePhy, ProfileConnectionState};
use btstack::bluetooth::{BluetoothDevice, IBluetooth};
use btstack::bluetooth_gatt::{GattWriteType, IBluetoothGatt};
use btstack::bluetooth_gatt::{
    BluetoothGattService, GattDbElementType, GattWriteType, IBluetoothGatt,
};
use btstack::bluetooth_media::{IBluetoothMedia, IBluetoothTelephony};
use btstack::bluetooth_qa::IBluetoothQA;
use btstack::socket_manager::{IBluetoothSocketManager, SocketResult};
@@ -27,6 +29,7 @@ const BAR2_CHAR: &str = "-";
const MAX_MENU_CHAR_WIDTH: usize = 72;
const GATT_CLIENT_APP_UUID: &str = "12345678123456781234567812345678";
const GATT_SERVER_APP_UUID: &str = "12345678123456781234567812345679";
const HEART_RATE_SERVICE_UUID: &str = "0000180D-0000-1000-8000-00805F9B34FB";

enum CommandError {
    // Command not handled due to invalid arguments.
@@ -204,6 +207,9 @@ fn build_commands() -> HashMap<String, CommandOption> {
                String::from("gatt register-server"),
                String::from("gatt server-connect <server_id> <client_address>"),
                String::from("gatt server-disconnect <server_id> <client_address>"),
                String::from("gatt server-add-heartrate-service <server_id>"),
                String::from("gatt server-remove-service <server_id> <service_handle>"),
                String::from("gatt server-clear-all-services <server_id>"),
                String::from("gatt server-set-direct-connect <true|false>"),
                String::from("gatt server-set-connect-transport <Bredr|LE|Auto>"),
            ],
@@ -1260,6 +1266,40 @@ impl CommandHandler {
                    return Err("Disconnection was unsuccessful".into());
                }
            }
            "server-add-heartrate-service" => {
                let uuid = Uuid::from(UuidHelper::from_string(HEART_RATE_SERVICE_UUID).unwrap());

                let server_id = String::from(get_arg(args, 1)?)
                    .parse::<i32>()
                    .or(Err("Failed to parse server_id"))?;
                let service = BluetoothGattService::new(
                    uuid.into(),
                    0, // libbluetooth assigns this handle once the service is added
                    GattDbElementType::PrimaryService.into(),
                );

                self.lock_context().gatt_dbus.as_mut().unwrap().add_service(server_id, service);
            }
            "server-remove-service" => {
                let server_id = String::from(get_arg(args, 1)?)
                    .parse::<i32>()
                    .or(Err("Failed to parse server_id"))?;
                let service_handle = String::from(get_arg(args, 1)?)
                    .parse::<i32>()
                    .or(Err("Failed to parse service handle"))?;

                self.lock_context()
                    .gatt_dbus
                    .as_mut()
                    .unwrap()
                    .remove_service(server_id, service_handle);
            }
            "server-clear-all-services" => {
                let server_id = String::from(get_arg(args, 1)?)
                    .parse::<i32>()
                    .or(Err("Failed to parse server_id"))?;
                self.lock_context().gatt_dbus.as_mut().unwrap().clear_services(server_id);
            }
            "server-set-direct-connect" => {
                let is_direct = String::from(get_arg(args, 1)?)
                    .parse::<bool>()
+2 −6
Original line number Diff line number Diff line
@@ -782,11 +782,7 @@ pub struct BluetoothGattService {
}

impl BluetoothGattService {
    pub(crate) fn new(
        uuid: Uuid128Bit,
        instance_id: i32,
        service_type: i32,
    ) -> BluetoothGattService {
    pub fn new(uuid: Uuid128Bit, instance_id: i32, service_type: i32) -> BluetoothGattService {
        BluetoothGattService {
            uuid,
            instance_id,
@@ -1133,7 +1129,7 @@ pub trait IScannerCallback: RPCProxy {
#[derive(Debug, FromPrimitive, ToPrimitive)]
#[repr(u8)]
/// GATT write type.
pub(crate) enum GattDbElementType {
pub enum GattDbElementType {
    PrimaryService = 0,
    SecondaryService = 1,
    IncludedService = 2,