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

Commit 0002ed36 authored by Abhishek Pandit-Subedi's avatar Abhishek Pandit-Subedi Committed by Automerger Merge Worker
Browse files

Merge "Floss: Add BtSdpRecord DBus implementation" am: 59aa5ffe

parents f2090d7d 59aa5ffe
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@ use crate::ClientContext;
use crate::{console_red, console_yellow, print_error, print_info};
use bt_topshim::btif::{BtBondState, BtPropertyType, BtSspVariant, BtStatus, Uuid128Bit};
use bt_topshim::profiles::gatt::{AdvertisingStatus, GattStatus, LePhy};
use bt_topshim::profiles::sdp::BtSdpRecord;
use btstack::bluetooth::{
    BluetoothDevice, IBluetooth, IBluetoothCallback, IBluetoothConnectionCallback,
};
@@ -231,6 +232,16 @@ impl IBluetoothCallback for BtCallback {
            self.context.lock().unwrap().bonded_devices.remove(&address);
        }
    }

    fn on_sdp_search_complete(
        &self,
        _remote_device: BluetoothDevice,
        _searched_uuid: Uuid128Bit,
        _sdp_records: Vec<BtSdpRecord>,
    ) {
    }

    fn on_sdp_record_created(&self, _record: BtSdpRecord, _handle: i32) {}
}

impl RPCProxy for BtCallback {
+239 −1
Original line number Diff line number Diff line
@@ -6,6 +6,11 @@ use bt_topshim::btif::{
};
use bt_topshim::profiles::gatt::{AdvertisingStatus, GattStatus, LePhy};
use bt_topshim::profiles::hid_host::BthhReportType;
use bt_topshim::profiles::sdp::{
    BtSdpDipRecord, BtSdpHeader, BtSdpHeaderOverlay, BtSdpMasRecord, BtSdpMnsRecord,
    BtSdpOpsRecord, BtSdpPceRecord, BtSdpPseRecord, BtSdpRecord, BtSdpSapRecord, BtSdpType,
    SupportedFormatsList,
};
use bt_topshim::profiles::socket::SocketType;
use bt_topshim::profiles::ProfileConnectionState;

@@ -53,7 +58,7 @@ use std::collections::HashMap;
use std::convert::{TryFrom, TryInto};
use std::sync::Arc;

use crate::dbus_arg::{DBusArg, DBusArgError, RefArgToRust};
use crate::dbus_arg::{DBusArg, DBusArgError, DirectDBus, RefArgToRust};

fn make_object_path(idx: i32, name: &str) -> dbus::Path {
    dbus::Path::new(format!("/org/chromium/bluetooth/hci{}/{}", idx, name)).unwrap()
@@ -108,6 +113,217 @@ impl DBusArg for Uuid128Bit {
    }
}

impl_dbus_arg_enum!(BtSdpType);

#[dbus_propmap(BtSdpHeader)]
pub struct BtSdpHeaderDBus {
    sdp_type: BtSdpType,
    uuid: Uuid,
    service_name_length: u32,
    service_name: String,
    rfcomm_channel_number: i32,
    l2cap_psm: i32,
    profile_version: i32,
}

#[dbus_propmap(BtSdpHeaderOverlay)]
struct BtSdpHeaderOverlayDBus {
    hdr: BtSdpHeader,
    user1_len: i32,
    user1_data: Vec<u8>,
    user2_len: i32,
    user2_data: Vec<u8>,
}

#[dbus_propmap(BtSdpMasRecord)]
struct BtSdpMasRecordDBus {
    hdr: BtSdpHeaderOverlay,
    mas_instance_id: u32,
    supported_features: u32,
    supported_message_types: u32,
}

#[dbus_propmap(BtSdpMnsRecord)]
struct BtSdpMnsRecordDBus {
    hdr: BtSdpHeaderOverlay,
    supported_features: u32,
}

#[dbus_propmap(BtSdpPseRecord)]
struct BtSdpPseRecordDBus {
    hdr: BtSdpHeaderOverlay,
    supported_features: u32,
    supported_repositories: u32,
}

#[dbus_propmap(BtSdpPceRecord)]
struct BtSdpPceRecordDBus {
    hdr: BtSdpHeaderOverlay,
}

impl_dbus_arg_from_into!(SupportedFormatsList, Vec<u8>);

#[dbus_propmap(BtSdpOpsRecord)]
struct BtSdpOpsRecordDBus {
    hdr: BtSdpHeaderOverlay,
    supported_formats_list_len: i32,
    supported_formats_list: SupportedFormatsList,
}

#[dbus_propmap(BtSdpSapRecord)]
struct BtSdpSapRecordDBus {
    hdr: BtSdpHeaderOverlay,
}

#[dbus_propmap(BtSdpDipRecord)]
struct BtSdpDipRecordDBus {
    hdr: BtSdpHeaderOverlay,
    spec_id: u16,
    vendor: u16,
    vendor_id_source: u16,
    product: u16,
    version: u16,
    primary_record: bool,
}

fn read_propmap_value<T: 'static + DirectDBus>(
    propmap: &dbus::arg::PropMap,
    key: &str,
) -> Result<T, Box<dyn std::error::Error>> {
    let output = propmap
        .get(key)
        .ok_or(Box::new(DBusArgError::new(String::from(format!("Key {} does not exist", key,)))))?;
    let output = <T as RefArgToRust>::ref_arg_to_rust(
        output.as_static_inner(0).ok_or(Box::new(DBusArgError::new(String::from(format!(
            "Unable to convert propmap[\"{}\"] to {}",
            key,
            stringify!(T),
        )))))?,
        String::from(stringify!(T)),
    )?;
    Ok(output)
}

