blob: 1df6bd5b85befe067747d9b9bf636469ae3f104b [file] [log] [blame]
// Copyright 2023 Google LLC
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use crate::{central::ScanResult, client::CharacteristicNotification, types::*};
use bt_common::{PeerId, Uuid};
use futures::{future::Ready, stream::Empty, Future, Stream};
use std::task::Poll;
#[derive(Default)]
pub(crate) struct FakeCentral {}
pub(crate) struct FakePeerService {}
impl crate::client::PeerService for FakePeerService {
type CharacteristicsFut = Ready<Result<Vec<Characteristic>>>;
type NotificationStream = Empty<Result<CharacteristicNotification>>;
type ReadFut<'a> = Ready<Result<(usize, bool)>>;
type WriteFut<'a> = Ready<Result<()>>;
fn discover_characteristics(&self, _uuid: Option<Uuid>) -> Self::CharacteristicsFut {
todo!()
}
fn read_characteristic<'a>(
&self,
_handle: &Handle,
_offset: u16,
_buf: &'a mut [u8],
) -> Self::ReadFut<'a> {
todo!()
}
fn write_characteristic<'a>(
&self,
_handle: &Handle,
_mode: WriteMode,
_offset: u16,
_buf: &'a [u8],
) -> Self::WriteFut<'a> {
todo!()
}
fn read_descriptor<'a>(
&self,
_handle: &Handle,
_offset: u16,
_buf: &'a mut [u8],
) -> Self::ReadFut<'a> {
todo!()
}
fn write_descriptor<'a>(
&self,
_handle: &Handle,
_offset: u16,
_buf: &'a [u8],
) -> Self::WriteFut<'a> {
todo!()
}
fn subscribe(&self, _handle: &Handle) -> Self::NotificationStream {
todo!()
}
}
pub(crate) struct FakeServiceHandle {}
impl crate::client::PeerServiceHandle for FakeServiceHandle {
type PeerServiceT = FakePeerService;
type ConnectFut = Ready<Result<Self::PeerServiceT>>;
fn uuid(&self) -> Uuid {
todo!()
}
fn is_primary(&self) -> bool {
todo!()
}
fn connect(&self) -> Self::ConnectFut {
todo!()
}
}
pub(crate) struct FakeClient {}
impl crate::Client for FakeClient {
type PeerServiceHandleT = FakeServiceHandle;
type ServiceResultFut = Ready<Result<Vec<Self::PeerServiceHandleT>>>;
fn peer_id(&self) -> PeerId {
todo!()
}
fn find_service(&self, _uuid: Uuid) -> Self::ServiceResultFut {
todo!()
}
}
pub(crate) struct SingleResultStream {
result: Option<Result<crate::central::ScanResult>>,
}
impl Stream for SingleResultStream {
type Item = Result<crate::central::ScanResult>;
fn poll_next(
self: std::pin::Pin<&mut Self>,
_cx: &mut std::task::Context<'_>,
) -> Poll<Option<Self::Item>> {
if self.result.is_some() {
Poll::Ready(self.get_mut().result.take())
} else {
// Never wake up, as if we never find another result
Poll::Pending
}
}
}
pub(crate) struct ClientConnectFut {}
impl Future for ClientConnectFut {
type Output = Result<FakeClient>;
fn poll(
self: std::pin::Pin<&mut Self>,
_cx: &mut std::task::Context<'_>,
) -> Poll<Self::Output> {
todo!()
}
}
impl crate::Central for FakeCentral {
type ScanResultStream = SingleResultStream;
type Client = FakeClient;
type ClientFut = ClientConnectFut;
fn scan(&self, _filters: &[crate::central::ScanFilter]) -> Self::ScanResultStream {
SingleResultStream {
result: Some(Ok(ScanResult {
id: PeerId(1),
connectable: true,
name: crate::central::PeerName::CompleteName("Marie's Pixel 7 Pro".to_owned()),
advertised: vec![crate::central::AdvertisingDatum::Services(vec![
Uuid::from_u16(0x1844),
])],
})),
}
}
fn connect(&self, _peer_id: PeerId) -> Self::ClientFut {
todo!()
}
}
#[test]
fn central_search_works() {
use crate::Central;
use futures::StreamExt;
let mut noop_cx = futures::task::Context::from_waker(futures::task::noop_waker_ref());
use crate::central::Filter;
let central = FakeCentral::default();
let mut scan_results = central.scan(&[Filter::ServiceUuid(Uuid::from_u16(0x1844)).into()]);
let polled = scan_results.poll_next_unpin(&mut noop_cx);
let Poll::Ready(Some(Ok(_scan_result))) = polled else {
panic!("Expected a ready scan result got {polled:?}");
};
}