• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! Mocked implementation of GattDatastore for use in test
2 
3 use crate::gatt::callbacks::GattDatastore;
4 use crate::gatt::ffi::AttributeBackingType;
5 use crate::gatt::ids::{AttHandle, TransportIndex};
6 use crate::packets::att::AttErrorCode;
7 use async_trait::async_trait;
8 use log::info;
9 use tokio::sync::mpsc::{self, unbounded_channel, UnboundedReceiver};
10 use tokio::sync::oneshot;
11 
12 /// Routes calls to GattDatastore into a channel of MockDatastoreEvents
13 pub struct MockDatastore(mpsc::UnboundedSender<MockDatastoreEvents>);
14 
15 impl MockDatastore {
16     /// Constructor. Returns self and the RX side of the associated channel.
new() -> (Self, UnboundedReceiver<MockDatastoreEvents>)17     pub fn new() -> (Self, UnboundedReceiver<MockDatastoreEvents>) {
18         let (tx, rx) = unbounded_channel();
19         (Self(tx), rx)
20     }
21 }
22 
23 /// Events representing calls to GattDatastore
24 #[derive(Debug)]
25 pub enum MockDatastoreEvents {
26     /// A characteristic was read on a given handle. The oneshot is used to
27     /// return the value read.
28     Read(
29         TransportIndex,
30         AttHandle,
31         AttributeBackingType,
32         oneshot::Sender<Result<Vec<u8>, AttErrorCode>>,
33     ),
34     /// A characteristic was written to on a given handle. The oneshot is used
35     /// to return whether the write succeeded.
36     Write(
37         TransportIndex,
38         AttHandle,
39         AttributeBackingType,
40         Vec<u8>,
41         oneshot::Sender<Result<(), AttErrorCode>>,
42     ),
43 }
44 
45 #[async_trait(?Send)]
46 impl GattDatastore for MockDatastore {
read( &self, tcb_idx: TransportIndex, handle: AttHandle, attr_type: AttributeBackingType, ) -> Result<Vec<u8>, AttErrorCode>47     async fn read(
48         &self,
49         tcb_idx: TransportIndex,
50         handle: AttHandle,
51         attr_type: AttributeBackingType,
52     ) -> Result<Vec<u8>, AttErrorCode> {
53         let (tx, rx) = oneshot::channel();
54         self.0.send(MockDatastoreEvents::Read(tcb_idx, handle, attr_type, tx)).unwrap();
55         let resp = rx.await.unwrap();
56         info!("sending {resp:?} down from upper tester");
57         resp
58     }
59 
write( &self, tcb_idx: TransportIndex, handle: AttHandle, attr_type: AttributeBackingType, data: &[u8], ) -> Result<(), AttErrorCode>60     async fn write(
61         &self,
62         tcb_idx: TransportIndex,
63         handle: AttHandle,
64         attr_type: AttributeBackingType,
65         data: &[u8],
66     ) -> Result<(), AttErrorCode> {
67         let (tx, rx) = oneshot::channel();
68         self.0
69             .send(MockDatastoreEvents::Write(tcb_idx, handle, attr_type, data.to_vec(), tx))
70             .unwrap();
71         rx.await.unwrap()
72     }
73 }
74