fn parse_propmap_value<T: DBusArg>(
    propmap: &dbus::arg::PropMap,
    key: &str,
) -> Result<T, Box<dyn std::error::Error>>
where
    <T as DBusArg>::DBusType: RefArgToRust<RustType = <T as DBusArg>::DBusType>,
{
    let output = propmap
        .get(key)
        .ok_or(Box::new(DBusArgError::new(String::from(format!("Key {} does not exist", key,)))))?;
    let output = <<T as DBusArg>::DBusType as RefArgToRust>::ref_arg_to_rust(
        output.as_static_inner(0).ok_or(Box::new(DBusArgError::new(String::from(format!(
            "Unable to convert propmap[\"{}\"] to {}",
            key,
            stringify!(T),
        )))))?,
        format!("{}", stringify!(T)),
    )?;
    let output = T::from_dbus(output, None, None, None)?;
    Ok(output)
}

fn write_propmap_value<T: DBusArg>(
    propmap: &mut dbus::arg::PropMap,
    value: T,
    key: &str,
) -> Result<(), Box<dyn std::error::Error>>
where
    T::DBusType: 'static + dbus::arg::RefArg,
{
    propmap.insert(String::from(key), dbus::arg::Variant(Box::new(DBusArg::to_dbus(value)?)));
    Ok(())
}

