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

Commit 1d4ec169 authored by Henri Chataing's avatar Henri Chataing Committed by Gerrit Code Review
Browse files

Merge "system/rust: Update GATT datastore interfaces to use raw values" into main

parents 6088fc2f 6f91bd9d
Loading
Loading
Loading
Loading
+15 −23
Original line number Original line Diff line number Diff line
@@ -9,7 +9,7 @@ pub use callback_transaction_manager::{CallbackResponseError, CallbackTransactio
use async_trait::async_trait;
use async_trait::async_trait;
use log::warn;
use log::warn;


use crate::packets::{AttAttributeDataChild, AttAttributeDataView, AttErrorCode};
use crate::packets::AttErrorCode;


use super::{
use super::{
    ffi::AttributeBackingType,
    ffi::AttributeBackingType,
@@ -41,7 +41,7 @@ pub trait GattCallbacks {
        handle: AttHandle,
        handle: AttHandle,
        attr_type: AttributeBackingType,
        attr_type: AttributeBackingType,
        write_type: GattWriteType,
        write_type: GattWriteType,
        value: AttAttributeDataView,
        value: &[u8],
    );
    );


    /// Invoked when a handle value indication transaction completes
    /// Invoked when a handle value indication transaction completes
@@ -102,7 +102,7 @@ pub trait RawGattDatastore {
        handle: AttHandle,
        handle: AttHandle,
        offset: u32,
        offset: u32,
        attr_type: AttributeBackingType,
        attr_type: AttributeBackingType,
    ) -> Result<AttAttributeDataChild, AttErrorCode>;
    ) -> Result<Vec<u8>, AttErrorCode>;


    /// Write data to a given characteristic on the specified connection.
    /// Write data to a given characteristic on the specified connection.
    async fn write(
    async fn write(
@@ -111,7 +111,7 @@ pub trait RawGattDatastore {
        handle: AttHandle,
        handle: AttHandle,
        attr_type: AttributeBackingType,
        attr_type: AttributeBackingType,
        write_type: GattWriteRequestType,
        write_type: GattWriteRequestType,
        data: AttAttributeDataView<'_>,
        data: &[u8],
    ) -> Result<(), AttErrorCode>;
    ) -> Result<(), AttErrorCode>;


    /// Write data to a given characteristic on the specified connection, without waiting
    /// Write data to a given characteristic on the specified connection, without waiting
@@ -121,7 +121,7 @@ pub trait RawGattDatastore {
        tcb_idx: TransportIndex,
        tcb_idx: TransportIndex,
        handle: AttHandle,
        handle: AttHandle,
        attr_type: AttributeBackingType,
        attr_type: AttributeBackingType,
        data: AttAttributeDataView<'_>,
        data: &[u8],
    );
    );


    /// Execute or cancel any prepared writes
    /// Execute or cancel any prepared writes
@@ -142,7 +142,7 @@ pub trait GattDatastore {
        tcb_idx: TransportIndex,
        tcb_idx: TransportIndex,
        handle: AttHandle,
        handle: AttHandle,
        attr_type: AttributeBackingType,
        attr_type: AttributeBackingType,
    ) -> Result<AttAttributeDataChild, AttErrorCode>;
    ) -> Result<Vec<u8>, AttErrorCode>;


    /// Write data to a given characteristic on the specified connection.
    /// Write data to a given characteristic on the specified connection.
    async fn write(
    async fn write(
@@ -150,7 +150,7 @@ pub trait GattDatastore {
        tcb_idx: TransportIndex,
        tcb_idx: TransportIndex,
        handle: AttHandle,
        handle: AttHandle,
        attr_type: AttributeBackingType,
        attr_type: AttributeBackingType,
        data: AttAttributeDataView<'_>,
        data: &[u8],
    ) -> Result<(), AttErrorCode>;
    ) -> Result<(), AttErrorCode>;
}
}


