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

Commit a7c28497 authored by Rahul Arya's avatar Rahul Arya
Browse files

[Private GATT] Make datastores per-service

Previously the GattDatastore was global. Now, it can be specified
per-service, so that multiple datastores can be used.

This is needed to support GAP/GATT/DIS services, as well as non-isolated
connections.

Test: unit
Bug: 255880936
Change-Id: I581fec49621ce1cc2652b013b5978d659166fb95
parent 3873f66b
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -49,9 +49,9 @@ impl<T> Deref for SharedBox<T> {
}

/// A weak reference to the contents within a SharedBox<>
pub struct WeakBox<T>(Weak<T>);
pub struct WeakBox<T: ?Sized>(Weak<T>);

impl<T> WeakBox<T> {
impl<T: ?Sized> WeakBox<T> {
    /// Fallibly upgrade to a strong reference, passed into the supplied closure.
    /// The strong reference is not passed into the closure to avoid accidental
    /// lifetime extension.
@@ -64,16 +64,16 @@ impl<T> WeakBox<T> {
    }
}

impl<T> Clone for WeakBox<T> {
impl<T: ?Sized> Clone for WeakBox<T> {
    fn clone(&self) -> Self {
        Self(self.0.clone())
    }
}

/// A strong reference to the contents within a SharedBox<>.
pub struct WeakBoxRef<'a, T>(&'a T, Weak<T>);
pub struct WeakBoxRef<'a, T: ?Sized>(&'a T, Weak<T>);

impl<'a, T> WeakBoxRef<'a, T> {
impl<'a, T: ?Sized> WeakBoxRef<'a, T> {
    /// Downgrade to a weak reference (with static lifetime) to the contents
    /// within the underlying SharedBox<>
    pub fn downgrade(&self) -> WeakBox<T> {
@@ -81,7 +81,7 @@ impl<'a, T> WeakBoxRef<'a, T> {
    }
}

impl<'a, T> Deref for WeakBoxRef<'a, T> {
impl<'a, T: ?Sized> Deref for WeakBoxRef<'a, T> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
+5 −1
Original line number Diff line number Diff line
@@ -358,7 +358,11 @@ fn add_service(server_id: u8, service_records: Vec<GattRecord>) {
        Ok(service) => {
            let handle = service.handle;
            do_in_rust_thread(move |modules| {
                let ok = modules.gatt_module.register_gatt_service(server_id, service.clone());
                let ok = modules.gatt_module.register_gatt_service(
                    server_id,
                    service.clone(),
                    modules.gatt_incoming_callbacks.clone(),
                );
                match ok {
                    Ok(_) => info!(
                        "successfully registered service for server {server_id:?} with handle {handle:?} (service={service:?})"
+9 −11
Original line number Diff line number Diff line
@@ -32,17 +32,15 @@ pub use indication_handler::IndicationError;

#[allow(missing_docs)]
pub struct GattModule {
    connection_bearers:
        HashMap<ConnectionId, SharedBox<AttServerBearer<AttDatabaseImpl<dyn GattDatastore>>>>,
    databases: HashMap<ServerId, SharedBox<GattDatabase<dyn GattDatastore>>>,
    datastore: Rc<dyn GattDatastore>,
    connection_bearers: HashMap<ConnectionId, SharedBox<AttServerBearer<AttDatabaseImpl>>>,
    databases: HashMap<ServerId, SharedBox<GattDatabase>>,
    transport: Rc<dyn AttTransport>,
}

impl GattModule {
    /// Constructor. Uses `datastore` to read/write characteristics.
    pub fn new(datastore: Rc<dyn GattDatastore>, transport: Rc<dyn AttTransport>) -> Self {
        Self { connection_bearers: HashMap::new(), databases: HashMap::new(), datastore, transport }
    /// Constructor.
    pub fn new(transport: Rc<dyn AttTransport>) -> Self {
        Self { connection_bearers: HashMap::new(), databases: HashMap::new(), transport }
    }

    /// Handle LE link connect
@@ -77,11 +75,12 @@ impl GattModule {
        &mut self,
        server_id: ServerId,
        service: GattServiceWithHandle,
        datastore: Rc<dyn GattDatastore>,
    ) -> Result<()> {
        self.databases
            .get(&server_id)
            .ok_or_else(|| anyhow!("server {server_id:?} not opened"))?
            .add_service_with_handles(service)
            .add_service_with_handles(service, datastore)
    }

    /// Unregister an existing GATT service on a given server
@@ -98,8 +97,7 @@ impl GattModule {

    /// Open a GATT server
    pub fn open_gatt_server(&mut self, server_id: ServerId) -> Result<()> {
        let old =
            self.databases.insert(server_id, GattDatabase::new(self.datastore.clone()).into());
        let old = self.databases.insert(server_id, GattDatabase::new().into());
        if old.is_some() {
            bail!("GATT server {server_id:?} already exists but was re-opened, clobbering old value...")
        }
@@ -120,7 +118,7 @@ impl GattModule {
    pub fn get_bearer(
        &self,
        conn_id: ConnectionId,
    ) -> Option<WeakBoxRef<AttServerBearer<AttDatabaseImpl<dyn GattDatastore>>>> {
    ) -> Option<WeakBoxRef<AttServerBearer<AttDatabaseImpl>>> {
        self.connection_bearers.get(&conn_id).map(|x| x.as_ref())
    }
}
+22 −19
Original line number Diff line number Diff line
@@ -319,8 +319,9 @@ mod test {
        // two characteristics in the database
        let (datastore, mut data_rx) = MockDatastore::new();
        let datastore = Rc::new(datastore);
        let db = SharedBox::new(GattDatabase::new(datastore));
        db.add_service_with_handles(GattServiceWithHandle {
        let db = SharedBox::new(GattDatabase::new());
        db.add_service_with_handles(
            GattServiceWithHandle {
                handle: AttHandle(1),
                type_: Uuid::new(1),
                characteristics: vec![
@@ -337,7 +338,9 @@ mod test {
                        descriptors: vec![],
                    },
                ],
        })
            },
            datastore,
        )
        .unwrap();
        let (tx, mut rx) = unbounded_channel();
        let send_packet = move |packet| {
+334 −215

File changed.

Preview size limit exceeded, changes collapsed.

Loading