impl DBusArg for BtSdpRecord {
    type DBusType = dbus::arg::PropMap;
    fn from_dbus(
        data: dbus::arg::PropMap,
        _conn: Option<std::sync::Arc<dbus::nonblock::SyncConnection>>,
        _remote: Option<dbus::strings::BusName<'static>>,
        _disconnect_watcher: Option<
            std::sync::Arc<std::sync::Mutex<dbus_projection::DisconnectWatcher>>,
        >,
    ) -> Result<BtSdpRecord, Box<dyn std::error::Error>> {
        let sdp_type = read_propmap_value::<u32>(&data, &String::from("type"))?;
        let sdp_type = BtSdpType::from(sdp_type);
        let record = match sdp_type {
            BtSdpType::Raw => {
                let arg_0 = parse_propmap_value::<BtSdpHeaderOverlay>(&data, "0")?;
                BtSdpRecord::HeaderOverlay(arg_0)
            }
            BtSdpType::MapMas => {
                let arg_0 = parse_propmap_value::<BtSdpMasRecord>(&data, "0")?;
                BtSdpRecord::MapMas(arg_0)
            }
            BtSdpType::MapMns => {
                let arg_0 = parse_propmap_value::<BtSdpMnsRecord>(&data, "0")?;
                BtSdpRecord::MapMns(arg_0)
            }
            BtSdpType::PbapPse => {
                let arg_0 = parse_propmap_value::<BtSdpPseRecord>(&data, "0")?;
                BtSdpRecord::PbapPse(arg_0)
            }
            BtSdpType::PbapPce => {
                let arg_0 = parse_propmap_value::<BtSdpPceRecord>(&data, "0")?;
                BtSdpRecord::PbapPce(arg_0)
            }
            BtSdpType::OppServer => {
                let arg_0 = parse_propmap_value::<BtSdpOpsRecord>(&data, "0")?;
                BtSdpRecord::OppServer(arg_0)
            }
            BtSdpType::SapServer => {
                let arg_0 = parse_propmap_value::<BtSdpSapRecord>(&data, "0")?;
                BtSdpRecord::SapServer(arg_0)
            }
            BtSdpType::Dip => {
                let arg_0 = parse_propmap_value::<BtSdpDipRecord>(&data, "0")?;
                BtSdpRecord::Dip(arg_0)
            }
        };
        Ok(record)
    }

    fn to_dbus(record: BtSdpRecord) -> Result<dbus::arg::PropMap, Box<dyn std::error::Error>> {
        let mut map: dbus::arg::PropMap = std::collections::HashMap::new();
        write_propmap_value::<u32>(
            &mut map,
            BtSdpType::from(&record) as u32,
            &String::from("type"),
        )?;
        match record {
            BtSdpRecord::HeaderOverlay(header) => {
                write_propmap_value::<BtSdpHeaderOverlay>(&mut map, header, &String::from("0"))?
            }
            BtSdpRecord::MapMas(mas_record) => {
                write_propmap_value::<BtSdpMasRecord>(&mut map, mas_record, &String::from("0"))?
            }
            BtSdpRecord::MapMns(mns_record) => {
                write_propmap_value::<BtSdpMnsRecord>(&mut map, mns_record, &String::from("0"))?
            }
            BtSdpRecord::PbapPse(pse_record) => {
                write_propmap_value::<BtSdpPseRecord>(&mut map, pse_record, &String::from("0"))?
            }
            BtSdpRecord::PbapPce(pce_record) => {
                write_propmap_value::<BtSdpPceRecord>(&mut map, pce_record, &String::from("0"))?
            }
            BtSdpRecord::OppServer(ops_record) => {
                write_propmap_value::<BtSdpOpsRecord>(&mut map, ops_record, &String::from("0"))?
            }
            BtSdpRecord::SapServer(sap_record) => {
                write_propmap_value::<BtSdpSapRecord>(&mut map, sap_record, &String::from("0"))?
            }
            BtSdpRecord::Dip(dip_record) => {
                write_propmap_value::<BtSdpDipRecord>(&mut map, dip_record, &String::from("0"))?
            }
        }
        Ok(map)
    }
}

#[dbus_propmap(BluetoothGattDescriptor)]
pub struct BluetoothGattDescriptorDBus {
    uuid: Uuid128Bit,
@@ -302,6 +518,18 @@ impl IBluetoothCallback for IBluetoothCallbackDBus {

    #[dbus_method("OnBondStateChanged")]
    fn on_bond_state_changed(&self, status: u32, address: String, state: u32) {}

    #[dbus_method("OnSdpSearchComplete")]
    fn on_sdp_search_complete(
        &self,
        remote_device: BluetoothDevice,
        searched_uuid: Uuid128Bit,
        sdp_records: Vec<BtSdpRecord>,
    ) {
    }

    #[dbus_method("OnSdpRecordCreated")]
    fn on_sdp_record_created(&self, record: BtSdpRecord, handle: i32) {}
}

struct IBluetoothConnectionCallbackDBus {}
@@ -599,6 +827,16 @@ impl IBluetooth for BluetoothDBus {
        dbus_generated!()
    }

