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

Commit 0d0ce859 authored by Henri Chataing's avatar Henri Chataing
Browse files

system/rust: Update GATT packet definition to use 8[] for ATT values

Bug: 331817295
Test: m com.android.btservices
Test: atest --host libbluetooth_core_rs_test
Flag: EXEMPT, mechanical refactor
Change-Id: Ia8b5fbf470df7ed3d20fced5339beb136e3aa9ba
parent 5978a926
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -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::{
@@ -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:?}");

+26 −78
Original line number Diff line number Diff line
@@ -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},
};
@@ -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:?}");

@@ -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
        }
    }

@@ -238,8 +238,8 @@ mod test {
            },
        },
        packets::{
            AttAttributeDataBuilder, AttAttributeDataChild, AttHandleValueConfirmationBuilder,
            AttOpcode, AttReadRequestBuilder, AttReadResponseBuilder,
            AttHandleValueConfirmationBuilder, AttOpcode, AttReadRequestBuilder,
            AttReadResponseBuilder,
        },
        utils::{
            packet::build_att_view_or_crash,
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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));
@@ -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
@@ -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
@@ -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();
@@ -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();

@@ -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
@@ -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();
+3 −8
Original line number Diff line number Diff line
@@ -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<_>>(),
                );
            }
            _ => {
@@ -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},
    };

@@ -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());

+31 −38
Original line number Diff line number Diff line
@@ -521,7 +521,6 @@ mod test {
            mock_datastore::{MockDatastore, MockDatastoreEvents},
            mock_raw_datastore::{MockRawDatastore, MockRawDatastoreEvents},
        },
        packets::AttAttributeDataChild,
        utils::task::block_on_locally,
    };

@@ -578,9 +577,7 @@ mod test {
        );
        assert_eq!(
            service_value,
            AttAttributeDataChild::GattServiceDeclarationValue(
            GattServiceDeclarationValueBuilder { uuid: SERVICE_TYPE.into() }
            )
                .to_vec()
                .map_err(|_| AttErrorCode::UNLIKELY_ERROR)
        );
@@ -717,7 +714,6 @@ mod test {

        assert_eq!(
            characteristic_decl,
            AttAttributeDataChild::GattCharacteristicDeclarationValue(
            GattCharacteristicDeclarationValueBuilder {
                properties: GattCharacteristicPropertiesBuilder {
                    read: 1,
@@ -732,7 +728,6 @@ mod test {
                handle: CHARACTERISTIC_VALUE_HANDLE.into(),
                uuid: CHARACTERISTIC_TYPE.into()
            }
            )
            .to_vec()
            .map_err(|_| AttErrorCode::UNLIKELY_ERROR)
        );
@@ -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,
@@ -782,7 +776,6 @@ mod test {
                handle: CHARACTERISTIC_VALUE_HANDLE.into(),
                uuid: CHARACTERISTIC_TYPE.into()
            }
            )
            .to_vec()
            .map_err(|_| AttErrorCode::UNLIKELY_ERROR)
        );
+15 −33
Original line number Diff line number Diff line
@@ -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::{
@@ -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 });
        }

@@ -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)?;

@@ -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![
@@ -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(())
                    })
@@ -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() }
            );
        });
    }
@@ -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
@@ -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
@@ -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(())
                    })
@@ -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(())
                    })
@@ -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(())
                    })
@@ -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(())
                    })
@@ -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