Loading system/rust/src/gatt/ffi.rs +2 −2 Original line number Diff line number Diff line Loading @@ -12,7 +12,7 @@ use tokio::task::spawn_local; use crate::{ do_in_rust_thread, packets::{AttAttributeDataChild, AttBuilder, AttErrorCode, Serializable, SerializeError}, packets::{AttBuilder, AttErrorCode, Serializable, SerializeError}, }; use super::{ Loading Loading @@ -438,7 +438,7 @@ fn send_response(_server_id: u8, conn_id: u16, trans_id: u32, status: u8, value: fn send_indication(_server_id: u8, handle: u16, conn_id: u16, value: &[u8]) { let handle = AttHandle(handle); let conn_id = ConnectionId(conn_id); let value = AttAttributeDataChild::RawData(value.into()); let value = value.into(); trace!("send_indication {handle:?}, {conn_id:?}"); Loading system/rust/src/gatt/server/att_server_bearer.rs +26 −78 Original line number Diff line number Diff line Loading @@ -19,8 +19,8 @@ use crate::{ opcode_types::{classify_opcode, OperationType}, }, packets::{ AttAttributeDataChild, AttBuilder, AttChild, AttErrorCode, AttErrorResponseBuilder, AttView, Packet, SerializeError, AttBuilder, AttChild, AttErrorCode, AttErrorResponseBuilder, AttView, Packet, SerializeError, }, utils::{owned_handle::OwnedHandle, packet::HACK_child_to_opcode}, }; Loading Loading @@ -118,7 +118,7 @@ impl<T: AttDatabase + Clone + 'static> WeakBoxRef<'_, AttServerBearer<T>> { pub fn send_indication( &self, handle: AttHandle, data: AttAttributeDataChild, data: Vec<u8>, ) -> impl Future<Output = Result<(), IndicationError>> { trace!("sending indication for handle {handle:?}"); Loading @@ -143,7 +143,7 @@ impl<T: AttDatabase + Clone + 'static> WeakBoxRef<'_, AttServerBearer<T>> { IndicationError::SendError(SendError::ConnectionDropped) })?; // finally, send, and wait for a response indication_handler.send(handle, data, mtu, |packet| this.try_send_packet(packet)).await indication_handler.send(handle, &data, mtu, |packet| this.try_send_packet(packet)).await } } Loading Loading @@ -238,8 +238,8 @@ mod test { }, }, packets::{ AttAttributeDataBuilder, AttAttributeDataChild, AttHandleValueConfirmationBuilder, AttOpcode, AttReadRequestBuilder, AttReadResponseBuilder, AttHandleValueConfirmationBuilder, AttOpcode, AttReadRequestBuilder, AttReadResponseBuilder, }, utils::{ packet::build_att_view_or_crash, Loading Loading @@ -389,14 +389,7 @@ mod test { resp, AttBuilder { opcode: AttOpcode::READ_RESPONSE, _child_: AttReadResponseBuilder { value: AttAttributeDataBuilder { _child_: AttAttributeDataChild::RawData( data.to_vec().into_boxed_slice() ) }, } .into() _child_: AttReadResponseBuilder { value: data.into() }.into() } ); // assert no other replies were made Loading @@ -414,10 +407,7 @@ mod test { // act: send an indication let pending_send = spawn_local(conn.as_ref().send_indication( VALID_HANDLE, AttAttributeDataChild::RawData([1, 2, 3].into()), )); spawn_local(conn.as_ref().send_indication(VALID_HANDLE, vec![1, 2, 3])); assert_eq!(rx.recv().await.unwrap().opcode, AttOpcode::HANDLE_VALUE_INDICATION); assert_eq!(rx.try_recv(), Err(TryRecvError::Empty)); // and the confirmation Loading @@ -438,10 +428,7 @@ mod test { // act: send the first indication let pending_send1 = spawn_local(conn.as_ref().send_indication( VALID_HANDLE, AttAttributeDataChild::RawData([1, 2, 3].into()), )); spawn_local(conn.as_ref().send_indication(VALID_HANDLE, vec![1, 2, 3])); // wait for/capture the outgoing packet let sent1 = rx.recv().await.unwrap(); // send the response Loading @@ -450,10 +437,7 @@ mod test { ); // send the second indication let pending_send2 = spawn_local(conn.as_ref().send_indication( VALID_HANDLE, AttAttributeDataChild::RawData([1, 2, 3].into()), )); spawn_local(conn.as_ref().send_indication(VALID_HANDLE, vec![1, 2, 3])); // wait for/capture the outgoing packet let sent2 = rx.recv().await.unwrap(); // and the response Loading @@ -479,14 +463,9 @@ mod test { // act: send two indications simultaneously let pending_send1 = spawn_local(conn.as_ref().send_indication( VALID_HANDLE, AttAttributeDataChild::RawData([1, 2, 3].into()), )); let pending_send2 = spawn_local(conn.as_ref().send_indication( ANOTHER_VALID_HANDLE, AttAttributeDataChild::RawData([1, 2, 3].into()), )); spawn_local(conn.as_ref().send_indication(VALID_HANDLE, vec![1, 2, 3])); let pending_send2 = spawn_local(conn.as_ref().send_indication(ANOTHER_VALID_HANDLE, vec![1, 2, 3])); // assert: only one was initially sent assert_eq!(rx.recv().await.unwrap().opcode, AttOpcode::HANDLE_VALUE_INDICATION); assert_eq!(rx.try_recv(), Err(TryRecvError::Empty)); Loading @@ -504,14 +483,9 @@ mod test { // act: send two indications simultaneously let pending_send1 = spawn_local(conn.as_ref().send_indication( VALID_HANDLE, AttAttributeDataChild::RawData([1, 2, 3].into()), )); let pending_send2 = spawn_local(conn.as_ref().send_indication( ANOTHER_VALID_HANDLE, AttAttributeDataChild::RawData([1, 2, 3].into()), )); spawn_local(conn.as_ref().send_indication(VALID_HANDLE, vec![1, 2, 3])); let pending_send2 = spawn_local(conn.as_ref().send_indication(ANOTHER_VALID_HANDLE, vec![1, 2, 3])); // wait for/capture the outgoing packet let sent1 = rx.recv().await.unwrap(); // send response for the first one Loading Loading @@ -540,14 +514,9 @@ mod test { // act: send two indications simultaneously let pending_send1 = spawn_local(conn.as_ref().send_indication( VALID_HANDLE, AttAttributeDataChild::RawData([1, 2, 3].into()), )); let pending_send2 = spawn_local(conn.as_ref().send_indication( ANOTHER_VALID_HANDLE, AttAttributeDataChild::RawData([1, 2, 3].into()), )); spawn_local(conn.as_ref().send_indication(VALID_HANDLE, vec![1, 2, 3])); let pending_send2 = spawn_local(conn.as_ref().send_indication(ANOTHER_VALID_HANDLE, vec![1, 2, 3])); // wait for/capture the outgoing packet let sent1 = rx.recv().await.unwrap(); // send response for the first one Loading Loading @@ -577,10 +546,7 @@ mod test { // arrange: a pending indication let (conn, mut rx) = open_connection(); let pending_send = spawn_local(conn.as_ref().send_indication( VALID_HANDLE, AttAttributeDataChild::RawData([1, 2, 3].into()), )); spawn_local(conn.as_ref().send_indication(VALID_HANDLE, vec![1, 2, 3])); // act: drop the connection after the indication is sent rx.recv().await.unwrap(); Loading @@ -602,12 +568,7 @@ mod test { conn.as_ref().handle_mtu_event(MtuEvent::OutgoingRequest).unwrap(); // act: try to send an indication with a large payload size let _ = try_await(conn.as_ref().send_indication( VALID_HANDLE, AttAttributeDataChild::RawData((1..50).collect()), )) .await; let _ = try_await(conn.as_ref().send_indication(VALID_HANDLE, (1..50).collect())).await; // then resolve the MTU negotiation with a large MTU conn.as_ref().handle_mtu_event(MtuEvent::IncomingResponse(100)).unwrap(); Loading @@ -625,10 +586,7 @@ mod test { // act: try to send an indication with a large payload size let pending_mtu = try_await(conn.as_ref().send_indication( VALID_HANDLE, AttAttributeDataChild::RawData((1..50).collect()), )) try_await(conn.as_ref().send_indication(VALID_HANDLE, (1..50).collect())) .await .unwrap_err(); // then resolve the MTU negotiation with a small MTU Loading Loading @@ -664,21 +622,11 @@ mod test { block_on_locally(async { // arrange: an outstanding indication let (conn, mut rx) = open_connection(); let _ = try_await(conn.as_ref().send_indication( VALID_HANDLE, AttAttributeDataChild::RawData([1, 2, 3].into()), )) .await; let _ = try_await(conn.as_ref().send_indication(VALID_HANDLE, vec![1, 2, 3])).await; rx.recv().await.unwrap(); // flush rx_queue // act: enqueue an indication with a large payload let _ = try_await(conn.as_ref().send_indication( VALID_HANDLE, AttAttributeDataChild::RawData((1..50).collect()), )) .await; let _ = try_await(conn.as_ref().send_indication(VALID_HANDLE, (1..50).collect())).await; // then perform MTU negotiation to upgrade to a large MTU conn.as_ref().handle_mtu_event(MtuEvent::OutgoingRequest).unwrap(); conn.as_ref().handle_mtu_event(MtuEvent::IncomingResponse(512)).unwrap(); Loading system/rust/src/gatt/server/command_handler.rs +3 −8 Original line number Diff line number Diff line Loading @@ -24,7 +24,7 @@ impl<Db: AttDatabase> AttCommandHandler<Db> { }; snapshotted_db.write_no_response_attribute( packet.get_handle().into(), &packet.get_value().get_raw_payload().collect::<Vec<_>>(), &packet.get_value_iter().collect::<Vec<_>>(), ); } _ => { Loading @@ -47,10 +47,7 @@ mod test { test::test_att_db::TestAttDatabase, }, }, packets::{ AttAttributeDataBuilder, AttAttributeDataChild, AttErrorCode, AttErrorResponseBuilder, AttOpcode, AttWriteCommandBuilder, }, packets::{AttErrorCode, AttErrorResponseBuilder, AttOpcode, AttWriteCommandBuilder}, utils::{packet::build_att_view_or_crash, task::block_on_locally}, }; Loading @@ -71,9 +68,7 @@ mod test { // act: send write command let att_view = build_att_view_or_crash(AttWriteCommandBuilder { handle: AttHandle(3).into(), value: AttAttributeDataBuilder { _child_: AttAttributeDataChild::RawData(data.to_vec().into_boxed_slice()), }, value: data.into(), }); handler.process_packet(att_view.view()); Loading system/rust/src/gatt/server/gatt_database.rs +31 −38 Original line number Diff line number Diff line Loading @@ -521,7 +521,6 @@ mod test { mock_datastore::{MockDatastore, MockDatastoreEvents}, mock_raw_datastore::{MockRawDatastore, MockRawDatastoreEvents}, }, packets::AttAttributeDataChild, utils::task::block_on_locally, }; Loading Loading @@ -578,9 +577,7 @@ mod test { ); assert_eq!( service_value, AttAttributeDataChild::GattServiceDeclarationValue( GattServiceDeclarationValueBuilder { uuid: SERVICE_TYPE.into() } ) .to_vec() .map_err(|_| AttErrorCode::UNLIKELY_ERROR) ); Loading Loading @@ -717,7 +714,6 @@ mod test { assert_eq!( characteristic_decl, AttAttributeDataChild::GattCharacteristicDeclarationValue( GattCharacteristicDeclarationValueBuilder { properties: GattCharacteristicPropertiesBuilder { read: 1, Loading @@ -732,7 +728,6 @@ mod test { handle: CHARACTERISTIC_VALUE_HANDLE.into(), uuid: CHARACTERISTIC_TYPE.into() } ) .to_vec() .map_err(|_| AttErrorCode::UNLIKELY_ERROR) ); Loading Loading @@ -767,7 +762,6 @@ mod test { tokio_test::block_on(att_db.read_attribute(CHARACTERISTIC_DECLARATION_HANDLE)); assert_eq!( characteristic_decl, AttAttributeDataChild::GattCharacteristicDeclarationValue( GattCharacteristicDeclarationValueBuilder { properties: GattCharacteristicPropertiesBuilder { read: 1, Loading @@ -782,7 +776,6 @@ mod test { handle: CHARACTERISTIC_VALUE_HANDLE.into(), uuid: CHARACTERISTIC_TYPE.into() } ) .to_vec() .map_err(|_| AttErrorCode::UNLIKELY_ERROR) ); Loading system/rust/src/gatt/server/indication_handler.rs +15 −33 Original line number Diff line number Diff line Loading @@ -8,8 +8,7 @@ use tokio::{ use crate::{ gatt::ids::AttHandle, packets::{AttAttributeDataChild, AttChild, AttHandleValueIndicationBuilder, Serializable}, utils::packet::build_att_data, packets::{AttChild, AttHandleValueIndicationBuilder}, }; use super::{ Loading Loading @@ -52,17 +51,14 @@ impl<T: AttDatabase> IndicationHandler<T> { pub async fn send( &mut self, handle: AttHandle, data: AttAttributeDataChild, data: &[u8], mtu: usize, send_packet: impl FnOnce(AttChild) -> Result<(), SendError>, ) -> Result<(), IndicationError> { let data_size = data .size_in_bits() .map_err(SendError::SerializeError) .map_err(IndicationError::SendError)?; let data_size = data.len(); // As per Core Spec 5.3 Vol 3F 3.4.7.2, the indicated value must be at most // ATT_MTU-3 if data_size > (mtu - 3) * 8 { if data_size > (mtu - 3) { return Err(IndicationError::DataExceedsMtu { mtu: mtu - 3 }); } Loading @@ -82,8 +78,7 @@ impl<T: AttDatabase> IndicationHandler<T> { let _ = self.pending_confirmation.try_recv(); send_packet( AttHandleValueIndicationBuilder { handle: handle.into(), value: build_att_data(data) } .into(), AttHandleValueIndicationBuilder { handle: handle.into(), value: data.into() }.into(), ) .map_err(IndicationError::SendError)?; Loading Loading @@ -138,10 +133,7 @@ mod test { const NONEXISTENT_HANDLE: AttHandle = AttHandle(2); const NON_INDICATE_HANDLE: AttHandle = AttHandle(3); const MTU: usize = 32; fn get_data() -> AttAttributeDataChild { AttAttributeDataChild::RawData([1, 2, 3].into()) } const DATA: [u8; 3] = [1, 2, 3]; fn get_att_database() -> TestAttDatabase { TestAttDatabase::new(vec![ Loading Loading @@ -175,7 +167,7 @@ mod test { // act: send an indication spawn_local(async move { indication_handler .send(HANDLE, get_data(), MTU, move |packet| { .send(HANDLE, &DATA, MTU, move |packet| { tx.send(packet).unwrap(); Ok(()) }) Loading @@ -188,10 +180,7 @@ mod test { }; assert_eq!( indication, AttHandleValueIndicationBuilder { handle: HANDLE.into(), value: build_att_data(get_data()), } AttHandleValueIndicationBuilder { handle: HANDLE.into(), value: DATA.into() } ); }); } Loading @@ -205,7 +194,7 @@ mod test { // act: send an indication on a nonexistent handle let ret = indication_handler .send(NONEXISTENT_HANDLE, get_data(), MTU, move |_| unreachable!()) .send(NONEXISTENT_HANDLE, &DATA, MTU, move |_| unreachable!()) .await; // assert: that we failed with IndicationError::AttributeNotFound Loading @@ -222,7 +211,7 @@ mod test { // act: send an indication on an attribute that does not support indications let ret = indication_handler .send(NON_INDICATE_HANDLE, get_data(), MTU, move |_| unreachable!()) .send(NON_INDICATE_HANDLE, &DATA, MTU, move |_| unreachable!()) .await; // assert: that we failed with IndicationError::IndicationsNotSupported Loading @@ -241,7 +230,7 @@ mod test { // act: send an indication let pending_result = spawn_local(async move { indication_handler .send(HANDLE, get_data(), MTU, move |packet| { .send(HANDLE, &DATA, MTU, move |packet| { tx.send(packet).unwrap(); Ok(()) }) Loading @@ -267,7 +256,7 @@ mod test { // act: send an indication let pending_result = spawn_local(async move { indication_handler .send(HANDLE, get_data(), MTU, move |packet| { .send(HANDLE, &DATA, MTU, move |packet| { tx.send(packet).unwrap(); Ok(()) }) Loading Loading @@ -299,7 +288,7 @@ mod test { // act: send an indication let pending_result = spawn_local(async move { indication_handler .send(HANDLE, get_data(), MTU, move |packet| { .send(HANDLE, &DATA, MTU, move |packet| { tx.send(packet).unwrap(); Ok(()) }) Loading Loading @@ -334,7 +323,7 @@ mod test { let time_sent = Instant::now(); let pending_result = spawn_local(async move { indication_handler .send(HANDLE, get_data(), MTU, move |packet| { .send(HANDLE, &DATA, MTU, move |packet| { tx.send(packet).unwrap(); Ok(()) }) Loading Loading @@ -365,14 +354,7 @@ mod test { IndicationHandler::new(get_att_database()); // act: send an indication with an ATT_MTU of 4 and data length of 3 let res = indication_handler .send( HANDLE, AttAttributeDataChild::RawData([1, 2, 3].into()), 4, move |_| unreachable!(), ) .await; let res = indication_handler.send(HANDLE, &[1, 2, 3], 4, move |_| unreachable!()).await; // assert: that we got the expected error, indicating the max data size (not the // ATT_MTU, but ATT_MTU-3) Loading Loading
system/rust/src/gatt/ffi.rs +2 −2 Original line number Diff line number Diff line Loading @@ -12,7 +12,7 @@ use tokio::task::spawn_local; use crate::{ do_in_rust_thread, packets::{AttAttributeDataChild, AttBuilder, AttErrorCode, Serializable, SerializeError}, packets::{AttBuilder, AttErrorCode, Serializable, SerializeError}, }; use super::{ Loading Loading @@ -438,7 +438,7 @@ fn send_response(_server_id: u8, conn_id: u16, trans_id: u32, status: u8, value: fn send_indication(_server_id: u8, handle: u16, conn_id: u16, value: &[u8]) { let handle = AttHandle(handle); let conn_id = ConnectionId(conn_id); let value = AttAttributeDataChild::RawData(value.into()); let value = value.into(); trace!("send_indication {handle:?}, {conn_id:?}"); Loading
system/rust/src/gatt/server/att_server_bearer.rs +26 −78 Original line number Diff line number Diff line Loading @@ -19,8 +19,8 @@ use crate::{ opcode_types::{classify_opcode, OperationType}, }, packets::{ AttAttributeDataChild, AttBuilder, AttChild, AttErrorCode, AttErrorResponseBuilder, AttView, Packet, SerializeError, AttBuilder, AttChild, AttErrorCode, AttErrorResponseBuilder, AttView, Packet, SerializeError, }, utils::{owned_handle::OwnedHandle, packet::HACK_child_to_opcode}, }; Loading Loading @@ -118,7 +118,7 @@ impl<T: AttDatabase + Clone + 'static> WeakBoxRef<'_, AttServerBearer<T>> { pub fn send_indication( &self, handle: AttHandle, data: AttAttributeDataChild, data: Vec<u8>, ) -> impl Future<Output = Result<(), IndicationError>> { trace!("sending indication for handle {handle:?}"); Loading @@ -143,7 +143,7 @@ impl<T: AttDatabase + Clone + 'static> WeakBoxRef<'_, AttServerBearer<T>> { IndicationError::SendError(SendError::ConnectionDropped) })?; // finally, send, and wait for a response indication_handler.send(handle, data, mtu, |packet| this.try_send_packet(packet)).await indication_handler.send(handle, &data, mtu, |packet| this.try_send_packet(packet)).await } } Loading Loading @@ -238,8 +238,8 @@ mod test { }, }, packets::{ AttAttributeDataBuilder, AttAttributeDataChild, AttHandleValueConfirmationBuilder, AttOpcode, AttReadRequestBuilder, AttReadResponseBuilder, AttHandleValueConfirmationBuilder, AttOpcode, AttReadRequestBuilder, AttReadResponseBuilder, }, utils::{ packet::build_att_view_or_crash, Loading Loading @@ -389,14 +389,7 @@ mod test { resp, AttBuilder { opcode: AttOpcode::READ_RESPONSE, _child_: AttReadResponseBuilder { value: AttAttributeDataBuilder { _child_: AttAttributeDataChild::RawData( data.to_vec().into_boxed_slice() ) }, } .into() _child_: AttReadResponseBuilder { value: data.into() }.into() } ); // assert no other replies were made Loading @@ -414,10 +407,7 @@ mod test { // act: send an indication let pending_send = spawn_local(conn.as_ref().send_indication( VALID_HANDLE, AttAttributeDataChild::RawData([1, 2, 3].into()), )); spawn_local(conn.as_ref().send_indication(VALID_HANDLE, vec![1, 2, 3])); assert_eq!(rx.recv().await.unwrap().opcode, AttOpcode::HANDLE_VALUE_INDICATION); assert_eq!(rx.try_recv(), Err(TryRecvError::Empty)); // and the confirmation Loading @@ -438,10 +428,7 @@ mod test { // act: send the first indication let pending_send1 = spawn_local(conn.as_ref().send_indication( VALID_HANDLE, AttAttributeDataChild::RawData([1, 2, 3].into()), )); spawn_local(conn.as_ref().send_indication(VALID_HANDLE, vec![1, 2, 3])); // wait for/capture the outgoing packet let sent1 = rx.recv().await.unwrap(); // send the response Loading @@ -450,10 +437,7 @@ mod test { ); // send the second indication let pending_send2 = spawn_local(conn.as_ref().send_indication( VALID_HANDLE, AttAttributeDataChild::RawData([1, 2, 3].into()), )); spawn_local(conn.as_ref().send_indication(VALID_HANDLE, vec![1, 2, 3])); // wait for/capture the outgoing packet let sent2 = rx.recv().await.unwrap(); // and the response Loading @@ -479,14 +463,9 @@ mod test { // act: send two indications simultaneously let pending_send1 = spawn_local(conn.as_ref().send_indication( VALID_HANDLE, AttAttributeDataChild::RawData([1, 2, 3].into()), )); let pending_send2 = spawn_local(conn.as_ref().send_indication( ANOTHER_VALID_HANDLE, AttAttributeDataChild::RawData([1, 2, 3].into()), )); spawn_local(conn.as_ref().send_indication(VALID_HANDLE, vec![1, 2, 3])); let pending_send2 = spawn_local(conn.as_ref().send_indication(ANOTHER_VALID_HANDLE, vec![1, 2, 3])); // assert: only one was initially sent assert_eq!(rx.recv().await.unwrap().opcode, AttOpcode::HANDLE_VALUE_INDICATION); assert_eq!(rx.try_recv(), Err(TryRecvError::Empty)); Loading @@ -504,14 +483,9 @@ mod test { // act: send two indications simultaneously let pending_send1 = spawn_local(conn.as_ref().send_indication( VALID_HANDLE, AttAttributeDataChild::RawData([1, 2, 3].into()), )); let pending_send2 = spawn_local(conn.as_ref().send_indication( ANOTHER_VALID_HANDLE, AttAttributeDataChild::RawData([1, 2, 3].into()), )); spawn_local(conn.as_ref().send_indication(VALID_HANDLE, vec![1, 2, 3])); let pending_send2 = spawn_local(conn.as_ref().send_indication(ANOTHER_VALID_HANDLE, vec![1, 2, 3])); // wait for/capture the outgoing packet let sent1 = rx.recv().await.unwrap(); // send response for the first one Loading Loading @@ -540,14 +514,9 @@ mod test { // act: send two indications simultaneously let pending_send1 = spawn_local(conn.as_ref().send_indication( VALID_HANDLE, AttAttributeDataChild::RawData([1, 2, 3].into()), )); let pending_send2 = spawn_local(conn.as_ref().send_indication( ANOTHER_VALID_HANDLE, AttAttributeDataChild::RawData([1, 2, 3].into()), )); spawn_local(conn.as_ref().send_indication(VALID_HANDLE, vec![1, 2, 3])); let pending_send2 = spawn_local(conn.as_ref().send_indication(ANOTHER_VALID_HANDLE, vec![1, 2, 3])); // wait for/capture the outgoing packet let sent1 = rx.recv().await.unwrap(); // send response for the first one Loading Loading @@ -577,10 +546,7 @@ mod test { // arrange: a pending indication let (conn, mut rx) = open_connection(); let pending_send = spawn_local(conn.as_ref().send_indication( VALID_HANDLE, AttAttributeDataChild::RawData([1, 2, 3].into()), )); spawn_local(conn.as_ref().send_indication(VALID_HANDLE, vec![1, 2, 3])); // act: drop the connection after the indication is sent rx.recv().await.unwrap(); Loading @@ -602,12 +568,7 @@ mod test { conn.as_ref().handle_mtu_event(MtuEvent::OutgoingRequest).unwrap(); // act: try to send an indication with a large payload size let _ = try_await(conn.as_ref().send_indication( VALID_HANDLE, AttAttributeDataChild::RawData((1..50).collect()), )) .await; let _ = try_await(conn.as_ref().send_indication(VALID_HANDLE, (1..50).collect())).await; // then resolve the MTU negotiation with a large MTU conn.as_ref().handle_mtu_event(MtuEvent::IncomingResponse(100)).unwrap(); Loading @@ -625,10 +586,7 @@ mod test { // act: try to send an indication with a large payload size let pending_mtu = try_await(conn.as_ref().send_indication( VALID_HANDLE, AttAttributeDataChild::RawData((1..50).collect()), )) try_await(conn.as_ref().send_indication(VALID_HANDLE, (1..50).collect())) .await .unwrap_err(); // then resolve the MTU negotiation with a small MTU Loading Loading @@ -664,21 +622,11 @@ mod test { block_on_locally(async { // arrange: an outstanding indication let (conn, mut rx) = open_connection(); let _ = try_await(conn.as_ref().send_indication( VALID_HANDLE, AttAttributeDataChild::RawData([1, 2, 3].into()), )) .await; let _ = try_await(conn.as_ref().send_indication(VALID_HANDLE, vec![1, 2, 3])).await; rx.recv().await.unwrap(); // flush rx_queue // act: enqueue an indication with a large payload let _ = try_await(conn.as_ref().send_indication( VALID_HANDLE, AttAttributeDataChild::RawData((1..50).collect()), )) .await; let _ = try_await(conn.as_ref().send_indication(VALID_HANDLE, (1..50).collect())).await; // then perform MTU negotiation to upgrade to a large MTU conn.as_ref().handle_mtu_event(MtuEvent::OutgoingRequest).unwrap(); conn.as_ref().handle_mtu_event(MtuEvent::IncomingResponse(512)).unwrap(); Loading
system/rust/src/gatt/server/command_handler.rs +3 −8 Original line number Diff line number Diff line Loading @@ -24,7 +24,7 @@ impl<Db: AttDatabase> AttCommandHandler<Db> { }; snapshotted_db.write_no_response_attribute( packet.get_handle().into(), &packet.get_value().get_raw_payload().collect::<Vec<_>>(), &packet.get_value_iter().collect::<Vec<_>>(), ); } _ => { Loading @@ -47,10 +47,7 @@ mod test { test::test_att_db::TestAttDatabase, }, }, packets::{ AttAttributeDataBuilder, AttAttributeDataChild, AttErrorCode, AttErrorResponseBuilder, AttOpcode, AttWriteCommandBuilder, }, packets::{AttErrorCode, AttErrorResponseBuilder, AttOpcode, AttWriteCommandBuilder}, utils::{packet::build_att_view_or_crash, task::block_on_locally}, }; Loading @@ -71,9 +68,7 @@ mod test { // act: send write command let att_view = build_att_view_or_crash(AttWriteCommandBuilder { handle: AttHandle(3).into(), value: AttAttributeDataBuilder { _child_: AttAttributeDataChild::RawData(data.to_vec().into_boxed_slice()), }, value: data.into(), }); handler.process_packet(att_view.view()); Loading
system/rust/src/gatt/server/gatt_database.rs +31 −38 Original line number Diff line number Diff line Loading @@ -521,7 +521,6 @@ mod test { mock_datastore::{MockDatastore, MockDatastoreEvents}, mock_raw_datastore::{MockRawDatastore, MockRawDatastoreEvents}, }, packets::AttAttributeDataChild, utils::task::block_on_locally, }; Loading Loading @@ -578,9 +577,7 @@ mod test { ); assert_eq!( service_value, AttAttributeDataChild::GattServiceDeclarationValue( GattServiceDeclarationValueBuilder { uuid: SERVICE_TYPE.into() } ) .to_vec() .map_err(|_| AttErrorCode::UNLIKELY_ERROR) ); Loading Loading @@ -717,7 +714,6 @@ mod test { assert_eq!( characteristic_decl, AttAttributeDataChild::GattCharacteristicDeclarationValue( GattCharacteristicDeclarationValueBuilder { properties: GattCharacteristicPropertiesBuilder { read: 1, Loading @@ -732,7 +728,6 @@ mod test { handle: CHARACTERISTIC_VALUE_HANDLE.into(), uuid: CHARACTERISTIC_TYPE.into() } ) .to_vec() .map_err(|_| AttErrorCode::UNLIKELY_ERROR) ); Loading Loading @@ -767,7 +762,6 @@ mod test { tokio_test::block_on(att_db.read_attribute(CHARACTERISTIC_DECLARATION_HANDLE)); assert_eq!( characteristic_decl, AttAttributeDataChild::GattCharacteristicDeclarationValue( GattCharacteristicDeclarationValueBuilder { properties: GattCharacteristicPropertiesBuilder { read: 1, Loading @@ -782,7 +776,6 @@ mod test { handle: CHARACTERISTIC_VALUE_HANDLE.into(), uuid: CHARACTERISTIC_TYPE.into() } ) .to_vec() .map_err(|_| AttErrorCode::UNLIKELY_ERROR) ); Loading
system/rust/src/gatt/server/indication_handler.rs +15 −33 Original line number Diff line number Diff line Loading @@ -8,8 +8,7 @@ use tokio::{ use crate::{ gatt::ids::AttHandle, packets::{AttAttributeDataChild, AttChild, AttHandleValueIndicationBuilder, Serializable}, utils::packet::build_att_data, packets::{AttChild, AttHandleValueIndicationBuilder}, }; use super::{ Loading Loading @@ -52,17 +51,14 @@ impl<T: AttDatabase> IndicationHandler<T> { pub async fn send( &mut self, handle: AttHandle, data: AttAttributeDataChild, data: &[u8], mtu: usize, send_packet: impl FnOnce(AttChild) -> Result<(), SendError>, ) -> Result<(), IndicationError> { let data_size = data .size_in_bits() .map_err(SendError::SerializeError) .map_err(IndicationError::SendError)?; let data_size = data.len(); // As per Core Spec 5.3 Vol 3F 3.4.7.2, the indicated value must be at most // ATT_MTU-3 if data_size > (mtu - 3) * 8 { if data_size > (mtu - 3) { return Err(IndicationError::DataExceedsMtu { mtu: mtu - 3 }); } Loading @@ -82,8 +78,7 @@ impl<T: AttDatabase> IndicationHandler<T> { let _ = self.pending_confirmation.try_recv(); send_packet( AttHandleValueIndicationBuilder { handle: handle.into(), value: build_att_data(data) } .into(), AttHandleValueIndicationBuilder { handle: handle.into(), value: data.into() }.into(), ) .map_err(IndicationError::SendError)?; Loading Loading @@ -138,10 +133,7 @@ mod test { const NONEXISTENT_HANDLE: AttHandle = AttHandle(2); const NON_INDICATE_HANDLE: AttHandle = AttHandle(3); const MTU: usize = 32; fn get_data() -> AttAttributeDataChild { AttAttributeDataChild::RawData([1, 2, 3].into()) } const DATA: [u8; 3] = [1, 2, 3]; fn get_att_database() -> TestAttDatabase { TestAttDatabase::new(vec![ Loading Loading @@ -175,7 +167,7 @@ mod test { // act: send an indication spawn_local(async move { indication_handler .send(HANDLE, get_data(), MTU, move |packet| { .send(HANDLE, &DATA, MTU, move |packet| { tx.send(packet).unwrap(); Ok(()) }) Loading @@ -188,10 +180,7 @@ mod test { }; assert_eq!( indication, AttHandleValueIndicationBuilder { handle: HANDLE.into(), value: build_att_data(get_data()), } AttHandleValueIndicationBuilder { handle: HANDLE.into(), value: DATA.into() } ); }); } Loading @@ -205,7 +194,7 @@ mod test { // act: send an indication on a nonexistent handle let ret = indication_handler .send(NONEXISTENT_HANDLE, get_data(), MTU, move |_| unreachable!()) .send(NONEXISTENT_HANDLE, &DATA, MTU, move |_| unreachable!()) .await; // assert: that we failed with IndicationError::AttributeNotFound Loading @@ -222,7 +211,7 @@ mod test { // act: send an indication on an attribute that does not support indications let ret = indication_handler .send(NON_INDICATE_HANDLE, get_data(), MTU, move |_| unreachable!()) .send(NON_INDICATE_HANDLE, &DATA, MTU, move |_| unreachable!()) .await; // assert: that we failed with IndicationError::IndicationsNotSupported Loading @@ -241,7 +230,7 @@ mod test { // act: send an indication let pending_result = spawn_local(async move { indication_handler .send(HANDLE, get_data(), MTU, move |packet| { .send(HANDLE, &DATA, MTU, move |packet| { tx.send(packet).unwrap(); Ok(()) }) Loading @@ -267,7 +256,7 @@ mod test { // act: send an indication let pending_result = spawn_local(async move { indication_handler .send(HANDLE, get_data(), MTU, move |packet| { .send(HANDLE, &DATA, MTU, move |packet| { tx.send(packet).unwrap(); Ok(()) }) Loading Loading @@ -299,7 +288,7 @@ mod test { // act: send an indication let pending_result = spawn_local(async move { indication_handler .send(HANDLE, get_data(), MTU, move |packet| { .send(HANDLE, &DATA, MTU, move |packet| { tx.send(packet).unwrap(); Ok(()) }) Loading Loading @@ -334,7 +323,7 @@ mod test { let time_sent = Instant::now(); let pending_result = spawn_local(async move { indication_handler .send(HANDLE, get_data(), MTU, move |packet| { .send(HANDLE, &DATA, MTU, move |packet| { tx.send(packet).unwrap(); Ok(()) }) Loading Loading @@ -365,14 +354,7 @@ mod test { IndicationHandler::new(get_att_database()); // act: send an indication with an ATT_MTU of 4 and data length of 3 let res = indication_handler .send( HANDLE, AttAttributeDataChild::RawData([1, 2, 3].into()), 4, move |_| unreachable!(), ) .await; let res = indication_handler.send(HANDLE, &[1, 2, 3], 4, move |_| unreachable!()).await; // assert: that we got the expected error, indicating the max data size (not the // ATT_MTU, but ATT_MTU-3) Loading