    #[dbus_method("CreateSdpRecord")]
    fn create_sdp_record(&self, sdp_record: BtSdpRecord) -> bool {
        dbus_generated!()
    }

    #[dbus_method("RemoveSdpRecord")]
    fn remove_sdp_record(&self, handle: i32) -> bool {
        dbus_generated!()
    }

    #[dbus_method("ConnectAllEnabledProfiles")]
    fn connect_all_enabled_profiles(&mut self, device: BluetoothDevice) -> bool {
        dbus_generated!()
+241 −1
Original line number Diff line number Diff line
@@ -7,6 +7,12 @@ use bt_topshim::profiles::ProfileConnectionState;

use bt_topshim::profiles::hid_host::BthhReportType;

use bt_topshim::profiles::sdp::{
    BtSdpDipRecord, BtSdpHeader, BtSdpHeaderOverlay, BtSdpMasRecord, BtSdpMnsRecord,
    BtSdpOpsRecord, BtSdpPceRecord, BtSdpPseRecord, BtSdpRecord, BtSdpSapRecord, BtSdpType,
    SupportedFormatsList,
};

use btstack::bluetooth::{
    Bluetooth, BluetoothDevice, IBluetooth, IBluetoothCallback, IBluetoothConnectionCallback,
    IBluetoothQA,
@@ -31,7 +37,7 @@ use num_traits::cast::{FromPrimitive, ToPrimitive};
use std::convert::{TryFrom, TryInto};
use std::sync::{Arc, Mutex};

use crate::dbus_arg::{DBusArg, DBusArgError, RefArgToRust};
use crate::dbus_arg::{DBusArg, DBusArgError, DirectDBus, RefArgToRust};

// Represents Uuid as an array in D-Bus.
impl_dbus_arg_from_into!(Uuid, Vec<u8>);
@@ -111,6 +117,19 @@ impl IBluetoothCallback for BluetoothCallbackDBus {
    fn on_bond_state_changed(&self, status: u32, address: String, state: u32) {
        dbus_generated!()
    }
    #[dbus_method("OnSdpSearchComplete")]
    fn on_sdp_search_complete(
        &self,
        remote_device: BluetoothDevice,
        searched_uuid: Uuid128Bit,
        sdp_records: Vec<BtSdpRecord>,
    ) {
        dbus_generated!()
    }
    #[dbus_method("OnSdpRecordCreated")]
    fn on_sdp_record_created(&self, record: BtSdpRecord, handle: i32) {
        dbus_generated!()
    }
}

impl_dbus_arg_enum!(BtBondState);
@@ -137,6 +156,217 @@ impl IBluetoothConnectionCallback for BluetoothConnectionCallbackDBus {
    }
}

impl_dbus_arg_enum!(BtSdpType);

#[dbus_propmap(BtSdpHeader)]
pub struct BtSdpHeaderDBus {
    sdp_type: BtSdpType,
    uuid: Uuid,
    service_name_length: u32,
    service_name: String,
    rfcomm_channel_number: i32,
    l2cap_psm: i32,
    profile_version: i32,
}

#[dbus_propmap(BtSdpHeaderOverlay)]
struct BtSdpHeaderOverlayDBus {
    hdr: BtSdpHeader,
    user1_len: i32,
    user1_data: Vec<u8>,
    user2_len: i32,
    user2_data: Vec<u8>,
}

#[dbus_propmap(BtSdpMasRecord)]
struct BtSdpMasRecordDBus {
    hdr: BtSdpHeaderOverlay,
    mas_instance_id: u32,
    supported_features: u32,
    supported_message_types: u32,
}

#[dbus_propmap(BtSdpMnsRecord)]
struct BtSdpMnsRecordDBus {
    hdr: BtSdpHeaderOverlay,
    supported_features: u32,
}

#[dbus_propmap(BtSdpPseRecord)]
struct BtSdpPseRecordDBus {
    hdr: BtSdpHeaderOverlay,
    supported_features: u32,
    supported_repositories: u32,
}

#[dbus_propmap(BtSdpPceRecord)]
struct BtSdpPceRecordDBus {
    hdr: BtSdpHeaderOverlay,
}

impl_dbus_arg_from_into!(SupportedFormatsList, Vec<u8>);

#[dbus_propmap(BtSdpOpsRecord)]
struct BtSdpOpsRecordDBus {
    hdr: BtSdpHeaderOverlay,
    supported_formats_list_len: i32,
    supported_formats_list: SupportedFormatsList,
}

#[dbus_propmap(BtSdpSapRecord)]
struct BtSdpSapRecordDBus {
    hdr: BtSdpHeaderOverlay,
}

#[dbus_propmap(BtSdpDipRecord)]
struct BtSdpDipRecordDBus {
    hdr: BtSdpHeaderOverlay,
    spec_id: u16,
    vendor: u16,
    vendor_id_source: u16,
    product: u16,
    version: u16,
    primary_record: bool,
}

fn read_propmap_value<T: 'static + DirectDBus>(
    propmap: &dbus::arg::PropMap,
    key: &str,
) -> Result<T, Box<dyn std::error::Error>> {
    let output = propmap
        .get(key)
        .ok_or(Box::new(DBusArgError::new(String::from(format!("Key {} does not exist", key,)))))?;
    let output = <T as RefArgToRust>::ref_arg_to_rust(
        output.as_static_inner(0).ok_or(Box::new(DBusArgError::new(String::from(format!(
            "Unable to convert propmap[\"{}\"] to {}",
            key,
            stringify!(T),
        )))))?,
        String::from(stringify!(T)),
    )?;
    Ok(output)
}

fn parse_propmap_value<T: DBusArg>(
    propmap: &dbus::arg::PropMap,
    key: &str,
) -> Result<T, Box<dyn std::error::Error>>
where
    <T as DBusArg>::DBusType: RefArgToRust<RustType = <T as DBusArg>::DBusType>,
{
    let output = propmap
        .get(key)
        .ok_or(Box::new(DBusArgError::new(String::from(format!("Key {} does not exist", key,)))))?;
    let output = <<T as DBusArg>::DBusType as RefArgToRust>::ref_arg_to_rust(
        output.as_static_inner(0).ok_or(Box::new(DBusArgError::new(String::from(format!(
            "Unable to convert propmap[\"{}\"] to {}",
            key,
            stringify!(T),
        )))))?,
        format!("{}", stringify!(T)),
    )?;
    let output = T::from_dbus(output, None, None, None)?;
    Ok(output)
}

fn write_propmap_value<T: DBusArg>(
    propmap: &mut dbus::arg::PropMap,
    value: T,
    key: &str,
) -> Result<(), Box<dyn std::error::Error>>
where
    T::DBusType: 'static + dbus::arg::RefArg,
{
    propmap.insert(String::from(key), dbus::arg::Variant(Box::new(DBusArg::to_dbus(value)?)));
    Ok(())
}

impl DBusArg for BtSdpRecord {
    type DBusType = dbus::arg::PropMap;
    fn from_dbus(
        data: dbus::arg::PropMap,
        _conn: Option<std::sync::Arc<dbus::nonblock::SyncConnection>>,
        _remote: Option<dbus::strings::BusName<'static>>,
        _disconnect_watcher: Option<
            std::sync::Arc<std::sync::Mutex<dbus_projection::DisconnectWatcher>>,
        >,
    ) -> Result<BtSdpRecord, Box<dyn std::error::Error>> {
        let sdp_type = read_propmap_value::<u32>(&data, &String::from("type"))?;
        let sdp_type = BtSdpType::from(sdp_type);
        let record = match sdp_type {
            BtSdpType::Raw => {
                let arg_0 = parse_propmap_value::<BtSdpHeaderOverlay>(&data, "0")?;
                BtSdpRecord::HeaderOverlay(arg_0)
            }
            BtSdpType::MapMas => {
                let arg_0 = parse_propmap_value::<BtSdpMasRecord>(&data, "0")?;
                BtSdpRecord::MapMas(arg_0)
            }
            BtSdpType::MapMns => {
                let arg_0 = parse_propmap_value::<BtSdpMnsRecord>(&data, "0")?;
                BtSdpRecord::MapMns(arg_0)
            }
            BtSdpType::PbapPse => {
                let arg_0 = parse_propmap_value::<BtSdpPseRecord>(&data, "0")?;
                BtSdpRecord::PbapPse(arg_0)
            }
            BtSdpType::PbapPce => {
                let arg_0 = parse_propmap_value::<BtSdpPceRecord>(&data, "0")?;
                BtSdpRecord::PbapPce(arg_0)
            }
            BtSdpType::OppServer => {
                let arg_0 = parse_propmap_value::<BtSdpOpsRecord>(&data, "0")?;
                BtSdpRecord::OppServer(arg_0)
            }
            BtSdpType::SapServer => {
                let arg_0 = parse_propmap_value::<BtSdpSapRecord>(&data, "0")?;
                BtSdpRecord::SapServer(arg_0)
            }
            BtSdpType::Dip => {
                let arg_0 = parse_propmap_value::<BtSdpDipRecord>(&data, "0")?;
                BtSdpRecord::Dip(arg_0)
            }
        };
        Ok(record)
    }

