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

Commit d09a6daa authored by Rahul Arya's avatar Rahul Arya Committed by Gerrit Code Review
Browse files

Merge changes I566daa99,I23b61eb6,Ic2c85e68

* changes:
  [Private GATT] Rename writable -> writable_with_response
  [Private GATT] Add logging at FFI interface
  [Private GATT] Add support for write commands
parents b7c20e64 e7d47a73
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -397,6 +397,9 @@ pub fn load(raw_flags: Vec<String>) {
    let flags = InitFlags::parse(raw_flags);
    info!("Flags loaded: {}", flags);
    *FLAGS.lock().unwrap() = flags;

    // re-init to respect log levels set by flags
    crate::init_logging();
}

#[cfg(test)]
+22 −2
Original line number Diff line number Diff line
//! Bluetooth common library

use init_flags::{
    get_log_level_for_tag, LOG_TAG_DEBUG, LOG_TAG_ERROR, LOG_TAG_FATAL, LOG_TAG_INFO,
    LOG_TAG_NOTICE, LOG_TAG_VERBOSE, LOG_TAG_WARN,
};

/// Provides waking timer abstractions
pub mod time;

@@ -21,22 +26,37 @@ pub mod init_flags;
/// Provides runtime configured system properties. Stubbed for non-Android.
pub mod sys_prop;

fn get_log_level() -> log::Level {
    match get_log_level_for_tag("bluetooth_core") {
        LOG_TAG_FATAL => log::Level::Error,
        LOG_TAG_ERROR => log::Level::Error,
        LOG_TAG_WARN => log::Level::Warn,
        LOG_TAG_NOTICE => log::Level::Info,
        LOG_TAG_INFO => log::Level::Info,
        LOG_TAG_DEBUG => log::Level::Debug,
        LOG_TAG_VERBOSE => log::Level::Trace,
        _ => log::Level::Info, // default level
    }
}

/// Inits logging for Android
#[cfg(target_os = "android")]
pub fn init_logging() {
    android_logger::init_once(
        android_logger::Config::default().with_tag("bt").with_min_level(log::Level::Debug),
        android_logger::Config::default().with_tag("bt").with_min_level(get_log_level()),
    );
    log::set_max_level(get_log_level().to_level_filter())
}

/// Inits logging for host
#[cfg(not(target_os = "android"))]
pub fn init_logging() {
    env_logger::Builder::new()
        .filter(None, log::LevelFilter::Debug)
        .filter(None, get_log_level().to_level_filter())
        .parse_default_env()
        .try_init()
        .ok();
    log::set_max_level(get_log_level().to_level_filter())
}

/// Indicates the object can be converted to a GRPC service
+20 −6
Original line number Diff line number Diff line
@@ -9,7 +9,7 @@ use bt_common::init_flags::{
};
use cxx::UniquePtr;
pub use inner::*;
use log::{error, info, warn};
use log::{error, info, trace, warn};
use tokio::task::spawn_local;

