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