    fn to_dbus(record: BtSdpRecord) -> Result<dbus::arg::PropMap, Box<dyn std::error::Error>> {
        let mut map: dbus::arg::PropMap = std::collections::HashMap::new();
        write_propmap_value::<u32>(
            &mut map,
            BtSdpType::from(&record) as u32,
            &String::from("type"),
        )?;
        match record {
            BtSdpRecord::HeaderOverlay(header) => {
                write_propmap_value::<BtSdpHeaderOverlay>(&mut map, header, &String::from("0"))?
            }
            BtSdpRecord::MapMas(mas_record) => {
                write_propmap_value::<BtSdpMasRecord>(&mut map, mas_record, &String::from("0"))?
            }
            BtSdpRecord::MapMns(mns_record) => {
                write_propmap_value::<BtSdpMnsRecord>(&mut map, mns_record, &String::from("0"))?
            }
            BtSdpRecord::PbapPse(pse_record) => {
                write_propmap_value::<BtSdpPseRecord>(&mut map, pse_record, &String::from("0"))?
            }
            BtSdpRecord::PbapPce(pce_record) => {
                write_propmap_value::<BtSdpPceRecord>(&mut map, pce_record, &String::from("0"))?
            }
            BtSdpRecord::OppServer(ops_record) => {
                write_propmap_value::<BtSdpOpsRecord>(&mut map, ops_record, &String::from("0"))?
            }
            BtSdpRecord::SapServer(sap_record) => {
                write_propmap_value::<BtSdpSapRecord>(&mut map, sap_record, &String::from("0"))?
            }
            BtSdpRecord::Dip(dip_record) => {
                write_propmap_value::<BtSdpDipRecord>(&mut map, dip_record, &String::from("0"))?
            }
        }
        Ok(map)
    }
}

#[allow(dead_code)]
struct IBluetoothDBus {}

@@ -361,6 +591,16 @@ impl IBluetooth for IBluetoothDBus {
        dbus_generated!()
    }