use crate::{
@@ -196,6 +196,7 @@ impl GattCallbacks for GattCallbacksImpl {
        attr_type: AttributeBackingType,
        offset: u32,
    ) {
        trace!("on_server_read ({conn_id:?}, {trans_id:?}, {handle:?}, {attr_type:?}, {offset:?}");
        self.0.as_ref().unwrap().on_server_read(
            conn_id.0,
            trans_id.0,
@@ -215,6 +216,9 @@ impl GattCallbacks for GattCallbacksImpl {
        write_type: GattWriteType,
        value: AttAttributeDataView,
    ) {
        trace!(
            "on_server_write ({conn_id:?}, {trans_id:?}, {handle:?}, {attr_type:?}, {write_type:?}"
        );
        self.0.as_ref().unwrap().on_server_write(
            conn_id.0,
            trans_id.0,
@@ -235,6 +239,7 @@ impl GattCallbacks for GattCallbacksImpl {
        conn_id: ConnectionId,
        result: Result<(), IndicationError>,
    ) {
        trace!("on_indication_sent_confirmation ({conn_id:?}, {result:?}");
        self.0.as_ref().unwrap().on_indication_sent_confirmation(
            conn_id.0,
            match result {
@@ -250,6 +255,7 @@ impl GattCallbacks for GattCallbacksImpl {
        trans_id: TransactionId,
        decision: TransactionDecision,
    ) {
        trace!("on_execute ({conn_id:?}, {trans_id:?}, {decision:?}");
        self.0.as_ref().unwrap().on_execute(
            conn_id.0,
            trans_id.0,
@@ -322,7 +328,7 @@ fn consume_descriptors<'a>(
    {
        let mut att_permissions = AttPermissions::empty();
        att_permissions.set(AttPermissions::READABLE, permissions & 0x01 != 0);
        att_permissions.set(AttPermissions::WRITABLE, permissions & 0x10 != 0);
        att_permissions.set(AttPermissions::WRITABLE_WITH_RESPONSE, permissions & 0x10 != 0);

        out.push(GattDescriptorWithHandle {
            handle: AttHandle(*attribute_handle),
@@ -444,6 +450,9 @@ fn send_response(_server_id: u8, conn_id: u16, trans_id: u32, status: u8, value:
    } else {
        Err(AttErrorCode::try_from(status).unwrap_or(AttErrorCode::UNLIKELY_ERROR))
    };

    trace!("send_response {conn_id:?}, {trans_id:?}, {:?}", value.as_ref().err());

    do_in_rust_thread(move |modules| {
        match modules.gatt_incoming_callbacks.send_response(
            ConnectionId(conn_id),
@@ -465,6 +474,8 @@ fn send_indication(_server_id: u8, handle: u16, conn_id: u16, value: &[u8]) {
    let conn_id = ConnectionId(conn_id);
    let value = AttAttributeDataChild::RawData(value.into());

    trace!("send_indication {handle:?}, {conn_id:?}");

    do_in_rust_thread(move |modules| {
        let Some(bearer) = modules.gatt_module.get_bearer(conn_id) else {
            error!("connection {conn_id:?} does not exist");
@@ -627,7 +638,7 @@ mod test {
        ])
        .unwrap();

        assert_eq!(service.characteristics[0].permissions, AttPermissions::WRITABLE);
        assert_eq!(service.characteristics[0].permissions, AttPermissions::WRITABLE_WITH_RESPONSE);
    }

    #[test]
@@ -640,7 +651,7 @@ mod test {

        assert_eq!(
            service.characteristics[0].permissions,
            AttPermissions::READABLE | AttPermissions::WRITABLE
            AttPermissions::READABLE | AttPermissions::WRITABLE_WITH_RESPONSE
        );
    }

@@ -673,10 +684,13 @@ mod test {
        .unwrap();

        assert_eq!(service.characteristics[0].descriptors[0].permissions, AttPermissions::READABLE);
        assert_eq!(service.characteristics[0].descriptors[1].permissions, AttPermissions::WRITABLE);
        assert_eq!(
            service.characteristics[0].descriptors[1].permissions,
            AttPermissions::WRITABLE_WITH_RESPONSE
        );
        assert_eq!(
            service.characteristics[0].descriptors[2].permissions,
            AttPermissions::READABLE | AttPermissions::WRITABLE
            AttPermissions::READABLE | AttPermissions::WRITABLE_WITH_RESPONSE
        );
    }

+1 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@ mod request_handler;
pub mod services;
mod transactions;

mod command_handler;
#[cfg(test)]
mod test;

+16 −3
Original line number Diff line number Diff line
@@ -37,8 +37,10 @@ bitflags! {
    pub struct AttPermissions : u8 {
        /// Attribute can be read using READ_REQ
        const READABLE = 0x02;
        /// Attribute can be written to using WRITE_CMD
        const WRITABLE_WITHOUT_RESPONSE = 0x04;
        /// Attribute can be written to using WRITE_REQ
        const WRITABLE = 0x08;
        const WRITABLE_WITH_RESPONSE = 0x08;
        /// Attribute value may be sent using indications
        const INDICATE = 0x20;
    }
@@ -50,8 +52,12 @@ impl AttPermissions {
        self.contains(AttPermissions::READABLE)
    }
    /// Attribute can be written to using WRITE_REQ
    pub fn writable(&self) -> bool {
        self.contains(AttPermissions::WRITABLE)
    pub fn writable_with_response(&self) -> bool {
        self.contains(AttPermissions::WRITABLE_WITH_RESPONSE)
    }
    /// Attribute can be written to using WRITE_CMD
    pub fn writable_without_response(&self) -> bool {
        self.contains(AttPermissions::WRITABLE_WITHOUT_RESPONSE)
    }
    /// Attribute value may be sent using indications
    pub fn indicate(&self) -> bool {
@@ -74,6 +80,9 @@ pub trait AttDatabase {
        data: AttAttributeDataView<'_>,
    ) -> Result<(), AttErrorCode>;

    /// Write to an attribute by handle
    fn write_no_response_attribute(&self, handle: AttHandle, data: AttAttributeDataView<'_>);

    /// List all the attributes in this database.
    ///
    /// Expected to return them in sorted order.
@@ -122,6 +131,10 @@ impl AttDatabase for SnapshottedAttDatabase<'_> {
        self.backing.write_attribute(handle, data).await
    }

    fn write_no_response_attribute(&self, handle: AttHandle, data: AttAttributeDataView<'_>) {
        self.backing.write_no_response_attribute(handle, data);
    }

    fn list_attributes(&self) -> Vec<AttAttribute> {
        self.attributes.clone()
    }
Loading