blob: 58e770ba4073d616c7d290e9a32054a009a3d346 [file]
// Copyright 2026 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use bt_common::PeerId;
use bt_gatt::GattTypes;
use std::collections::HashMap;
use crate::client::BapUnicastClient;
use crate::types::{Error, SupportedCapabilities};
/// Manages multiple BAP Unicast peers.
pub struct BapUnicastManager<T: GattTypes> {
peers: HashMap<PeerId, BapUnicastClient<T>>,
}
impl<T: GattTypes> BapUnicastManager<T> {
pub fn new() -> Self {
Self { peers: HashMap::new() }
}
/// Add a peer to the manager.
/// Triggers the connection and discovery of PACS and ASCS on the remote
/// peer.
pub async fn add_peer(
&mut self,
peer_id: PeerId,
gatt_client: T::Client,
) -> Result<SupportedCapabilities, Error> {
if self.peers.contains_key(&peer_id) {
return Err(Error::PeerAlreadyExists(peer_id));
}
let mut client = BapUnicastClient::new(peer_id, gatt_client);
let mapping = client.discover().await?;
self.peers.insert(peer_id, client);
Ok(mapping)
}
/// Remove a peer from the manager.
pub fn remove_peer(&mut self, peer_id: PeerId) -> Result<(), Error> {
if self.peers.remove(&peer_id).is_none() {
return Err(Error::PeerNotFound(peer_id));
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::Configuration;
use bt_common::PeerId;
use bt_gatt::test_utils::{FakeClient, FakeTypes};
#[test]
fn test_add_remove_peer() {
let mut manager = BapUnicastManager::<FakeTypes>::new();
let peer_id = PeerId(1);
let client = FakeClient::new();
let mapping =
futures::executor::block_on(manager.add_peer(peer_id, client.clone())).unwrap();
assert!(mapping.contains_key(&Configuration::MonoAudioSink));
assert!(mapping.contains_key(&Configuration::Conversational));
assert!(futures::executor::block_on(manager.add_peer(peer_id, client.clone())).is_err()); // Duplicate
assert!(manager.remove_peer(peer_id).is_ok());
assert!(manager.remove_peer(peer_id).is_err()); // Not found
}
}