diff --git a/host/src/att.rs b/host/src/att.rs index 120c1d06..dbf5d4d1 100644 --- a/host/src/att.rs +++ b/host/src/att.rs @@ -768,7 +768,7 @@ impl<'d> AttCmd<'d> { let mut w = WriteCursor::new(dest); match self { Self::Write { handle, data } => { - w.write(ATT_WRITE_REQ)?; + w.write(ATT_WRITE_CMD)?; w.write(*handle)?; w.append(data)?; } diff --git a/host/src/gatt.rs b/host/src/gatt.rs index 7aaeedfc..37bf7b15 100644 --- a/host/src/gatt.rs +++ b/host/src/gatt.rs @@ -422,6 +422,7 @@ impl<'reference> Drop for Response<'reference> { pub(crate) trait Client<'d, E> { /// Perform a gatt request and return the response. fn request(&self, req: AttReq<'_>) -> impl Future, BleHostError>>; + fn command(&self, cmd: AttCmd<'_>) -> impl Future>>; } impl<'reference, T: Controller, const MAX_SERVICES: usize, const L2CAP_MTU: usize> Client<'reference, T::Error> @@ -430,6 +431,33 @@ impl<'reference, T: Controller, const MAX_SERVICES: usize, const L2CAP_MTU: usiz async fn request(&self, req: AttReq<'_>) -> Result, BleHostError> { let data = Att::Client(AttClient::Request(req)); + self.send_att_data(data).await?; + + let (h, pdu) = self.response_channel.receive().await; + + assert_eq!(h, self.connection.handle()); + Ok(Response { + handle: h, + pdu, + connections: &self.stack.host.connections, + }) + } + + async fn command(&self, cmd: AttCmd<'_>) -> Result<(), BleHostError> { + let data = Att::Client(AttClient::Command(cmd)); + + self.send_att_data(data).await?; + + Ok(()) + } +} + +impl<'reference, T: Controller, const MAX_SERVICES: usize, const L2CAP_MTU: usize> + GattClient<'reference, T, MAX_SERVICES, L2CAP_MTU> +{ + async fn send_att_data(&self, data: Att<'_>) -> Result<(), BleHostError> { + // Check the data type without consuming it + let header = L2capHeader { channel: crate::types::l2cap::L2CAP_CID_ATT, length: data.size() as u16, @@ -447,14 +475,7 @@ impl<'reference, T: Controller, const MAX_SERVICES: usize, const L2CAP_MTU: usiz .await?; grant.send(w.finish()).await?; - let (h, pdu) = self.response_channel.receive().await; - - assert_eq!(h, self.connection.handle()); - Ok(Response { - handle: h, - pdu, - connections: &self.stack.host.connections, - }) + Ok(()) } } @@ -706,6 +727,22 @@ impl<'reference, C: Controller, const MAX_SERVICES: usize, const L2CAP_MTU: usiz } } + /// Write without waiting for a response to a characteristic described by a handle. + pub async fn write_characteristic_without_response( + &self, + handle: &Characteristic, + buf: &[u8], + ) -> Result<(), BleHostError> { + let data = att::AttCmd::Write { + handle: handle.handle, + data: buf, + }; + + self.command(data).await?; + + Ok(()) + } + /// Subscribe to indication/notification of a given Characteristic /// /// A listener is returned, which has a `next()` method