@@ -163,7 +163,7 @@ impl<T: GattDatastore + ?Sized> RawGattDatastore for T {
        handle: AttHandle,
        handle: AttHandle,
        offset: u32,
        offset: u32,
        attr_type: AttributeBackingType,
        attr_type: AttributeBackingType,
    ) -> Result<AttAttributeDataChild, AttErrorCode> {
    ) -> Result<Vec<u8>, AttErrorCode> {
        if offset != 0 {
        if offset != 0 {
            warn!("got read blob request for non-long attribute {handle:?}");
            warn!("got read blob request for non-long attribute {handle:?}");
            return Err(AttErrorCode::ATTRIBUTE_NOT_LONG);
            return Err(AttErrorCode::ATTRIBUTE_NOT_LONG);
@@ -178,7 +178,7 @@ impl<T: GattDatastore + ?Sized> RawGattDatastore for T {
        handle: AttHandle,
        handle: AttHandle,
        attr_type: AttributeBackingType,
        attr_type: AttributeBackingType,
        write_type: GattWriteRequestType,
        write_type: GattWriteRequestType,
        data: AttAttributeDataView<'_>,
        data: &[u8],
    ) -> Result<(), AttErrorCode> {
    ) -> Result<(), AttErrorCode> {
        match write_type {
        match write_type {
            GattWriteRequestType::Prepare { .. } => {
            GattWriteRequestType::Prepare { .. } => {
@@ -194,7 +194,7 @@ impl<T: GattDatastore + ?Sized> RawGattDatastore for T {
        tcb_idx: TransportIndex,
        tcb_idx: TransportIndex,
        handle: AttHandle,
        handle: AttHandle,
        _: AttributeBackingType,
        _: AttributeBackingType,
        _: AttAttributeDataView<'_>,
        _: &[u8],
    ) {
    ) {
        // silently drop, since there's no way to return an error
        // silently drop, since there's no way to return an error
        warn!("got write command on {tcb_idx:?} to characteristic {handle:?} not supporting write_without_response");
        warn!("got write command on {tcb_idx:?} to characteristic {handle:?} not supporting write_without_response");
@@ -213,11 +213,7 @@ mod test {


    use crate::{
    use crate::{
        gatt::mocks::mock_datastore::{MockDatastore, MockDatastoreEvents},
        gatt::mocks::mock_datastore::{MockDatastore, MockDatastoreEvents},
        packets::OwnedAttAttributeDataView,
        utils::task::block_on_locally,
        utils::{
            packet::{build_att_data, build_view_or_crash},
            task::block_on_locally,
        },
    };
    };


    use super::*;
    use super::*;
@@ -301,10 +297,6 @@ mod test {
        assert_eq!(rx.try_recv().unwrap_err(), TryRecvError::Empty);
        assert_eq!(rx.try_recv().unwrap_err(), TryRecvError::Empty);
    }
    }


    fn make_data() -> OwnedAttAttributeDataView {
        build_view_or_crash(build_att_data(AttAttributeDataChild::RawData(DATA.into())))
    }

    #[test]
    #[test]
    fn test_write_request_invoke() {
    fn test_write_request_invoke() {
        block_on_locally(async {
        block_on_locally(async {
@@ -319,7 +311,7 @@ mod test {
                    HANDLE,
                    HANDLE,
                    AttributeBackingType::Characteristic,
                    AttributeBackingType::Characteristic,
                    GattWriteRequestType::Request,
                    GattWriteRequestType::Request,
                    make_data().view(),
                    &DATA,
                )
                )
                .await
                .await
            });
            });
@@ -353,7 +345,7 @@ mod test {
                    HANDLE,
                    HANDLE,
                    AttributeBackingType::Characteristic,
                    AttributeBackingType::Characteristic,
                    GattWriteRequestType::Request,
                    GattWriteRequestType::Request,
                    make_data().view(),
                    &DATA,
                )
                )
                .await
                .await
            });
            });
@@ -380,7 +372,7 @@ mod test {
            HANDLE,
            HANDLE,
            AttributeBackingType::Characteristic,
            AttributeBackingType::Characteristic,
            GattWriteRequestType::Prepare { offset: 1 },
            GattWriteRequestType::Prepare { offset: 1 },
            make_data().view(),
            &DATA,
        ));
        ));


        // assert: got the correct error code
        // assert: got the correct error code
@@ -400,7 +392,7 @@ mod test {
            TCB_IDX,
            TCB_IDX,
            HANDLE,
            HANDLE,
            AttributeBackingType::Characteristic,
            AttributeBackingType::Characteristic,
            make_data().view(),
            &DATA,
        );
        );


        // assert: no event sent up
        // assert: no event sent up
+8 −11
Original line number Original line Diff line number Diff line
@@ -9,7 +9,7 @@ use crate::{
        ids::{AttHandle, ConnectionId, ServerId, TransactionId, TransportIndex},
        ids::{AttHandle, ConnectionId, ServerId, TransactionId, TransportIndex},
        GattCallbacks,
        GattCallbacks,
    },
    },
    packets::{AttAttributeDataChild, AttAttributeDataView, AttErrorCode},
    packets::AttErrorCode,
};
};


