Skip to content

Commit 80e7056

Browse files
HaoboGululf
authored andcommitted
feat(gatt): support multiple gatt client
Signed-off-by: Haobo Gu <[email protected]>
1 parent 6a82e70 commit 80e7056

File tree

4 files changed

+31
-11
lines changed

4 files changed

+31
-11
lines changed

host/src/connection.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,11 @@ impl<'stack, P: PacketPool> Connection<'stack, P> {
271271
self.manager.next_gatt(self.index).await
272272
}
273273

274+
#[cfg(feature = "gatt")]
275+
pub(crate) async fn next_gatt_client(&self) -> Pdu<P::Packet> {
276+
self.manager.next_gatt_client(self.index).await
277+
}
278+
274279
/// Check if still connected
275280
pub fn is_connected(&self) -> bool {
276281
self.manager.is_connected(self.index)

host/src/connection_manager.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,24 @@ impl<'d, P: PacketPool> ConnectionManager<'d, P> {
133133
})
134134
}
135135

136+
#[cfg(feature = "gatt")]
137+
pub(crate) fn post_gatt_client(&self, handle: ConnHandle, pdu: Pdu<P::Packet>) -> Result<(), Error> {
138+
self.with_mut(|state| {
139+
for entry in state.connections.iter() {
140+
if entry.state == ConnectionState::Connected && Some(handle) == entry.handle {
141+
entry.gatt_client.try_send(pdu).map_err(|_| Error::OutOfMemory)?;
142+
return Ok(());
143+
}
144+
}
145+
Err(Error::NotFound)
146+
})
147+
}
148+
149+
#[cfg(feature = "gatt")]
150+
pub(crate) async fn next_gatt_client(&self, index: u8) -> Pdu<P::Packet> {
151+
poll_fn(|cx| self.with_mut(|state| state.connections[index as usize].gatt_client.poll_receive(cx))).await
152+
}
153+
136154
pub(crate) fn peer_address(&self, index: u8) -> BdAddr {
137155
self.with_mut(|state| {
138156
let state = &mut state.connections[index as usize];
@@ -791,6 +809,8 @@ pub struct ConnectionStorage<P> {
791809
pub reassembly: PacketReassembly<P>,
792810
#[cfg(feature = "gatt")]
793811
pub gatt: GattChannel<P>,
812+
#[cfg(feature = "gatt")]
813+
pub(crate) gatt_client: GattChannel<P>,
794814
}
795815

796816
/// Connection metrics
@@ -874,6 +894,8 @@ impl<P> ConnectionStorage<P> {
874894
events: EventChannel::new(),
875895
#[cfg(feature = "gatt")]
876896
gatt: GattChannel::new(),
897+
#[cfg(feature = "gatt")]
898+
gatt_client: GattChannel::new(),
877899
reassembly: PacketReassembly::new(),
878900
#[cfg(feature = "security")]
879901
bondable: false,

host/src/gatt.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use bt_hci::uuid::declarations::{CHARACTERISTIC, PRIMARY_SERVICE};
99
use bt_hci::uuid::descriptors::CLIENT_CHARACTERISTIC_CONFIGURATION;
1010
use embassy_futures::select::{select, Either};
1111
use embassy_sync::blocking_mutex::raw::{NoopRawMutex, RawMutex};
12-
use embassy_sync::channel::{Channel, DynamicReceiver};
12+
use embassy_sync::channel::Channel;
1313
use embassy_sync::pubsub::{self, PubSubChannel, WaitResult};
1414
use embassy_time::Duration;
1515
use heapless::Vec;
@@ -650,7 +650,6 @@ const NOTIF_QSIZE: usize = config::GATT_CLIENT_NOTIFICATION_QUEUE_SIZE;
650650
/// A GATT client capable of using the GATT protocol.
651651
pub struct GattClient<'reference, T: Controller, P: PacketPool, const MAX_SERVICES: usize> {
652652
known_services: RefCell<Vec<ServiceHandle, MAX_SERVICES>>,
653-
rx: DynamicReceiver<'reference, (ConnHandle, Pdu<P::Packet>)>,
654653
stack: &'reference Stack<'reference, T, P>,
655654
connection: Connection<'reference, P>,
656655
response_channel: Channel<NoopRawMutex, (ConnHandle, Pdu<P::Packet>), 1>,
@@ -754,7 +753,6 @@ impl<'reference, C: Controller, P: PacketPool, const MAX_SERVICES: usize> GattCl
754753
connection.send(Pdu::new(buf, len)).await;
755754
Ok(Self {
756755
known_services: RefCell::new(heapless::Vec::new()),
757-
rx: stack.host.att_client.receiver().into(),
758756
stack,
759757
connection: connection.clone(),
760758

@@ -1173,7 +1171,8 @@ impl<'reference, C: Controller, P: PacketPool, const MAX_SERVICES: usize> GattCl
11731171
/// Task which handles GATT rx data (needed for notifications to work)
11741172
pub async fn task(&self) -> Result<(), BleHostError<C::Error>> {
11751173
loop {
1176-
let (handle, pdu) = self.rx.receive().await;
1174+
let handle = self.connection.handle();
1175+
let pdu = self.connection.next_gatt_client().await;
11771176
let data = pdu.as_ref();
11781177
// handle notifications
11791178
if pdu.as_ref()[0] == ATT_HANDLE_VALUE_NTF {

host/src/host.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@ use bt_hci::{ControllerToHostPacket, FromHciBytes, WriteHci};
3737
use embassy_futures::select::{select3, select4, Either3, Either4};
3838
use embassy_sync::once_lock::OnceLock;
3939
use embassy_sync::waitqueue::WakerRegistration;
40-
#[cfg(feature = "gatt")]
41-
use embassy_sync::{blocking_mutex::raw::NoopRawMutex, channel::Channel};
4240
use embassy_time::Duration;
4341
use futures::pin_mut;
4442

@@ -71,8 +69,6 @@ pub(crate) struct BleHost<'d, T, P: PacketPool> {
7169
pub(crate) controller: T,
7270
pub(crate) connections: ConnectionManager<'d, P>,
7371
pub(crate) channels: ChannelManager<'d, P>,
74-
#[cfg(feature = "gatt")]
75-
pub(crate) att_client: Channel<NoopRawMutex, (ConnHandle, Pdu<P::Packet>), { crate::config::L2CAP_RX_QUEUE_SIZE }>,
7672
pub(crate) advertise_state: AdvState<'d>,
7773
pub(crate) advertise_command_state: CommandState<bool>,
7874
pub(crate) connect_command_state: CommandState<bool>,
@@ -211,8 +207,6 @@ where
211207
controller,
212208
connections: ConnectionManager::new(connections, P::MTU as u16 - 4),
213209
channels: ChannelManager::new(channels),
214-
#[cfg(feature = "gatt")]
215-
att_client: Channel::new(),
216210
advertise_state: AdvState::new(advertise_handles),
217211
advertise_command_state: CommandState::new(),
218212
scan_command_state: CommandState::new(),
@@ -470,7 +464,7 @@ where
470464
self.connections.post_gatt(acl.handle(), pdu)?;
471465
}
472466
Ok(att::Att::Server(_)) => {
473-
if let Err(e) = self.att_client.try_send((acl.handle(), pdu)) {
467+
if let Err(e) = self.connections.post_gatt_client(acl.handle(), pdu) {
474468
return Err(Error::OutOfMemory);
475469
}
476470
}

0 commit comments

Comments
 (0)