summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Henri Chataing <henrichataing@google.com> 2024-06-10 19:26:38 -0700
committer Henri Chataing <henrichataing@google.com> 2024-06-12 10:39:40 -0700
commit6f91bd9dea04591976e4271fdb4401bfc1bc11bf (patch)
tree370510f7a807b91880b90e0841d8a67491893b99
parent1077361f4ba2ddb4e715559ae0f4fed4f7d822b8 (diff)
system/rust: Update GATT datastore interfaces to use raw values
The code almost never makes use of the structured type and mostly relies on AttAttributeDataChild::RawData. Removing this type will help convert the pdl rust backend later as the generated type AttAttributeDataChild will no longer exist under this form. Bug: 331817295 Test: m com.android.btservices Test: atest --host libbluetooth_core_rs_test Flag: EXEMPT, mechanical refactor Change-Id: I429341ed0ccc4a8cdaba7cc86d1249f16f11a28e
-rw-r--r--system/rust/src/gatt/callbacks.rs38
-rw-r--r--system/rust/src/gatt/callbacks/callback_transaction_manager.rs19
-rw-r--r--system/rust/src/gatt/ffi.rs11
-rw-r--r--system/rust/src/gatt/mocks/mock_callbacks.rs21
-rw-r--r--system/rust/src/gatt/mocks/mock_datastore.rs21
-rw-r--r--system/rust/src/gatt/mocks/mock_raw_datastore.rs21
-rw-r--r--system/rust/src/gatt/server/att_database.rs30
-rw-r--r--system/rust/src/gatt/server/att_server_bearer.rs19
-rw-r--r--system/rust/src/gatt/server/command_handler.rs21
-rw-r--r--system/rust/src/gatt/server/gatt_database.rs122
-rw-r--r--system/rust/src/gatt/server/services/gap.rs10
-rw-r--r--system/rust/src/gatt/server/services/gatt.rs71
-rw-r--r--system/rust/src/gatt/server/test/test_att_db.rs23
-rw-r--r--system/rust/src/gatt/server/transactions/find_by_type_value.rs24
-rw-r--r--system/rust/src/gatt/server/transactions/helpers.rs1
-rw-r--r--system/rust/src/gatt/server/transactions/helpers/att_filter_by_size_type.rs15
-rw-r--r--system/rust/src/gatt/server/transactions/helpers/truncate_att_data.rs56
-rw-r--r--system/rust/src/gatt/server/transactions/read_request.rs17
-rw-r--r--system/rust/src/gatt/server/transactions/write_request.rs13
-rw-r--r--system/rust/src/packets.rs6
-rw-r--r--system/rust/tests/gatt_callbacks_test.rs71
-rw-r--r--system/rust/tests/gatt_server_test.rs47
22 files changed, 268 insertions, 409 deletions
diff --git a/system/rust/src/gatt/callbacks.rs b/system/rust/src/gatt/callbacks.rs
index a90e55c734..2d6a58cbdd 100644
--- a/system/rust/src/gatt/callbacks.rs
+++ b/system/rust/src/gatt/callbacks.rs
@@ -9,7 +9,7 @@ pub use callback_transaction_manager::{CallbackResponseError, CallbackTransactio
use async_trait::async_trait;
use log::warn;
-use crate::packets::{AttAttributeDataChild, AttAttributeDataView, AttErrorCode};
+use crate::packets::AttErrorCode;
use super::{
ffi::AttributeBackingType,
@@ -41,7 +41,7 @@ pub trait GattCallbacks {
handle: AttHandle,
attr_type: AttributeBackingType,
write_type: GattWriteType,
- value: AttAttributeDataView,
+ value: &[u8],
);
/// Invoked when a handle value indication transaction completes
@@ -102,7 +102,7 @@ pub trait RawGattDatastore {
handle: AttHandle,
offset: u32,
attr_type: AttributeBackingType,
- ) -> Result<AttAttributeDataChild, AttErrorCode>;
+ ) -> Result<Vec<u8>, AttErrorCode>;
/// Write data to a given characteristic on the specified connection.
async fn write(
@@ -111,7 +111,7 @@ pub trait RawGattDatastore {
handle: AttHandle,
attr_type: AttributeBackingType,
write_type: GattWriteRequestType,
- data: AttAttributeDataView<'_>,
+ data: &[u8],
) -> Result<(), AttErrorCode>;
/// Write data to a given characteristic on the specified connection, without waiting
@@ -121,7 +121,7 @@ pub trait RawGattDatastore {
tcb_idx: TransportIndex,
handle: AttHandle,
attr_type: AttributeBackingType,
- data: AttAttributeDataView<'_>,
+ data: &[u8],
);
/// Execute or cancel any prepared writes
@@ -142,7 +142,7 @@ pub trait GattDatastore {
tcb_idx: TransportIndex,
handle: AttHandle,
attr_type: AttributeBackingType,
- ) -> Result<AttAttributeDataChild, AttErrorCode>;
+ ) -> Result<Vec<u8>, AttErrorCode>;
/// Write data to a given characteristic on the specified connection.
async fn write(
@@ -150,7 +150,7 @@ pub trait GattDatastore {
tcb_idx: TransportIndex,
handle: AttHandle,
attr_type: AttributeBackingType,
- data: AttAttributeDataView<'_>,
+ data: &[u8],
) -> Result<(), AttErrorCode>;
}
@@ -163,7 +163,7 @@ impl<T: GattDatastore + ?Sized> RawGattDatastore for T {
handle: AttHandle,
offset: u32,
attr_type: AttributeBackingType,
- ) -> Result<AttAttributeDataChild, AttErrorCode> {
+ ) -> Result<Vec<u8>, AttErrorCode> {
if offset != 0 {
warn!("got read blob request for non-long attribute {handle:?}");
return Err(AttErrorCode::ATTRIBUTE_NOT_LONG);
@@ -178,7 +178,7 @@ impl<T: GattDatastore + ?Sized> RawGattDatastore for T {
handle: AttHandle,
attr_type: AttributeBackingType,
write_type: GattWriteRequestType,
- data: AttAttributeDataView<'_>,
+ data: &[u8],
) -> Result<(), AttErrorCode> {
match write_type {
GattWriteRequestType::Prepare { .. } => {
@@ -194,7 +194,7 @@ impl<T: GattDatastore + ?Sized> RawGattDatastore for T {
tcb_idx: TransportIndex,
handle: AttHandle,
_: AttributeBackingType,
- _: AttAttributeDataView<'_>,
+ _: &[u8],
) {
// 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");
@@ -213,11 +213,7 @@ mod test {
use crate::{
gatt::mocks::mock_datastore::{MockDatastore, MockDatastoreEvents},
- packets::OwnedAttAttributeDataView,
- utils::{
- packet::{build_att_data, build_view_or_crash},
- task::block_on_locally,
- },
+ utils::task::block_on_locally,
};
use super::*;
@@ -301,10 +297,6 @@ mod test {
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]
fn test_write_request_invoke() {
block_on_locally(async {
@@ -319,7 +311,7 @@ mod test {
HANDLE,
AttributeBackingType::Characteristic,
GattWriteRequestType::Request,
- make_data().view(),
+ &DATA,
)
.await
});
@@ -353,7 +345,7 @@ mod test {
HANDLE,
AttributeBackingType::Characteristic,
GattWriteRequestType::Request,
- make_data().view(),
+ &DATA,
)
.await
});
@@ -380,7 +372,7 @@ mod test {
HANDLE,
AttributeBackingType::Characteristic,
GattWriteRequestType::Prepare { offset: 1 },
- make_data().view(),
+ &DATA,
));
// assert: got the correct error code
@@ -400,7 +392,7 @@ mod test {
TCB_IDX,
HANDLE,
AttributeBackingType::Characteristic,
- make_data().view(),
+ &DATA,
);
// assert: no event sent up
diff --git a/system/rust/src/gatt/callbacks/callback_transaction_manager.rs b/system/rust/src/gatt/callbacks/callback_transaction_manager.rs
index c9c9862c81..4210d64535 100644
--- a/system/rust/src/gatt/callbacks/callback_transaction_manager.rs
+++ b/system/rust/src/gatt/callbacks/callback_transaction_manager.rs
@@ -9,7 +9,7 @@ use crate::{
ids::{AttHandle, ConnectionId, ServerId, TransactionId, TransportIndex},
GattCallbacks,
},
- packets::{AttAttributeDataChild, AttAttributeDataView, AttErrorCode},
+ packets::AttErrorCode,
};
use super::{
@@ -18,14 +18,14 @@ use super::{
};
struct PendingTransaction {
- response: oneshot::Sender<Result<AttAttributeDataChild, AttErrorCode>>,
+ response: oneshot::Sender<Result<Vec<u8>, AttErrorCode>>,
}
#[derive(Debug)]
struct PendingTransactionWatcher {
conn_id: ConnectionId,
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
@@ -72,7 +72,7 @@ impl CallbackTransactionManager {
&self,
conn_id: ConnectionId,
trans_id: TransactionId,
- value: Result<AttAttributeDataChild, AttErrorCode>,
+ value: Result<Vec<u8>, AttErrorCode>,
) -> Result<(), CallbackResponseError> {
let mut pending = self.pending_transactions.borrow_mut();
if let Some(transaction) = pending.pending_transactions.remove(&(conn_id, trans_id)) {
@@ -111,10 +111,7 @@ impl PendingTransactionsState {
impl PendingTransactionWatcher {
/// Wait for the transaction to resolve, or to hit the timeout. If the
/// timeout is reached, clean up state related to transaction watching.
- async fn wait(
- self,
- manager: &CallbackTransactionManager,
- ) -> Result<AttAttributeDataChild, AttErrorCode> {
+ async fn wait(self, manager: &CallbackTransactionManager) -> Result<Vec<u8>, AttErrorCode> {
if let Ok(Ok(result)) = timeout(TIMEOUT, self.rx).await {
result
} else {
@@ -142,7 +139,7 @@ impl RawGattDatastore for GattDatastoreImpl {
handle: AttHandle,
offset: u32,
attr_type: AttributeBackingType,
- ) -> Result<AttAttributeDataChild, AttErrorCode> {
+ ) -> Result<Vec<u8>, AttErrorCode> {
let conn_id = ConnectionId::new(tcb_idx, self.server_id);
let pending_transaction = self
@@ -169,7 +166,7 @@ impl RawGattDatastore for GattDatastoreImpl {
handle: AttHandle,
attr_type: AttributeBackingType,
write_type: GattWriteRequestType,
- data: AttAttributeDataView<'_>,
+ data: &[u8],
) -> Result<(), AttErrorCode> {
let conn_id = ConnectionId::new(tcb_idx, self.server_id);
@@ -198,7 +195,7 @@ impl RawGattDatastore for GattDatastoreImpl {
tcb_idx: TransportIndex,
handle: AttHandle,
attr_type: AttributeBackingType,
- data: AttAttributeDataView<'_>,
+ data: &[u8],
) {
let conn_id = ConnectionId::new(tcb_idx, self.server_id);
diff --git a/system/rust/src/gatt/ffi.rs b/system/rust/src/gatt/ffi.rs
index d21c23dd1c..d5a9ec7a2d 100644
--- a/system/rust/src/gatt/ffi.rs
+++ b/system/rust/src/gatt/ffi.rs
@@ -12,10 +12,7 @@ use tokio::task::spawn_local;
use crate::{
do_in_rust_thread,
- packets::{
- AttAttributeDataChild, AttAttributeDataView, AttBuilder, AttErrorCode, Serializable,
- SerializeError,
- },
+ packets::{AttAttributeDataChild, AttBuilder, AttErrorCode, Serializable, SerializeError},
};
use super::{
@@ -213,7 +210,7 @@ impl GattCallbacks for GattCallbacksImpl {
handle: AttHandle,
attr_type: AttributeBackingType,
write_type: GattWriteType,
- value: AttAttributeDataView,
+ value: &[u8],
) {
trace!(
"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(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
// make it an enum in PDL)
let value = if status == 0 {
- Ok(AttAttributeDataChild::RawData(value.to_vec().into_boxed_slice()))
+ Ok(value.to_vec())
} else {
Err(AttErrorCode::try_from(status).unwrap_or(AttErrorCode::UNLIKELY_ERROR))
};
diff --git a/system/rust/src/gatt/mocks/mock_callbacks.rs b/system/rust/src/gatt/mocks/mock_callbacks.rs
index a5dbee253f..14a8da7a6b 100644
--- a/system/rust/src/gatt/mocks/mock_callbacks.rs
+++ b/system/rust/src/gatt/mocks/mock_callbacks.rs
@@ -1,14 +1,11 @@
//! Mocked implementation of GattCallbacks for use in test
-use crate::{
- gatt::{
- callbacks::{GattWriteType, TransactionDecision},
- ffi::AttributeBackingType,
- ids::{AttHandle, ConnectionId, TransactionId},
- server::IndicationError,
- GattCallbacks,
- },
- packets::{AttAttributeDataView, OwnedAttAttributeDataView, Packet},
+use crate::gatt::{
+ callbacks::{GattWriteType, TransactionDecision},
+ ffi::AttributeBackingType,
+ ids::{AttHandle, ConnectionId, TransactionId},
+ server::IndicationError,
+ GattCallbacks,
};
use tokio::sync::mpsc::{self, unbounded_channel, UnboundedReceiver};
@@ -35,7 +32,7 @@ pub enum MockCallbackEvents {
AttHandle,
AttributeBackingType,
GattWriteType,
- OwnedAttAttributeDataView,
+ Vec<u8>,
),
/// GattCallbacks#on_indication_sent_confirmation invoked
OnIndicationSentConfirmation(ConnectionId, Result<(), IndicationError>),
@@ -64,7 +61,7 @@ impl GattCallbacks for MockCallbacks {
handle: AttHandle,
attr_type: AttributeBackingType,
write_type: GattWriteType,
- value: AttAttributeDataView,
+ value: &[u8],
) {
self.0
.send(MockCallbackEvents::OnServerWrite(
@@ -73,7 +70,7 @@ impl GattCallbacks for MockCallbacks {
handle,
attr_type,
write_type,
- value.to_owned_packet(),
+ value.to_vec(),
))
.unwrap();
}
diff --git a/system/rust/src/gatt/mocks/mock_datastore.rs b/system/rust/src/gatt/mocks/mock_datastore.rs
index e21889421f..901fe75565 100644
--- a/system/rust/src/gatt/mocks/mock_datastore.rs
+++ b/system/rust/src/gatt/mocks/mock_datastore.rs
@@ -6,10 +6,7 @@ use crate::{
ffi::AttributeBackingType,
ids::{AttHandle, TransportIndex},
},
- packets::{
- AttAttributeDataChild, AttAttributeDataView, AttErrorCode, OwnedAttAttributeDataView,
- Packet,
- },
+ packets::AttErrorCode,
};
use async_trait::async_trait;
use log::info;
@@ -38,7 +35,7 @@ pub enum MockDatastoreEvents {
TransportIndex,
AttHandle,
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
/// to return whether the write succeeded.
@@ -46,7 +43,7 @@ pub enum MockDatastoreEvents {
TransportIndex,
AttHandle,
AttributeBackingType,
- OwnedAttAttributeDataView,
+ Vec<u8>,
oneshot::Sender<Result<(), AttErrorCode>>,
),
}
@@ -58,7 +55,7 @@ impl GattDatastore for MockDatastore {
tcb_idx: TransportIndex,
handle: AttHandle,
attr_type: AttributeBackingType,
- ) -> Result<AttAttributeDataChild, AttErrorCode> {
+ ) -> Result<Vec<u8>, AttErrorCode> {
let (tx, rx) = oneshot::channel();
self.0.send(MockDatastoreEvents::Read(tcb_idx, handle, attr_type, tx)).unwrap();
let resp = rx.await.unwrap();
@@ -71,17 +68,11 @@ impl GattDatastore for MockDatastore {
tcb_idx: TransportIndex,
handle: AttHandle,
attr_type: AttributeBackingType,
- data: AttAttributeDataView<'_>,
+ data: &[u8],
) -> Result<(), AttErrorCode> {
let (tx, rx) = oneshot::channel();
self.0
- .send(MockDatastoreEvents::Write(
- tcb_idx,
- handle,
- attr_type,
- data.to_owned_packet(),
- tx,
- ))
+ .send(MockDatastoreEvents::Write(tcb_idx, handle, attr_type, data.to_vec(), tx))
.unwrap();
rx.await.unwrap()
}
diff --git a/system/rust/src/gatt/mocks/mock_raw_datastore.rs b/system/rust/src/gatt/mocks/mock_raw_datastore.rs
index 7d4055ca2e..0deb220d28 100644
--- a/system/rust/src/gatt/mocks/mock_raw_datastore.rs
+++ b/system/rust/src/gatt/mocks/mock_raw_datastore.rs
@@ -6,10 +6,7 @@ use crate::{
ffi::AttributeBackingType,
ids::{AttHandle, TransportIndex},
},
- packets::{
- AttAttributeDataChild, AttAttributeDataView, AttErrorCode, OwnedAttAttributeDataView,
- Packet,
- },
+ packets::AttErrorCode,
};
use async_trait::async_trait;
use log::info;
@@ -39,7 +36,7 @@ pub enum MockRawDatastoreEvents {
AttHandle,
AttributeBackingType,
u32,
- oneshot::Sender<Result<AttAttributeDataChild, AttErrorCode>>,
+ oneshot::Sender<Result<Vec<u8>, AttErrorCode>>,
),
/// A characteristic was written to on a given handle. The oneshot is used
/// to return whether the write succeeded.
@@ -48,11 +45,11 @@ pub enum MockRawDatastoreEvents {
AttHandle,
AttributeBackingType,
GattWriteRequestType,
- OwnedAttAttributeDataView,
+ Vec<u8>,
oneshot::Sender<Result<(), AttErrorCode>>,
),
/// A characteristic was written to on a given handle, where the response was disregarded.
- WriteNoResponse(TransportIndex, AttHandle, AttributeBackingType, OwnedAttAttributeDataView),
+ WriteNoResponse(TransportIndex, AttHandle, AttributeBackingType, Vec<u8>),
/// The prepared writes have been committed / aborted. The oneshot is used
/// to return whether this operation succeeded.
Execute(TransportIndex, TransactionDecision, oneshot::Sender<Result<(), AttErrorCode>>),
@@ -66,7 +63,7 @@ impl RawGattDatastore for MockRawDatastore {
handle: AttHandle,
offset: u32,
attr_type: AttributeBackingType,
- ) -> Result<AttAttributeDataChild, AttErrorCode> {
+ ) -> Result<Vec<u8>, AttErrorCode> {
let (tx, rx) = oneshot::channel();
self.0.send(MockRawDatastoreEvents::Read(tcb_idx, handle, attr_type, offset, tx)).unwrap();
let resp = rx.await.unwrap();
@@ -80,7 +77,7 @@ impl RawGattDatastore for MockRawDatastore {
handle: AttHandle,
attr_type: AttributeBackingType,
write_type: GattWriteRequestType,
- data: AttAttributeDataView<'_>,
+ data: &[u8],
) -> Result<(), AttErrorCode> {
let (tx, rx) = oneshot::channel();
self.0
@@ -89,7 +86,7 @@ impl RawGattDatastore for MockRawDatastore {
handle,
attr_type,
write_type,
- data.to_owned_packet(),
+ data.to_vec(),
tx,
))
.unwrap();
@@ -101,14 +98,14 @@ impl RawGattDatastore for MockRawDatastore {
tcb_idx: TransportIndex,
handle: AttHandle,
attr_type: AttributeBackingType,
- data: AttAttributeDataView<'_>,
+ data: &[u8],
) {
self.0
.send(MockRawDatastoreEvents::WriteNoResponse(
tcb_idx,
handle,
attr_type,
- data.to_owned_packet(),
+ data.to_vec(),
))
.unwrap();
}
diff --git a/system/rust/src/gatt/server/att_database.rs b/system/rust/src/gatt/server/att_database.rs
index 2235fd81f5..47e67270a2 100644
--- a/system/rust/src/gatt/server/att_database.rs
+++ b/system/rust/src/gatt/server/att_database.rs
@@ -4,9 +4,7 @@ use bitflags::bitflags;
use crate::{
core::uuid::Uuid,
gatt::ids::AttHandle,
- packets::{
- AttAttributeDataChild, AttAttributeDataView, AttErrorCode, AttHandleBuilder, AttHandleView,
- },
+ packets::{AttErrorCode, AttHandleBuilder, AttHandleView},
};
impl From<AttHandleView<'_>> for AttHandle {
@@ -69,20 +67,13 @@ impl AttPermissions {
#[async_trait(?Send)]
pub trait AttDatabase {
/// Read an attribute by handle
- async fn read_attribute(
- &self,
- handle: AttHandle,
- ) -> Result<AttAttributeDataChild, AttErrorCode>;
+ async fn read_attribute(&self, handle: AttHandle) -> Result<Vec<u8>, AttErrorCode>;
/// Write to an attribute by handle
- async fn write_attribute(
- &self,
- handle: AttHandle,
- data: AttAttributeDataView<'_>,
- ) -> Result<(), AttErrorCode>;
+ async fn write_attribute(&self, handle: AttHandle, data: &[u8]) -> Result<(), AttErrorCode>;
/// Write to an attribute by handle
- fn write_no_response_attribute(&self, handle: AttHandle, data: AttAttributeDataView<'_>);
+ fn write_no_response_attribute(&self, handle: AttHandle, data: &[u8]);
/// List all the attributes in this database.
///
@@ -117,22 +108,15 @@ pub struct SnapshottedAttDatabase<'a> {
#[async_trait(?Send)]
impl AttDatabase for SnapshottedAttDatabase<'_> {
- async fn read_attribute(
- &self,
- handle: AttHandle,
- ) -> Result<AttAttributeDataChild, AttErrorCode> {
+ async fn read_attribute(&self, handle: AttHandle) -> Result<Vec<u8>, AttErrorCode> {
self.backing.read_attribute(handle).await
}
- async fn write_attribute(
- &self,
- handle: AttHandle,
- data: AttAttributeDataView<'_>,
- ) -> Result<(), AttErrorCode> {
+ async fn write_attribute(&self, handle: AttHandle, data: &[u8]) -> Result<(), AttErrorCode> {
self.backing.write_attribute(handle, data).await
}
- fn write_no_response_attribute(&self, handle: AttHandle, data: AttAttributeDataView<'_>) {
+ fn write_no_response_attribute(&self, handle: AttHandle, data: &[u8]) {
self.backing.write_no_response_attribute(handle, data);
}
diff --git a/system/rust/src/gatt/server/att_server_bearer.rs b/system/rust/src/gatt/server/att_server_bearer.rs
index c8b7a38241..d2d732fc7a 100644
--- a/system/rust/src/gatt/server/att_server_bearer.rs
+++ b/system/rust/src/gatt/server/att_server_bearer.rs
@@ -238,11 +238,11 @@ mod test {
},
},
packets::{
- AttAttributeDataChild, AttHandleValueConfirmationBuilder, AttOpcode,
- AttReadRequestBuilder, AttReadResponseBuilder,
+ AttAttributeDataBuilder, AttAttributeDataChild, AttHandleValueConfirmationBuilder,
+ AttOpcode, AttReadRequestBuilder, AttReadResponseBuilder,
},
utils::{
- packet::{build_att_data, build_att_view_or_crash},
+ packet::build_att_view_or_crash,
task::{block_on_locally, try_await},
},
};
@@ -356,7 +356,7 @@ mod test {
Ok(())
};
let conn = SharedBox::new(AttServerBearer::new(db.get_att_database(TCB_IDX), send_packet));
- let data = AttAttributeDataChild::RawData([1, 2].into());
+ let data = [1, 2];
// act: send two read requests before replying to either read
// first request
@@ -380,7 +380,7 @@ mod test {
else {
unreachable!();
};
- data_resp.send(Ok(data.clone())).unwrap();
+ data_resp.send(Ok(data.to_vec())).unwrap();
trace!("reply sent from upper tester");
// assert: that the first reply was made
@@ -389,7 +389,14 @@ mod test {
resp,
AttBuilder {
opcode: AttOpcode::READ_RESPONSE,
- _child_: AttReadResponseBuilder { value: build_att_data(data) }.into(),
+ _child_: AttReadResponseBuilder {
+ value: AttAttributeDataBuilder {
+ _child_: AttAttributeDataChild::RawData(
+ data.to_vec().into_boxed_slice()
+ )
+ },
+ }
+ .into()
}
);
// assert no other replies were made
diff --git a/system/rust/src/gatt/server/command_handler.rs b/system/rust/src/gatt/server/command_handler.rs
index 365ed3bc1e..a147584da9 100644
--- a/system/rust/src/gatt/server/command_handler.rs
+++ b/system/rust/src/gatt/server/command_handler.rs
@@ -22,8 +22,10 @@ impl<Db: AttDatabase> AttCommandHandler<Db> {
warn!("failed to parse WRITE_COMMAND packet");
return;
};
- snapshotted_db
- .write_no_response_attribute(packet.get_handle().into(), packet.get_value());
+ snapshotted_db.write_no_response_attribute(
+ packet.get_handle().into(),
+ &packet.get_value().get_raw_payload().collect::<Vec<_>>(),
+ );
}
_ => {
warn!("Dropping unsupported opcode {:?}", packet.get_opcode());
@@ -46,13 +48,10 @@ mod test {
},
},
packets::{
- AttAttributeDataChild, AttErrorCode, AttErrorResponseBuilder, AttOpcode,
- AttWriteCommandBuilder,
- },
- utils::{
- packet::{build_att_data, build_att_view_or_crash},
- task::block_on_locally,
+ AttAttributeDataBuilder, AttAttributeDataChild, AttErrorCode, AttErrorResponseBuilder,
+ AttOpcode, AttWriteCommandBuilder,
},
+ utils::{packet::build_att_view_or_crash, task::block_on_locally},
};
#[test]
@@ -67,12 +66,14 @@ mod test {
vec![1, 2, 3],
)]);
let handler = AttCommandHandler { db: db.clone() };
- let data = AttAttributeDataChild::RawData([1, 2].into());
+ let data = [1, 2];
// act: send write command
let att_view = build_att_view_or_crash(AttWriteCommandBuilder {
handle: AttHandle(3).into(),
- value: build_att_data(data.clone()),
+ value: AttAttributeDataBuilder {
+ _child_: AttAttributeDataChild::RawData(data.to_vec().into_boxed_slice()),
+ },
});
handler.process_packet(att_view.view());
diff --git a/system/rust/src/gatt/server/gatt_database.rs b/system/rust/src/gatt/server/gatt_database.rs
index 806ab4e7c2..baffd17773 100644
--- a/system/rust/src/gatt/server/gatt_database.rs
+++ b/system/rust/src/gatt/server/gatt_database.rs
@@ -19,9 +19,9 @@ use crate::{
ids::{AttHandle, TransportIndex},
},
packets::{
- AttAttributeDataChild, AttAttributeDataView, AttErrorCode,
- GattCharacteristicDeclarationValueBuilder, GattCharacteristicPropertiesBuilder,
- GattServiceDeclarationValueBuilder, UuidBuilder,
+ AttErrorCode, GattCharacteristicDeclarationValueBuilder,
+ GattCharacteristicPropertiesBuilder, GattServiceDeclarationValueBuilder, Serializable,
+ UuidBuilder,
},
};
@@ -98,7 +98,7 @@ struct GattDatabaseSchema {
#[derive(Clone)]
enum AttAttributeBackingValue {
- Static(AttAttributeDataChild),
+ Static(Vec<u8>),
DynamicCharacteristic(Rc<dyn RawGattDatastore>),
DynamicDescriptor(Rc<dyn RawGattDatastore>),
}
@@ -187,7 +187,10 @@ impl GattDatabase {
},
AttAttributeBackingValue::Static(
GattServiceDeclarationValueBuilder { uuid: UuidBuilder::from(service.type_) }
- .into(),
+ .to_vec()
+ .map_err(|e| {
+ anyhow::anyhow!("failed to encode primary service declaration: {e:?}")
+ })?,
),
);
@@ -224,7 +227,10 @@ impl GattDatabase {
handle: characteristic.handle.into(),
uuid: characteristic.type_.into(),
}
- .into(),
+ .to_vec()
+ .map_err(|e| {
+ anyhow::anyhow!("failed to encode characteristic declaration: {e:?}")
+ })?,
),
);
@@ -341,10 +347,7 @@ pub struct AttDatabaseImpl {
#[async_trait(?Send)]
impl AttDatabase for AttDatabaseImpl {
- async fn read_attribute(
- &self,
- handle: AttHandle,
- ) -> Result<AttAttributeDataChild, AttErrorCode> {
+ async fn read_attribute(&self, handle: AttHandle) -> Result<Vec<u8>, AttErrorCode> {
let value = self.gatt_db.with(|gatt_db| {
let Some(gatt_db) = gatt_db else {
// db must have been closed
@@ -385,11 +388,7 @@ impl AttDatabase for AttDatabaseImpl {
}
}
- async fn write_attribute(
- &self,
- handle: AttHandle,
- data: AttAttributeDataView<'_>,
- ) -> Result<(), AttErrorCode> {
+ async fn write_attribute(&self, handle: AttHandle, data: &[u8]) -> Result<(), AttErrorCode> {
let value = self.gatt_db.with(|gatt_db| {
let Some(gatt_db) = gatt_db else {
// db must have been closed
@@ -435,7 +434,7 @@ impl AttDatabase for AttDatabaseImpl {
}
}
- fn write_no_response_attribute(&self, handle: AttHandle, data: AttAttributeDataView<'_>) {
+ fn write_no_response_attribute(&self, handle: AttHandle, data: &[u8]) {
let value = self.gatt_db.with(|gatt_db| {
let Some(gatt_db) = gatt_db else {
// db must have been closed
@@ -522,11 +521,8 @@ mod test {
mock_datastore::{MockDatastore, MockDatastoreEvents},
mock_raw_datastore::{MockRawDatastore, MockRawDatastoreEvents},
},
- packets::Packet,
- utils::{
- packet::{build_att_data, build_view_or_crash},
- task::block_on_locally,
- },
+ packets::AttAttributeDataChild,
+ utils::task::block_on_locally,
};
use super::*;
@@ -582,9 +578,11 @@ mod test {
);
assert_eq!(
service_value,
- Ok(AttAttributeDataChild::GattServiceDeclarationValue(
+ AttAttributeDataChild::GattServiceDeclarationValue(
GattServiceDeclarationValueBuilder { uuid: SERVICE_TYPE.into() }
- ))
+ )
+ .to_vec()
+ .map_err(|_| AttErrorCode::UNLIKELY_ERROR)
);
}
@@ -719,7 +717,7 @@ mod test {
assert_eq!(
characteristic_decl,
- Ok(AttAttributeDataChild::GattCharacteristicDeclarationValue(
+ AttAttributeDataChild::GattCharacteristicDeclarationValue(
GattCharacteristicDeclarationValueBuilder {
properties: GattCharacteristicPropertiesBuilder {
read: 1,
@@ -734,7 +732,9 @@ mod test {
handle: CHARACTERISTIC_VALUE_HANDLE.into(),
uuid: CHARACTERISTIC_TYPE.into()
}
- ))
+ )
+ .to_vec()
+ .map_err(|_| AttErrorCode::UNLIKELY_ERROR)
);
}
@@ -767,7 +767,7 @@ mod test {
tokio_test::block_on(att_db.read_attribute(CHARACTERISTIC_DECLARATION_HANDLE));
assert_eq!(
characteristic_decl,
- Ok(AttAttributeDataChild::GattCharacteristicDeclarationValue(
+ AttAttributeDataChild::GattCharacteristicDeclarationValue(
GattCharacteristicDeclarationValueBuilder {
properties: GattCharacteristicPropertiesBuilder {
read: 1,
@@ -782,7 +782,9 @@ mod test {
handle: CHARACTERISTIC_VALUE_HANDLE.into(),
uuid: CHARACTERISTIC_TYPE.into()
}
- ))
+ )
+ .to_vec()
+ .map_err(|_| AttErrorCode::UNLIKELY_ERROR)
);
}
@@ -807,7 +809,7 @@ mod test {
)
.unwrap();
let att_db = gatt_db.get_att_database(TCB_IDX);
- let data = AttAttributeDataChild::RawData(Box::new([1, 2]));
+ let data = [1, 2];
// act: read from the database, and supply a value from the backing datastore
let characteristic_value = tokio_test::block_on(async {
@@ -822,7 +824,7 @@ mod test {
else {
unreachable!()
};
- reply.send(Ok(data.clone())).unwrap();
+ reply.send(Ok(data.to_vec())).unwrap();
},
att_db.read_attribute(CHARACTERISTIC_VALUE_HANDLE)
)
@@ -830,7 +832,7 @@ mod test {
});
// assert: the supplied value matches what the att datastore returned
- assert_eq!(characteristic_value, Ok(data));
+ assert_eq!(characteristic_value, Ok(data.to_vec()));
}
#[test]
@@ -932,18 +934,13 @@ mod test {
)
.unwrap();
let att_db = gatt_db.get_att_database(TCB_IDX);
- let data =
- build_view_or_crash(build_att_data(AttAttributeDataChild::RawData(Box::new([1, 2]))));
+ let data = [1, 2];
// act: write to the database
let recv_data = block_on_locally(async {
// start write task
- let cloned_data = data.view().to_owned_packet();
spawn_local(async move {
- att_db
- .write_attribute(CHARACTERISTIC_VALUE_HANDLE, cloned_data.view())
- .await
- .unwrap();
+ att_db.write_attribute(CHARACTERISTIC_VALUE_HANDLE, &data).await.unwrap();
});
let MockDatastoreEvents::Write(
@@ -960,10 +957,7 @@ mod test {
});
// assert: the received value matches what we supplied
- assert_eq!(
- recv_data.view().get_raw_payload().collect::<Vec<_>>(),
- data.view().get_raw_payload().collect::<Vec<_>>()
- );
+ assert_eq!(recv_data, data);
}
#[test]
@@ -987,8 +981,7 @@ mod test {
)
.unwrap();
let att_db = gatt_db.get_att_database(TCB_IDX);
- let data =
- build_view_or_crash(build_att_data(AttAttributeDataChild::RawData(Box::new([1, 2]))));
+ let data = [1, 2];
// act: write to the database
let res = tokio_test::block_on(async {
@@ -1001,7 +994,7 @@ mod test {
};
reply.send(Err(AttErrorCode::UNLIKELY_ERROR)).unwrap();
},
- att_db.write_attribute(CHARACTERISTIC_VALUE_HANDLE, data.view())
+ att_db.write_attribute(CHARACTERISTIC_VALUE_HANDLE, &data)
)
.1
});
@@ -1029,13 +1022,10 @@ mod test {
Rc::new(gatt_datastore),
)
.unwrap();
- let data =
- build_view_or_crash(build_att_data(AttAttributeDataChild::RawData(Box::new([1, 2]))));
+ let data = [1, 2];
let characteristic_value = tokio_test::block_on(
- gatt_db
- .get_att_database(TCB_IDX)
- .write_attribute(CHARACTERISTIC_VALUE_HANDLE, data.view()),
+ gatt_db.get_att_database(TCB_IDX).write_attribute(CHARACTERISTIC_VALUE_HANDLE, &data),
);
assert_eq!(characteristic_value, Err(AttErrorCode::WRITE_NOT_PERMITTED));
@@ -1065,7 +1055,7 @@ mod test {
)
.unwrap();
let att_db = gatt_db.get_att_database(TCB_IDX);
- let data = AttAttributeDataChild::RawData(Box::new([1, 2]));
+ let data = [1, 2];
let descriptor_value = block_on_locally(async {
// start write task
@@ -1082,7 +1072,7 @@ mod test {
unreachable!();
};
- reply.send(Ok(data.clone())).unwrap();
+ reply.send(Ok(data.to_vec())).unwrap();
pending_read.await.unwrap()
});
@@ -1115,15 +1105,14 @@ mod test {
)
.unwrap();
let att_db = gatt_db.get_att_database(TCB_IDX);
- let data =
- build_view_or_crash(build_att_data(AttAttributeDataChild::RawData(Box::new([1, 2]))));
+ let data = [1, 2];
// act: write, and wait for the callback to be invoked
block_on_locally(async {
// start write task
- spawn_local(async move {
- att_db.write_attribute(DESCRIPTOR_HANDLE, data.view()).await.unwrap()
- });
+ spawn_local(
+ async move { att_db.write_attribute(DESCRIPTOR_HANDLE, &data).await.unwrap() },
+ );
let MockDatastoreEvents::Write(
TCB_IDX,
@@ -1251,7 +1240,7 @@ mod test {
.unwrap();
let att_db = gatt_db.get_att_database(TCB_IDX);
- let data = AttAttributeDataChild::RawData(Box::new([1, 2]));
+ let data = [1, 2];
// act: read from the second characteristic and supply a response from the second datastore
let characteristic_value = tokio_test::block_on(async {
@@ -1266,7 +1255,7 @@ mod test {
else {
unreachable!()
};
- reply.send(Ok(data.clone())).unwrap();
+ reply.send(Ok(data.to_vec())).unwrap();
},
att_db.read_attribute(AttHandle(6))
)
@@ -1274,7 +1263,7 @@ mod test {
});
// assert: the supplied value matches what the att datastore returned
- assert_eq!(characteristic_value, Ok(data));
+ assert_eq!(characteristic_value, Ok(data.to_vec()));
// the first datastore received no events
assert_eq!(data_evts_1.try_recv().unwrap_err(), TryRecvError::Empty);
// the second datastore has no remaining events
@@ -1510,11 +1499,10 @@ mod test {
)
.unwrap();
let att_db = gatt_db.get_att_database(TCB_IDX);
- let data =
- build_view_or_crash(build_att_data(AttAttributeDataChild::RawData(Box::new([1, 2]))));
+ let data = [1, 2];
// act: write without response to the database
- att_db.write_no_response_attribute(CHARACTERISTIC_VALUE_HANDLE, data.view());
+ att_db.write_no_response_attribute(CHARACTERISTIC_VALUE_HANDLE, &data);
// assert: we got a callback
let event = data_evts.blocking_recv().unwrap();
@@ -1527,10 +1515,7 @@ mod test {
else {
unreachable!("{event:?}");
};
- assert_eq!(
- recv_data.view().get_raw_payload().collect::<Vec<_>>(),
- data.view().get_raw_payload().collect::<Vec<_>>()
- );
+ assert_eq!(recv_data, data);
}
#[test]
@@ -1555,11 +1540,10 @@ mod test {
)
.unwrap();
let att_db = gatt_db.get_att_database(TCB_IDX);
- let data =
- build_view_or_crash(build_att_data(AttAttributeDataChild::RawData(Box::new([1, 2]))));
+ let data = [1, 2];
// act: try writing without response to this characteristic
- att_db.write_no_response_attribute(CHARACTERISTIC_VALUE_HANDLE, data.view());
+ att_db.write_no_response_attribute(CHARACTERISTIC_VALUE_HANDLE, &data);
// assert: no callback was sent
assert_eq!(data_events.try_recv().unwrap_err(), TryRecvError::Empty);
diff --git a/system/rust/src/gatt/server/services/gap.rs b/system/rust/src/gatt/server/services/gap.rs
index c601587a18..f5476301ff 100644
--- a/system/rust/src/gatt/server/services/gap.rs
+++ b/system/rust/src/gatt/server/services/gap.rs
@@ -15,7 +15,7 @@ use crate::{
AttPermissions, GattCharacteristicWithHandle, GattDatabase, GattServiceWithHandle,
},
},
- packets::{AttAttributeDataChild, AttAttributeDataView, AttErrorCode},
+ packets::AttErrorCode,
};
struct GapService;
@@ -39,7 +39,7 @@ impl GattDatastore for GapService {
_: TransportIndex,
handle: AttHandle,
_: AttributeBackingType,
- ) -> Result<AttAttributeDataChild, AttErrorCode> {
+ ) -> Result<Vec<u8>, AttErrorCode> {
match handle {
DEVICE_NAME_HANDLE => {
// for non-bonded peers, don't let them read the device name
@@ -47,7 +47,7 @@ impl GattDatastore for GapService {
Err(AttErrorCode::INSUFFICIENT_AUTHENTICATION)
}
// 0x0000 from AssignedNumbers => "Unknown"
- DEVICE_APPEARANCE_HANDLE => Ok(AttAttributeDataChild::RawData([0x00, 0x00].into())),
+ DEVICE_APPEARANCE_HANDLE => Ok(vec![0x00, 0x00]),
_ => unreachable!("unexpected handle read"),
}
}
@@ -57,7 +57,7 @@ impl GattDatastore for GapService {
_: TransportIndex,
_: AttHandle,
_: AttributeBackingType,
- _: AttAttributeDataView<'_>,
+ _: &[u8],
) -> Result<(), AttErrorCode> {
unreachable!("no GAP data should be writable")
}
@@ -160,6 +160,6 @@ mod test {
let name = block_on_locally(att_db.read_attribute(DEVICE_APPEARANCE_HANDLE));
// assert: the name is not readable
- assert_eq!(name, Ok(AttAttributeDataChild::RawData([0x00, 0x00].into())));
+ assert_eq!(name, Ok(vec![0x00, 0x00]));
}
}
diff --git a/system/rust/src/gatt/server/services/gatt.rs b/system/rust/src/gatt/server/services/gatt.rs
index ba42a0ca6d..5bb6ce5f89 100644
--- a/system/rust/src/gatt/server/services/gatt.rs
+++ b/system/rust/src/gatt/server/services/gatt.rs
@@ -25,9 +25,8 @@ use crate::{
},
},
packets::{
- AttAttributeDataChild, AttAttributeDataView, AttErrorCode,
- GattClientCharacteristicConfigurationBuilder, GattClientCharacteristicConfigurationView,
- GattServiceChangedBuilder, Packet,
+ AttErrorCode, GattClientCharacteristicConfigurationBuilder,
+ GattClientCharacteristicConfigurationView, GattServiceChangedBuilder, Packet, Serializable,
},
};
@@ -61,9 +60,9 @@ impl GattDatastore for GattService {
tcb_idx: TransportIndex,
handle: AttHandle,
_: AttributeBackingType,
- ) -> Result<AttAttributeDataChild, AttErrorCode> {
+ ) -> Result<Vec<u8>, AttErrorCode> {
if handle == SERVICE_CHANGE_CCC_DESCRIPTOR_HANDLE {
- Ok(GattClientCharacteristicConfigurationBuilder {
+ GattClientCharacteristicConfigurationBuilder {
notification: 0,
indication: self
.clients
@@ -73,7 +72,8 @@ impl GattDatastore for GattService {
.unwrap_or(false)
.into(),
}
- .into())
+ .to_vec()
+ .map_err(|_| AttErrorCode::UNLIKELY_ERROR)
} else {
unreachable!()
}
@@ -84,11 +84,11 @@ impl GattDatastore for GattService {
tcb_idx: TransportIndex,
handle: AttHandle,
_: AttributeBackingType,
- data: AttAttributeDataView<'_>,
+ data: &[u8],
) -> Result<(), AttErrorCode> {
if handle == SERVICE_CHANGE_CCC_DESCRIPTOR_HANDLE {
- let ccc =
- GattClientCharacteristicConfigurationView::try_parse(data).map_err(|err| {
+ let ccc = GattClientCharacteristicConfigurationView::try_parse_from_buffer(data)
+ .map_err(|err| {
warn!("failed to parse CCC descriptor, got: {err:?}");
AttErrorCode::APPLICATION_ERROR
})?;
@@ -190,11 +190,8 @@ mod test {
},
},
},
- packets::{AttBuilder, AttChild},
- utils::{
- packet::{build_att_data, build_view_or_crash},
- task::{block_on_locally, try_await},
- },
+ packets::{AttAttributeDataChild, AttBuilder, AttChild},
+ utils::task::{block_on_locally, try_await},
};
const TCB_IDX: TransportIndex = TransportIndex(1);
@@ -260,14 +257,10 @@ mod test {
let resp =
block_on_locally(att_db.read_attribute(SERVICE_CHANGE_CCC_DESCRIPTOR_HANDLE)).unwrap();
- // assert: we are not registered for either indications/notifications
- let AttAttributeDataChild::GattClientCharacteristicConfiguration(configuration) = resp
- else {
- unreachable!()
- };
assert_eq!(
- configuration,
+ Ok(resp),
GattClientCharacteristicConfigurationBuilder { notification: 0, indication: 0 }
+ .to_vec()
);
}
@@ -278,11 +271,9 @@ mod test {
att_db
.write_attribute(
handle,
- build_view_or_crash(build_att_data(GattClientCharacteristicConfigurationBuilder {
- notification: 0,
- indication: 1,
- }))
- .view(),
+ &GattClientCharacteristicConfigurationBuilder { notification: 0, indication: 1 }
+ .to_vec()
+ .unwrap(),
)
.await
}
@@ -301,13 +292,10 @@ mod test {
block_on_locally(att_db.read_attribute(SERVICE_CHANGE_CCC_DESCRIPTOR_HANDLE)).unwrap();
// assert: we are registered for indications
- let AttAttributeDataChild::GattClientCharacteristicConfiguration(configuration) = resp
- else {
- unreachable!()
- };
assert_eq!(
- configuration,
+ Ok(resp),
GattClientCharacteristicConfigurationBuilder { notification: 0, indication: 1 }
+ .to_vec()
);
}
@@ -321,11 +309,9 @@ mod test {
block_on_locally(
att_db.write_attribute(
SERVICE_CHANGE_CCC_DESCRIPTOR_HANDLE,
- build_view_or_crash(build_att_data(GattClientCharacteristicConfigurationBuilder {
- notification: 0,
- indication: 1,
- }))
- .view(),
+ &GattClientCharacteristicConfigurationBuilder { notification: 0, indication: 1 }
+ .to_vec()
+ .unwrap(),
),
)
.unwrap();
@@ -333,11 +319,9 @@ mod test {
block_on_locally(
att_db.write_attribute(
SERVICE_CHANGE_CCC_DESCRIPTOR_HANDLE,
- build_view_or_crash(build_att_data(GattClientCharacteristicConfigurationBuilder {
- notification: 0,
- indication: 0,
- }))
- .view(),
+ &GattClientCharacteristicConfigurationBuilder { notification: 0, indication: 0 }
+ .to_vec()
+ .unwrap(),
),
)
.unwrap();
@@ -346,13 +330,10 @@ mod test {
block_on_locally(att_db.read_attribute(SERVICE_CHANGE_CCC_DESCRIPTOR_HANDLE)).unwrap();
// assert: we are not registered for indications
- let AttAttributeDataChild::GattClientCharacteristicConfiguration(configuration) = resp
- else {
- unreachable!()
- };
assert_eq!(
- configuration,
+ Ok(resp),
GattClientCharacteristicConfigurationBuilder { notification: 0, indication: 0 }
+ .to_vec()
);
}
diff --git a/system/rust/src/gatt/server/test/test_att_db.rs b/system/rust/src/gatt/server/test/test_att_db.rs
index 45b82dcfa9..896f31d4f1 100644
--- a/system/rust/src/gatt/server/test/test_att_db.rs
+++ b/system/rust/src/gatt/server/test/test_att_db.rs
@@ -3,7 +3,7 @@ use crate::{
ids::AttHandle,
server::att_database::{AttAttribute, AttDatabase, StableAttDatabase},
},
- packets::{AttAttributeDataChild, AttAttributeDataView, AttErrorCode},
+ packets::AttErrorCode,
};
use async_trait::async_trait;
@@ -38,10 +38,7 @@ impl TestAttDatabase {
#[async_trait(?Send)]
impl AttDatabase for TestAttDatabase {
- async fn read_attribute(
- &self,
- handle: AttHandle,
- ) -> Result<AttAttributeDataChild, AttErrorCode> {
+ async fn read_attribute(&self, handle: AttHandle) -> Result<Vec<u8>, AttErrorCode> {
info!("reading {handle:?}");
match self.attributes.get(&handle) {
Some(TestAttributeWithData { attribute: AttAttribute { permissions, .. }, .. })
@@ -49,17 +46,11 @@ impl AttDatabase for TestAttDatabase {
{
Err(AttErrorCode::READ_NOT_PERMITTED)
}
- Some(TestAttributeWithData { data, .. }) => {
- Ok(AttAttributeDataChild::RawData(data.borrow().clone().into_boxed_slice()))
- }
+ Some(TestAttributeWithData { data, .. }) => Ok(data.borrow().clone()),
None => Err(AttErrorCode::INVALID_HANDLE),
}
}
- async fn write_attribute(
- &self,
- handle: AttHandle,
- data: AttAttributeDataView<'_>,
- ) -> Result<(), AttErrorCode> {
+ async fn write_attribute(&self, handle: AttHandle, data: &[u8]) -> Result<(), AttErrorCode> {
match self.attributes.get(&handle) {
Some(TestAttributeWithData { attribute: AttAttribute { permissions, .. }, .. })
if !permissions.writable_with_response() =>
@@ -67,19 +58,19 @@ impl AttDatabase for TestAttDatabase {
Err(AttErrorCode::WRITE_NOT_PERMITTED)
}
Some(TestAttributeWithData { data: data_cell, .. }) => {
- data_cell.replace(data.get_raw_payload().collect());
+ data_cell.replace(data.to_vec());
Ok(())
}
None => Err(AttErrorCode::INVALID_HANDLE),
}
}
- fn write_no_response_attribute(&self, handle: AttHandle, data: AttAttributeDataView<'_>) {
+ fn write_no_response_attribute(&self, handle: AttHandle, data: &[u8]) {
match self.attributes.get(&handle) {
Some(TestAttributeWithData {
attribute: AttAttribute { permissions, .. },
data: data_cell,
}) if !permissions.writable_with_response() => {
- data_cell.replace(data.get_raw_payload().collect());
+ data_cell.replace(data.to_vec());
}
_ => {
warn!("rejecting write command to {handle:?}")
diff --git a/system/rust/src/gatt/server/transactions/find_by_type_value.rs b/system/rust/src/gatt/server/transactions/find_by_type_value.rs
index b09e7f7ef6..5a7cbb280a 100644
--- a/system/rust/src/gatt/server/transactions/find_by_type_value.rs
+++ b/system/rust/src/gatt/server/transactions/find_by_type_value.rs
@@ -8,7 +8,7 @@ use crate::{
},
packets::{
AttChild, AttErrorCode, AttErrorResponseBuilder, AttFindByTypeValueRequestView,
- AttFindByTypeValueResponseBuilder, AttOpcode, AttributeHandleRangeBuilder, Serializable,
+ AttFindByTypeValueResponseBuilder, AttOpcode, AttributeHandleRangeBuilder,
},
};
@@ -43,18 +43,16 @@ pub async fn handle_find_by_type_value_request(
continue;
}
if let Ok(value) = db.read_attribute(handle).await {
- if let Ok(data) = value.to_vec() {
- if data == request.get_attribute_value().get_raw_payload().collect::<Vec<_>>() {
- // match found
- if !matches.push(AttributeHandleRangeBuilder {
- found_attribute_handle: handle.into(),
- group_end_handle: find_group_end(db, attr)
- .map(|attr| attr.handle)
- .unwrap_or(handle)
- .into(),
- }) {
- break;
- }
+ if value == request.get_attribute_value().get_raw_payload().collect::<Vec<_>>() {
+ // match found
+ if !matches.push(AttributeHandleRangeBuilder {
+ found_attribute_handle: handle.into(),
+ group_end_handle: find_group_end(db, attr)
+ .map(|attr| attr.handle)
+ .unwrap_or(handle)
+ .into(),
+ }) {
+ break;
}
}
} else {
diff --git a/system/rust/src/gatt/server/transactions/helpers.rs b/system/rust/src/gatt/server/transactions/helpers.rs
index b69547dc99..d868794e30 100644
--- a/system/rust/src/gatt/server/transactions/helpers.rs
+++ b/system/rust/src/gatt/server/transactions/helpers.rs
@@ -2,4 +2,3 @@ pub mod att_filter_by_size_type;
pub mod att_grouping;
pub mod att_range_filter;
pub mod payload_accumulator;
-pub mod truncate_att_data;
diff --git a/system/rust/src/gatt/server/transactions/helpers/att_filter_by_size_type.rs b/system/rust/src/gatt/server/transactions/helpers/att_filter_by_size_type.rs
index 684e79bf69..52abe8c5c2 100644
--- a/system/rust/src/gatt/server/transactions/helpers/att_filter_by_size_type.rs
+++ b/system/rust/src/gatt/server/transactions/helpers/att_filter_by_size_type.rs
@@ -4,11 +4,9 @@
use crate::{
core::uuid::Uuid,
gatt::server::att_database::{AttAttribute, StableAttDatabase},
- packets::{AttAttributeDataChild, AttErrorCode, Serializable},
+ packets::{AttAttributeDataChild, AttErrorCode},
};
-use super::truncate_att_data::truncate_att_data;
-
/// An attribute and the value
#[derive(Debug, PartialEq, Eq)]
pub struct AttributeWithValue {
@@ -39,9 +37,9 @@ pub async fn filter_read_attributes_by_size_type(
for attr @ AttAttribute { handle, .. } in target_attrs {
match db.read_attribute(handle).await {
- Ok(value) => {
- let value = truncate_att_data(value, size_limit);
- let value_size = value.size_in_bits().unwrap_or(0);
+ Ok(mut value) => {
+ value.truncate(size_limit);
+ let value_size = value.len();
if let Some(curr_elem_size) = curr_elem_size {
if curr_elem_size != value_size {
// no more attributes of the same size
@@ -51,7 +49,10 @@ pub async fn filter_read_attributes_by_size_type(
curr_elem_size = Some(value_size)
}
- out.push(AttributeWithValue { attr, value });
+ out.push(AttributeWithValue {
+ attr,
+ value: AttAttributeDataChild::RawData(value.into_boxed_slice()),
+ });
}
Err(err) => {
if out.is_empty() {
diff --git a/system/rust/src/gatt/server/transactions/helpers/truncate_att_data.rs b/system/rust/src/gatt/server/transactions/helpers/truncate_att_data.rs
deleted file mode 100644
index b1a2c3b9de..0000000000
--- a/system/rust/src/gatt/server/transactions/helpers/truncate_att_data.rs
+++ /dev/null
@@ -1,56 +0,0 @@
-use crate::packets::AttAttributeDataChild;
-
-pub fn truncate_att_data(data: AttAttributeDataChild, len: usize) -> AttAttributeDataChild {
- // Note: we only truncate RawData, not other children
- // This behavior is non-ideal, but in practice it's OK
- // since anything except for RawData will NEVER exceed an MTU
- // Kept since it makes writing tests way easier
- match data {
- AttAttributeDataChild::RawData(data) => {
- let mut data = Vec::from(data);
- data.truncate(len);
- AttAttributeDataChild::RawData(data.into_boxed_slice())
- }
- _ => data,
- }
-}
-
-#[cfg(test)]
-mod test {
- use super::*;
-
- use crate::packets::{GattServiceDeclarationValueBuilder, Serializable, UuidBuilder};
-
- #[test]
- fn test_unaffected() {
- let data = AttAttributeDataChild::RawData([1, 2, 3].into());
- let mtu = 21;
-
- let truncated = truncate_att_data(data, mtu);
-
- assert_eq!(truncated.to_vec().unwrap(), vec![1, 2, 3]);
- }
-
- #[test]
- fn test_truncated() {
- let data = AttAttributeDataChild::RawData([1, 2, 3].into());
- let mtu = 2;
-
- let truncated = truncate_att_data(data, mtu);
-
- assert_eq!(truncated.to_vec().unwrap(), vec![1, 2]);
- }
-
- #[test]
- fn test_truncated_non_raw() {
- // Verifies that non-Raw data is not truncated
- let data =
- GattServiceDeclarationValueBuilder { uuid: UuidBuilder { data: [1, 2, 3].into() } }
- .into();
- let mtu = 2;
-
- let truncated = truncate_att_data(data, mtu);
-
- assert_eq!(truncated.to_vec().unwrap(), vec![1, 2, 3]);
- }
-}
diff --git a/system/rust/src/gatt/server/transactions/read_request.rs b/system/rust/src/gatt/server/transactions/read_request.rs
index 4cb517764b..fb33074c6d 100644
--- a/system/rust/src/gatt/server/transactions/read_request.rs
+++ b/system/rust/src/gatt/server/transactions/read_request.rs
@@ -1,13 +1,11 @@
use crate::{
gatt::server::att_database::AttDatabase,
packets::{
- AttAttributeDataBuilder, AttChild, AttErrorResponseBuilder, AttOpcode, AttReadRequestView,
- AttReadResponseBuilder,
+ AttAttributeDataBuilder, AttAttributeDataChild, AttChild, AttErrorResponseBuilder,
+ AttOpcode, AttReadRequestView, AttReadResponseBuilder,
},
};
-use super::helpers::truncate_att_data::truncate_att_data;
-
pub async fn handle_read_request<T: AttDatabase>(
request: AttReadRequestView<'_>,
mtu: usize,
@@ -16,11 +14,16 @@ pub async fn handle_read_request<T: AttDatabase>(
let handle = request.get_attribute_handle().into();
match db.read_attribute(handle).await {
- Ok(data) => AttReadResponseBuilder {
+ Ok(mut data) => {
// as per 5.3 3F 3.4.4.4 ATT_READ_RSP, we truncate to MTU - 1
- value: AttAttributeDataBuilder { _child_: truncate_att_data(data, mtu - 1) },
+ data.truncate(mtu - 1);
+ AttReadResponseBuilder {
+ value: AttAttributeDataBuilder {
+ _child_: AttAttributeDataChild::RawData(data.into_boxed_slice()),
+ },
+ }
+ .into()
}
- .into(),
Err(error_code) => AttErrorResponseBuilder {
opcode_in_error: AttOpcode::READ_REQUEST,
handle_in_error: handle.into(),
diff --git a/system/rust/src/gatt/server/transactions/write_request.rs b/system/rust/src/gatt/server/transactions/write_request.rs
index 325b9b7373..23a11d9d56 100644
--- a/system/rust/src/gatt/server/transactions/write_request.rs
+++ b/system/rust/src/gatt/server/transactions/write_request.rs
@@ -10,7 +10,8 @@ pub async fn handle_write_request<T: AttDatabase>(
db: &T,
) -> AttChild {
let handle = request.get_handle().into();
- match db.write_attribute(handle, request.get_value()).await {
+ let value = request.get_value().get_raw_payload().collect::<Vec<_>>();
+ match db.write_attribute(handle, &value).await {
Ok(()) => AttWriteResponseBuilder {}.into(),
Err(error_code) => AttErrorResponseBuilder {
opcode_in_error: AttOpcode::WRITE_REQUEST,
@@ -38,8 +39,8 @@ mod test {
},
},
packets::{
- AttAttributeDataChild, AttChild, AttErrorCode, AttErrorResponseBuilder,
- AttWriteRequestBuilder, AttWriteResponseBuilder,
+ AttAttributeDataBuilder, AttAttributeDataChild, AttChild, AttErrorCode,
+ AttErrorResponseBuilder, AttWriteRequestBuilder, AttWriteResponseBuilder,
},
utils::packet::{build_att_data, build_view_or_crash},
};
@@ -55,12 +56,14 @@ mod test {
},
vec![],
)]);
- let data = AttAttributeDataChild::RawData([1, 2].into());
+ let data = vec![1, 2];
// act: write to the attribute
let att_view = build_view_or_crash(AttWriteRequestBuilder {
handle: AttHandle(1).into(),
- value: build_att_data(data.clone()),
+ value: AttAttributeDataBuilder {
+ _child_: AttAttributeDataChild::RawData(data.clone().into_boxed_slice()),
+ },
});
let resp = block_on(handle_write_request(att_view.view(), &db));
diff --git a/system/rust/src/packets.rs b/system/rust/src/packets.rs
index db0fcf6b20..a14103f1f7 100644
--- a/system/rust/src/packets.rs
+++ b/system/rust/src/packets.rs
@@ -7,3 +7,9 @@
#![feature(mixed_integer_ops)]
include!(concat!(env!("OUT_DIR"), "/_packets.rs"));
+
+impl std::cmp::PartialEq for SerializeError {
+ fn eq(&self, rhs: &Self) -> bool {
+ std::mem::discriminant(self) == std::mem::discriminant(rhs)
+ }
+}
diff --git a/system/rust/tests/gatt_callbacks_test.rs b/system/rust/tests/gatt_callbacks_test.rs
index 9ba62a5946..1a462da113 100644
--- a/system/rust/tests/gatt_callbacks_test.rs
+++ b/system/rust/tests/gatt_callbacks_test.rs
@@ -12,8 +12,7 @@ use bluetooth_core::{
ids::{AttHandle, ConnectionId, ServerId, TransactionId, TransportIndex},
mocks::mock_callbacks::{MockCallbackEvents, MockCallbacks},
},
- packets::{AttAttributeDataChild, AttErrorCode, Packet},
- utils::packet::{build_att_data, build_view_or_crash},
+ packets::AttErrorCode,
};
use tokio::{sync::mpsc::UnboundedReceiver, task::spawn_local, time::Instant};
use utils::start_test;
@@ -73,7 +72,7 @@ fn test_read_characteristic_response() {
start_test(async {
// arrange
let (callback_manager, mut callbacks_rx) = initialize_manager_with_connection();
- let data = Ok(AttAttributeDataChild::RawData([1, 2].into()));
+ let data = [1, 2];
// act: start read operation
let datastore = callback_manager.get_datastore(SERVER_ID);
@@ -83,10 +82,10 @@ fn test_read_characteristic_response() {
);
// provide a response
let trans_id = pull_trans_id(&mut callbacks_rx).await;
- callback_manager.send_response(CONN_ID, trans_id, data.clone()).unwrap();
+ callback_manager.send_response(CONN_ID, trans_id, Ok(data.to_vec())).unwrap();
// assert: that the supplied data was correctly read
- assert_eq!(pending_read.await.unwrap(), data);
+ assert_eq!(pending_read.await.unwrap(), Ok(data.to_vec()));
});
}
@@ -95,8 +94,8 @@ fn test_sequential_reads() {
start_test(async {
// arrange
let (callback_manager, mut callbacks_rx) = initialize_manager_with_connection();
- let data1 = Ok(AttAttributeDataChild::RawData([1, 2].into()));
- let data2 = Ok(AttAttributeDataChild::RawData([3, 4].into()));
+ let data1 = [1, 2];
+ let data2 = [3, 4];
// act: start read operation
let datastore = callback_manager.get_datastore(SERVER_ID);
@@ -106,7 +105,7 @@ fn test_sequential_reads() {
);
// respond to first
let trans_id = pull_trans_id(&mut callbacks_rx).await;
- callback_manager.send_response(CONN_ID, trans_id, data1.clone()).unwrap();
+ callback_manager.send_response(CONN_ID, trans_id, Ok(data1.to_vec())).unwrap();
// do a second read operation
let datastore = callback_manager.get_datastore(SERVER_ID);
@@ -116,11 +115,11 @@ fn test_sequential_reads() {
);
// respond to second
let trans_id = pull_trans_id(&mut callbacks_rx).await;
- callback_manager.send_response(CONN_ID, trans_id, data2.clone()).unwrap();
+ callback_manager.send_response(CONN_ID, trans_id, Ok(data2.to_vec())).unwrap();
// assert: that both operations got the correct response
- assert_eq!(pending_read_1.await.unwrap(), data1);
- assert_eq!(pending_read_2.await.unwrap(), data2);
+ assert_eq!(pending_read_1.await.unwrap(), Ok(data1.to_vec()));
+ assert_eq!(pending_read_2.await.unwrap(), Ok(data2.to_vec()));
});
}
@@ -129,8 +128,8 @@ fn test_concurrent_reads() {
start_test(async {
// arrange
let (callback_manager, mut callbacks_rx) = initialize_manager_with_connection();
- let data1 = Ok(AttAttributeDataChild::RawData([1, 2].into()));
- let data2 = Ok(AttAttributeDataChild::RawData([3, 4].into()));
+ let data1 = [1, 2];
+ let data2 = [3, 4];
// act: start read operation
let datastore = callback_manager.get_datastore(SERVER_ID);
@@ -148,15 +147,15 @@ fn test_concurrent_reads() {
// respond to first
let trans_id = pull_trans_id(&mut callbacks_rx).await;
- callback_manager.send_response(CONN_ID, trans_id, data1.clone()).unwrap();
+ callback_manager.send_response(CONN_ID, trans_id, Ok(data1.to_vec())).unwrap();
// respond to second
let trans_id = pull_trans_id(&mut callbacks_rx).await;
- callback_manager.send_response(CONN_ID, trans_id, data2.clone()).unwrap();
+ callback_manager.send_response(CONN_ID, trans_id, Ok(data2.to_vec())).unwrap();
// assert: that both operations got the correct response
- assert_eq!(pending_read_1.await.unwrap(), data1);
- assert_eq!(pending_read_2.await.unwrap(), data2);
+ assert_eq!(pending_read_1.await.unwrap(), Ok(data1.to_vec()));
+ assert_eq!(pending_read_2.await.unwrap(), Ok(data2.to_vec()));
});
}
@@ -186,7 +185,7 @@ fn test_invalid_trans_id() {
start_test(async {
// arrange
let (callback_manager, mut callbacks_rx) = initialize_manager_with_connection();
- let data = Ok(AttAttributeDataChild::RawData([1, 2].into()));
+ let data = [1, 2];
// act: start a read operation
let datastore = callback_manager.get_datastore(SERVER_ID);
@@ -194,7 +193,9 @@ fn test_invalid_trans_id() {
// respond with the correct conn_id but an invalid trans_id
let trans_id = pull_trans_id(&mut callbacks_rx).await;
let invalid_trans_id = TransactionId(trans_id.0 + 1);
- let err = callback_manager.send_response(CONN_ID, invalid_trans_id, data).unwrap_err();
+ let err = callback_manager
+ .send_response(CONN_ID, invalid_trans_id, Ok(data.to_vec()))
+ .unwrap_err();
// assert
assert_eq!(err, CallbackResponseError::NonExistentTransaction(invalid_trans_id));
@@ -206,7 +207,7 @@ fn test_invalid_conn_id() {
start_test(async {
// arrange
let (callback_manager, mut callbacks_rx) = initialize_manager_with_connection();
- let data = Ok(AttAttributeDataChild::RawData([1, 2].into()));
+ let data = [1, 2];
// act: start a read operation
let datastore = callback_manager.get_datastore(SERVER_ID);
@@ -214,7 +215,9 @@ fn test_invalid_conn_id() {
// respond with the correct trans_id but an invalid conn_id
let trans_id = pull_trans_id(&mut callbacks_rx).await;
let invalid_conn_id = ConnectionId(CONN_ID.0 + 1);
- let err = callback_manager.send_response(invalid_conn_id, trans_id, data).unwrap_err();
+ let err = callback_manager
+ .send_response(invalid_conn_id, trans_id, Ok(data.to_vec()))
+ .unwrap_err();
// assert
assert_eq!(err, CallbackResponseError::NonExistentTransaction(trans_id));
@@ -228,13 +231,11 @@ fn test_write_characteristic_callback() {
let (callback_manager, mut callbacks_rx) = initialize_manager_with_connection();
// act: start write operation
- let data =
- build_view_or_crash(build_att_data(AttAttributeDataChild::RawData([1, 2].into())));
- let cloned_data = data.view().to_owned_packet();
+ let data = [1, 2];
spawn_local(async move {
callback_manager
.get_datastore(SERVER_ID)
- .write(TCB_IDX, HANDLE_1, BACKING_TYPE, WRITE_REQUEST_TYPE, cloned_data.view())
+ .write(TCB_IDX, HANDLE_1, BACKING_TYPE, WRITE_REQUEST_TYPE, &data)
.await
});
@@ -250,10 +251,7 @@ fn test_write_characteristic_callback() {
else {
unreachable!()
};
- assert_eq!(
- recv_data.view().get_raw_payload().collect::<Vec<_>>(),
- data.view().get_raw_payload().collect::<Vec<_>>()
- );
+ assert_eq!(recv_data, data);
});
}
@@ -264,12 +262,11 @@ fn test_write_characteristic_response() {
let (callback_manager, mut callbacks_rx) = initialize_manager_with_connection();
// act: start write operation
- let data =
- build_view_or_crash(build_att_data(AttAttributeDataChild::RawData([1, 2].into())));
+ let data = [1, 2];
let datastore = callback_manager.get_datastore(SERVER_ID);
let pending_write = spawn_local(async move {
datastore
- .write(TCB_IDX, HANDLE_1, BACKING_TYPE, GattWriteRequestType::Request, data.view())
+ .write(TCB_IDX, HANDLE_1, BACKING_TYPE, GattWriteRequestType::Request, &data)
.await
});
// provide a response with some error code
@@ -361,13 +358,12 @@ fn test_write_no_response_callback() {
let (callback_manager, mut callbacks_rx) = initialize_manager_with_connection();
// act: start write_no_response operation
- let data =
- build_view_or_crash(build_att_data(AttAttributeDataChild::RawData([1, 2].into())));
+ let data = [1, 2];
callback_manager.get_datastore(SERVER_ID).write_no_response(
TCB_IDX,
HANDLE_1,
BACKING_TYPE,
- data.view(),
+ &data,
);
// assert: verify the write callback is received
@@ -382,10 +378,7 @@ fn test_write_no_response_callback() {
else {
unreachable!()
};
- assert_eq!(
- recv_data.view().get_raw_payload().collect::<Vec<_>>(),
- data.view().get_raw_payload().collect::<Vec<_>>()
- );
+ assert_eq!(recv_data, data);
});
}
diff --git a/system/rust/tests/gatt_server_test.rs b/system/rust/tests/gatt_server_test.rs
index 8aae62105a..2b31db764c 100644
--- a/system/rust/tests/gatt_server_test.rs
+++ b/system/rust/tests/gatt_server_test.rs
@@ -35,9 +35,9 @@ use bluetooth_core::{
AttFindInformationResponseChild, AttHandleValueConfirmationBuilder,
AttHandleValueIndicationBuilder, AttOpcode, AttReadByTypeRequestBuilder,
AttReadRequestBuilder, AttReadResponseBuilder, AttWriteRequestBuilder,
- AttWriteResponseBuilder, GattClientCharacteristicConfigurationBuilder,
- GattServiceChangedBuilder, GattServiceDeclarationValueBuilder, Serializable,
- UuidAsAttDataBuilder,
+ AttWriteResponseBuilder, GattCharacteristicDeclarationValueView,
+ GattClientCharacteristicConfigurationBuilder, GattServiceChangedBuilder,
+ GattServiceDeclarationValueBuilder, Packet, Serializable, UuidAsAttDataBuilder,
},
utils::packet::{build_att_data, build_att_view_or_crash},
};
@@ -129,7 +129,7 @@ fn test_service_read() {
// assert
assert_eq!(tcb_idx, TCB_IDX);
assert_eq!(
- resp,
+ resp.to_vec(),
AttBuilder {
opcode: AttOpcode::READ_RESPONSE,
_child_: AttReadResponseBuilder {
@@ -139,6 +139,7 @@ fn test_service_read() {
}
.into()
}
+ .to_vec()
);
})
}
@@ -204,7 +205,7 @@ fn test_characteristic_read() {
} else {
unreachable!()
};
- tx.send(Ok(data.clone())).unwrap();
+ tx.send(Ok(DATA.to_vec())).unwrap();
let (tcb_idx, resp) = transport_rx.recv().await.unwrap();
// assert
@@ -261,10 +262,7 @@ fn test_characteristic_write() {
_child_: AttWriteResponseBuilder {}.into()
}
);
- assert_eq!(
- data.to_vec().unwrap(),
- written_data.view().get_raw_payload().collect::<Vec<_>>()
- )
+ assert_eq!(data.to_vec().unwrap(), written_data)
})
}
@@ -372,10 +370,7 @@ fn test_write_to_descriptor() {
_child_: AttWriteResponseBuilder {}.into()
}
);
- assert_eq!(
- data.to_vec().unwrap(),
- written_data.view().get_raw_payload().collect::<Vec<_>>()
- )
+ assert_eq!(data.to_vec().unwrap(), written_data)
})
}
@@ -384,8 +379,6 @@ fn test_multiple_servers() {
start_test(async move {
// arrange
let (mut gatt, mut transport_rx) = start_gatt_module();
- let data = AttAttributeDataChild::RawData(DATA.into());
- let another_data = AttAttributeDataChild::RawData(ANOTHER_DATA.into());
// open the default server (SERVER_ID on CONN_ID)
let mut data_rx_1 = create_server_and_open_connection(&mut gatt);
// open a second server and connect to it (ANOTHER_SERVER_ID on ANOTHER_CONN_ID)
@@ -427,13 +420,13 @@ fn test_multiple_servers() {
let MockDatastoreEvents::Read(TCB_IDX, _, _, tx) = data_rx_1.recv().await.unwrap() else {
unreachable!()
};
- tx.send(Ok(data.clone())).unwrap();
+ tx.send(Ok(DATA.to_vec())).unwrap();
// and then the second read with `another_data`
let MockDatastoreEvents::Read(ANOTHER_TCB_IDX, _, _, tx) = data_rx_2.recv().await.unwrap()
else {
unreachable!()
};
- tx.send(Ok(another_data.clone())).unwrap();
+ tx.send(Ok(ANOTHER_DATA.to_vec())).unwrap();
// receive both response packets
let (tcb_idx_1, resp_1) = transport_rx.recv().await.unwrap();
@@ -540,18 +533,18 @@ fn test_service_change_indication() {
else {
unreachable!()
};
- let service_change_char_handle = resp
+ let service_change_char_handle: AttHandle = resp
.data
.into_vec()
.into_iter()
.find_map(|characteristic| {
- let AttAttributeDataChild::GattCharacteristicDeclarationValue(decl) =
- characteristic.value._child_
- else {
- unreachable!();
- };
- if decl.uuid == SERVICE_CHANGE_UUID.into() {
- Some(decl.handle)
+ let value = characteristic.value.to_vec().unwrap();
+ let decl =
+ GattCharacteristicDeclarationValueView::try_parse_from_buffer(value.as_slice())
+ .unwrap();
+
+ if SERVICE_CHANGE_UUID == decl.get_uuid().try_into().unwrap() {
+ Some(decl.get_handle().into())
} else {
None
}
@@ -560,7 +553,7 @@ fn test_service_change_indication() {
// act: find the CCC descriptor for the service changed characteristic
gatt.get_bearer(TCB_IDX).unwrap().handle_packet(
build_att_view_or_crash(AttFindInformationRequestBuilder {
- starting_handle: service_change_char_handle.clone(),
+ starting_handle: service_change_char_handle.into(),
ending_handle: AttHandle::MAX.into(),
})
.view(),
@@ -619,7 +612,7 @@ fn test_service_change_indication() {
else {
unreachable!()
};
- assert_eq!(indication.handle, service_change_char_handle);
+ assert_eq!(indication.handle, service_change_char_handle.into());
assert_eq!(
indication.value,
build_att_data(GattServiceChangedBuilder {