use super::{
use super::{
@@ -18,14 +18,14 @@ use super::{
};
};


struct PendingTransaction {
struct PendingTransaction {
    response: oneshot::Sender<Result<AttAttributeDataChild, AttErrorCode>>,
    response: oneshot::Sender<Result<Vec<u8>, AttErrorCode>>,
}
}


#[derive(Debug)]
#[derive(Debug)]
struct PendingTransactionWatcher {
struct PendingTransactionWatcher {
    conn_id: ConnectionId,
    conn_id: ConnectionId,
    trans_id: TransactionId,
    trans_id: TransactionId,
    rx: oneshot::Receiver<Result<AttAttributeDataChild, AttErrorCode>>,
    rx: oneshot::Receiver<Result<Vec<u8>, AttErrorCode>>,
}
}


/// This struct converts the asynchronus read/write operations of GattDatastore
/// This struct converts the asynchronus read/write operations of GattDatastore
@@ -72,7 +72,7 @@ impl CallbackTransactionManager {
        &self,
        &self,
        conn_id: ConnectionId,
        conn_id: ConnectionId,
        trans_id: TransactionId,
        trans_id: TransactionId,
        value: Result<AttAttributeDataChild, AttErrorCode>,
        value: Result<Vec<u8>, AttErrorCode>,
    ) -> Result<(), CallbackResponseError> {
    ) -> Result<(), CallbackResponseError> {
        let mut pending = self.pending_transactions.borrow_mut();
        let mut pending = self.pending_transactions.borrow_mut();
        if let Some(transaction) = pending.pending_transactions.remove(&(conn_id, trans_id)) {
        if let Some(transaction) = pending.pending_transactions.remove(&(conn_id, trans_id)) {
@@ -111,10 +111,7 @@ impl PendingTransactionsState {
impl PendingTransactionWatcher {
impl PendingTransactionWatcher {
    /// Wait for the transaction to resolve, or to hit the timeout. If the
    /// Wait for the transaction to resolve, or to hit the timeout. If the
    /// timeout is reached, clean up state related to transaction watching.
    /// timeout is reached, clean up state related to transaction watching.
    async fn wait(
    async fn wait(self, manager: &CallbackTransactionManager) -> Result<Vec<u8>, AttErrorCode> {
        self,
        manager: &CallbackTransactionManager,
    ) -> Result<AttAttributeDataChild, AttErrorCode> {
        if let Ok(Ok(result)) = timeout(TIMEOUT, self.rx).await {
        if let Ok(Ok(result)) = timeout(TIMEOUT, self.rx).await {
            result
            result
        } else {
        } else {
@@ -142,7 +139,7 @@ impl RawGattDatastore for GattDatastoreImpl {
        handle: AttHandle,
        handle: AttHandle,
        offset: u32,
        offset: u32,
        attr_type: AttributeBackingType,
        attr_type: AttributeBackingType,
    ) -> Result<AttAttributeDataChild, AttErrorCode> {
    ) -> Result<Vec<u8>, AttErrorCode> {
        let conn_id = ConnectionId::new(tcb_idx, self.server_id);
        let conn_id = ConnectionId::new(tcb_idx, self.server_id);


        let pending_transaction = self
        let pending_transaction = self
@@ -169,7 +166,7 @@ impl RawGattDatastore for GattDatastoreImpl {
        handle: AttHandle,
        handle: AttHandle,
        attr_type: AttributeBackingType,
        attr_type: AttributeBackingType,
        write_type: GattWriteRequestType,
        write_type: GattWriteRequestType,
        data: AttAttributeDataView<'_>,
        data: &[u8],
    ) -> Result<(), AttErrorCode> {
    ) -> Result<(), AttErrorCode> {
        let conn_id = ConnectionId::new(tcb_idx, self.server_id);
        let conn_id = ConnectionId::new(tcb_idx, self.server_id);


@@ -198,7 +195,7 @@ impl RawGattDatastore for GattDatastoreImpl {
        tcb_idx: TransportIndex,
        tcb_idx: TransportIndex,
        handle: AttHandle,
        handle: AttHandle,
        attr_type: AttributeBackingType,
        attr_type: AttributeBackingType,
        data: AttAttributeDataView<'_>,
        data: &[u8],
    ) {
    ) {
        let conn_id = ConnectionId::new(tcb_idx, self.server_id);
        let conn_id = ConnectionId::new(tcb_idx, self.server_id);


+4 −7
Original line number Original line Diff line number Diff line
@@ -12,10 +12,7 @@ use tokio::task::spawn_local;


use crate::{
use crate::{
    do_in_rust_thread,
    do_in_rust_thread,
    packets::{
    packets::{AttAttributeDataChild, AttBuilder, AttErrorCode, Serializable, SerializeError},
        AttAttributeDataChild, AttAttributeDataView, AttBuilder, AttErrorCode, Serializable,
        SerializeError,
    },
};
};


use super::{
use super::{
@@ -213,7 +210,7 @@ impl GattCallbacks for GattCallbacksImpl {
        handle: AttHandle,
        handle: AttHandle,
        attr_type: AttributeBackingType,
        attr_type: AttributeBackingType,
        write_type: GattWriteType,
        write_type: GattWriteType,
        value: AttAttributeDataView,
        value: &[u8],
    ) {
    ) {
        trace!(
        trace!(
            "on_server_write ({conn_id:?}, {trans_id:?}, {handle:?}, {attr_type:?}, {write_type:?}"
            "on_server_write ({conn_id:?}, {trans_id:?}, {handle:?}, {attr_type:?}, {write_type:?}"
@@ -229,7 +226,7 @@ impl GattCallbacks for GattCallbacksImpl {
            },
            },
            matches!(write_type, GattWriteType::Request { .. }),
            matches!(write_type, GattWriteType::Request { .. }),
            matches!(write_type, GattWriteType::Request(GattWriteRequestType::Prepare { .. })),
            matches!(write_type, GattWriteType::Request(GattWriteRequestType::Prepare { .. })),
            &value.get_raw_payload().collect::<Vec<_>>(),
            value,
        );
        );
    }
    }


@@ -419,7 +416,7 @@ fn send_response(_server_id: u8, conn_id: u16, trans_id: u32, status: u8, value:
    // TODO(aryarahul): fixup error codes to allow app-specific values (i.e. don't
    // TODO(aryarahul): fixup error codes to allow app-specific values (i.e. don't
    // make it an enum in PDL)
    // make it an enum in PDL)
    let value = if status == 0 {
    let value = if status == 0 {
        Ok(AttAttributeDataChild::RawData(value.to_vec().into_boxed_slice()))
        Ok(value.to_vec())
    } else {
    } else {
        Err(AttErrorCode::try_from(status).unwrap_or(AttErrorCode::UNLIKELY_ERROR))
        Err(AttErrorCode::try_from(status).unwrap_or(AttErrorCode::UNLIKELY_ERROR))
    };
    };
+9 −12
Original line number Original line Diff line number Diff line
//! Mocked implementation of GattCallbacks for use in test
//! Mocked implementation of GattCallbacks for use in test


use crate::{
use crate::gatt::{
    gatt::{
    callbacks::{GattWriteType, TransactionDecision},
    callbacks::{GattWriteType, TransactionDecision},
    ffi::AttributeBackingType,
    ffi::AttributeBackingType,
    ids::{AttHandle, ConnectionId, TransactionId},
    ids::{AttHandle, ConnectionId, TransactionId},
    server::IndicationError,
    server::IndicationError,
    GattCallbacks,
    GattCallbacks,
    },
    packets::{AttAttributeDataView, OwnedAttAttributeDataView, Packet},
};
};
use tokio::sync::mpsc::{self, unbounded_channel, UnboundedReceiver};
use tokio::sync::mpsc::{self, unbounded_channel, UnboundedReceiver};


@@ -35,7 +32,7 @@ pub enum MockCallbackEvents {
        AttHandle,
        AttHandle,
        AttributeBackingType,
        AttributeBackingType,
        GattWriteType,
        GattWriteType,
        OwnedAttAttributeDataView,
        Vec<u8>,
    ),
    ),
    /// GattCallbacks#on_indication_sent_confirmation invoked
    /// GattCallbacks#on_indication_sent_confirmation invoked
    OnIndicationSentConfirmation(ConnectionId, Result<(), IndicationError>),
    OnIndicationSentConfirmation(ConnectionId, Result<(), IndicationError>),
@@ -64,7 +61,7 @@ impl GattCallbacks for MockCallbacks {
        handle: AttHandle,
        handle: AttHandle,
        attr_type: AttributeBackingType,
        attr_type: AttributeBackingType,
        write_type: GattWriteType,
        write_type: GattWriteType,
        value: AttAttributeDataView,
        value: &[u8],
    ) {
    ) {
        self.0
        self.0
            .send(MockCallbackEvents::OnServerWrite(
            .send(MockCallbackEvents::OnServerWrite(
@@ -73,7 +70,7 @@ impl GattCallbacks for MockCallbacks {
                handle,
                handle,
                attr_type,
                attr_type,
                write_type,
                write_type,
                value.to_owned_packet(),
                value.to_vec(),
            ))
            ))
            .unwrap();
            .unwrap();
    }
    }
+6 −15
Original line number Original line Diff line number Diff line
@@ -6,10 +6,7 @@ use crate::{
        ffi::AttributeBackingType,
        ffi::AttributeBackingType,
        ids::{AttHandle, TransportIndex},
        ids::{AttHandle, TransportIndex},
    },
    },
    packets::{
    packets::AttErrorCode,
        AttAttributeDataChild, AttAttributeDataView, AttErrorCode, OwnedAttAttributeDataView,
        Packet,
    },
};
};
use async_trait::async_trait;
use async_trait::async_trait;
use log::info;
use log::info;
@@ -38,7 +35,7 @@ pub enum MockDatastoreEvents {
        TransportIndex,
        TransportIndex,
        AttHandle,
        AttHandle,
        AttributeBackingType,
        AttributeBackingType,
        oneshot::Sender<Result<AttAttributeDataChild, AttErrorCode>>,
        oneshot::Sender<Result<Vec<u8>, AttErrorCode>>,
    ),
    ),
    /// A characteristic was written to on a given handle. The oneshot is used
    /// A characteristic was written to on a given handle. The oneshot is used
    /// to return whether the write succeeded.
    /// to return whether the write succeeded.
@@ -46,7 +43,7 @@ pub enum MockDatastoreEvents {
        TransportIndex,
        TransportIndex,
        AttHandle,
        AttHandle,
        AttributeBackingType,
        AttributeBackingType,
        OwnedAttAttributeDataView,
        Vec<u8>,
        oneshot::Sender<Result<(), AttErrorCode>>,
        oneshot::Sender<Result<(), AttErrorCode>>,
    ),
    ),
}
}
@@ -58,7 +55,7 @@ impl GattDatastore for MockDatastore {
        tcb_idx: TransportIndex,
        tcb_idx: TransportIndex,
        handle: AttHandle,
        handle: AttHandle,
        attr_type: AttributeBackingType,
        attr_type: AttributeBackingType,
    ) -> Result<AttAttributeDataChild, AttErrorCode> {
    ) -> Result<Vec<u8>, AttErrorCode> {
        let (tx, rx) = oneshot::channel();
        let (tx, rx) = oneshot::channel();
        self.0.send(MockDatastoreEvents::Read(tcb_idx, handle, attr_type, tx)).unwrap();
        self.0.send(MockDatastoreEvents::Read(tcb_idx, handle, attr_type, tx)).unwrap();
        let resp = rx.await.unwrap();
        let resp = rx.await.unwrap();
@@ -71,17 +68,11 @@ impl GattDatastore for MockDatastore {
        tcb_idx: TransportIndex,
        tcb_idx: TransportIndex,
        handle: AttHandle,
        handle: AttHandle,
        attr_type: AttributeBackingType,
        attr_type: AttributeBackingType,
        data: AttAttributeDataView<'_>,
        data: &[u8],
    ) -> Result<(), AttErrorCode> {
    ) -> Result<(), AttErrorCode> {
        let (tx, rx) = oneshot::channel();
        let (tx, rx) = oneshot::channel();
        self.0
        self.0
            .send(MockDatastoreEvents::Write(
            .send(MockDatastoreEvents::Write(tcb_idx, handle, attr_type, data.to_vec(), tx))
                tcb_idx,
                handle,
                attr_type,
                data.to_owned_packet(),
                tx,
            ))
            .unwrap();
            .unwrap();
        rx.await.unwrap()
        rx.await.unwrap()
    }
    }
Loading