    #[dbus_method("CreateSdpRecord")]
    fn create_sdp_record(&self, sdp_record: BtSdpRecord) -> bool {
        dbus_generated!()
    }

    #[dbus_method("RemoveSdpRecord")]
    fn remove_sdp_record(&self, handle: i32) -> bool {
        dbus_generated!()
    }

    #[dbus_method("ConnectAllEnabledProfiles")]
    fn connect_all_enabled_profiles(&mut self, device: BluetoothDevice) -> bool {
        dbus_generated!()
+52 −1
Original line number Diff line number Diff line
@@ -192,6 +192,12 @@ pub trait IBluetooth {
    /// Triggers SDP and searches for a specific UUID on a remote device.
    fn sdp_search(&self, device: BluetoothDevice, uuid: Uuid128Bit) -> bool;

    /// Creates a new SDP record.
    fn create_sdp_record(&self, sdp_record: BtSdpRecord) -> bool;

    /// Removes the SDP record associated with the provided handle.
    fn remove_sdp_record(&self, handle: i32) -> bool;

    /// Connect all profiles supported by device and enabled on adapter.
    fn connect_all_enabled_profiles(&mut self, device: BluetoothDevice) -> bool;

@@ -371,6 +377,17 @@ pub trait IBluetoothCallback: RPCProxy {

    /// When a bonding attempt has completed.
    fn on_bond_state_changed(&self, status: u32, device_address: String, state: u32);

    /// When an SDP search has completed.
    fn on_sdp_search_complete(
        &self,
        remote_device: BluetoothDevice,
        searched_uuid: Uuid128Bit,
        sdp_records: Vec<BtSdpRecord>,
    );

    /// When an SDP record has been successfully created.
    fn on_sdp_record_created(&self, record: BtSdpRecord, handle: i32);
}

/// An interface for other modules to track found remote devices.
@@ -594,6 +611,11 @@ impl Bluetooth {
        }
    }

    fn get_remote_device_info_if_found(&self, remote_address: &str) -> Option<BluetoothDevice> {
        self.get_remote_device_if_found(remote_address)
            .map(|device_context| device_context.info.clone())
    }

    fn get_remote_device_property(
        &self,
        device: &BluetoothDevice,
@@ -1835,6 +1857,24 @@ impl IBluetooth for Bluetooth {
        self.sdp.as_ref().unwrap().sdp_search(&mut addr.unwrap(), &uu) == BtStatus::Success
    }

    fn create_sdp_record(&self, sdp_record: BtSdpRecord) -> bool {
        let mut handle: i32 = -1;
        let mut sdp_record = sdp_record;
        match self.sdp.as_ref().unwrap().create_sdp_record(&mut sdp_record, &mut handle) {
            BtStatus::Success => {
                self.callbacks.for_all_callbacks(|callback| {
                    callback.on_sdp_record_created(sdp_record.clone(), handle);
                });
                true
            }
            _ => false,
        }
    }

    fn remove_sdp_record(&self, handle: i32) -> bool {
        self.sdp.as_ref().unwrap().remove_sdp_record(handle) == BtStatus::Success
    }

    fn connect_all_enabled_profiles(&mut self, device: BluetoothDevice) -> bool {
        // Profile init must be complete before this api is callable
        if !self.profiles_ready {
@@ -2032,8 +2072,19 @@ impl BtifSdpCallbacks for Bluetooth {
        address: RawAddress,
        uuid: Uuid,
        _count: i32,
        _records: Vec<BtSdpRecord>,
        records: Vec<BtSdpRecord>,
    ) {
        let uuid = match UuidHelper::from_string(uuid.to_string()) {
            Some(uu) => uu,
            None => return,
        };
        let device_info = match self.get_remote_device_info_if_found(&address.to_string()) {
            Some(info) => info,
            None => BluetoothDevice::new(address.to_string(), "".to_string()),
        };
        self.callbacks.for_all_callbacks(|callback| {
            callback.on_sdp_search_complete(device_info.clone(), uuid, records.clone());
        });
        debug!(
            "Sdp search result found: Status({:?}) Address({:?}) Uuid({:?})",
            status, address, uuid
+50 −33

File changed.

Preview size limit exceeded, changes collapsed.