1use core::{cell::RefCell, marker::PhantomData};
4
5use embedded_hal_async::delay::DelayNs;
6use heapless::Vec;
7use rand::{CryptoRng, TryCryptoRng, TryRng};
8use umsh_hal::{CounterStore, KeyValueStore};
9
10pub use umsh_hal::EmbassyClock;
16
17#[cfg(feature = "software-crypto")]
18use crate::{
19 Platform,
20 crypto::software::{SoftwareAes, SoftwareIdentity, SoftwareSha256},
21};
22
23#[derive(Clone, Copy, Debug, Default)]
25pub struct EmbassyDelay;
26
27impl DelayNs for EmbassyDelay {
28 async fn delay_ns(&mut self, ns: u32) {
29 embassy_time::Timer::after_nanos(u64::from(ns)).await;
30 }
31}
32
33pub struct RngCoreAdapter<R>(pub R);
35
36impl<R: TryRng> TryRng for RngCoreAdapter<R> {
37 type Error = R::Error;
38
39 fn try_next_u32(&mut self) -> Result<u32, Self::Error> {
40 self.0.try_next_u32()
41 }
42
43 fn try_next_u64(&mut self) -> Result<u64, Self::Error> {
44 self.0.try_next_u64()
45 }
46
47 fn try_fill_bytes(&mut self, dest: &mut [u8]) -> Result<(), Self::Error> {
48 self.0.try_fill_bytes(dest)
49 }
50}
51
52impl<R: TryCryptoRng> TryCryptoRng for RngCoreAdapter<R> {}
53
54#[derive(Clone, Copy, Debug, PartialEq, Eq)]
56pub enum MemoryStoreError {
57 Capacity,
58 KeyTooLarge,
59 ValueTooLarge,
60 BufferTooSmall,
61}
62
63pub struct MemoryCounterStore<const ENTRIES: usize, const KEY_LEN: usize> {
65 entries: RefCell<Vec<(Vec<u8, KEY_LEN>, u32), ENTRIES>>,
66}
67
68impl<const ENTRIES: usize, const KEY_LEN: usize> Default for MemoryCounterStore<ENTRIES, KEY_LEN> {
69 fn default() -> Self {
70 Self {
71 entries: RefCell::new(Vec::new()),
72 }
73 }
74}
75
76impl<const ENTRIES: usize, const KEY_LEN: usize> CounterStore
77 for MemoryCounterStore<ENTRIES, KEY_LEN>
78{
79 type Error = MemoryStoreError;
80
81 async fn load(&self, context: &[u8]) -> Result<u32, Self::Error> {
82 Ok(self
83 .entries
84 .borrow()
85 .iter()
86 .find(|(key, _)| key.as_slice() == context)
87 .map(|(_, value)| *value)
88 .unwrap_or(0))
89 }
90
91 async fn store(&self, context: &[u8], value: u32) -> Result<(), Self::Error> {
92 let mut entries = self.entries.borrow_mut();
93 if let Some((_, stored)) = entries
94 .iter_mut()
95 .find(|(key, _)| key.as_slice() == context)
96 {
97 *stored = value;
98 return Ok(());
99 }
100 let key = to_heapless_vec::<KEY_LEN>(context).map_err(|_| MemoryStoreError::KeyTooLarge)?;
101 entries
102 .push((key, value))
103 .map_err(|_| MemoryStoreError::Capacity)
104 }
105
106 async fn flush(&self) -> Result<(), Self::Error> {
107 Ok(())
108 }
109}
110
111pub struct MemoryKeyValueStore<const ENTRIES: usize, const KEY_LEN: usize, const VALUE_LEN: usize> {
113 entries: RefCell<Vec<(Vec<u8, KEY_LEN>, Vec<u8, VALUE_LEN>), ENTRIES>>,
114}
115
116impl<const ENTRIES: usize, const KEY_LEN: usize, const VALUE_LEN: usize> Default
117 for MemoryKeyValueStore<ENTRIES, KEY_LEN, VALUE_LEN>
118{
119 fn default() -> Self {
120 Self {
121 entries: RefCell::new(Vec::new()),
122 }
123 }
124}
125
126impl<const ENTRIES: usize, const KEY_LEN: usize, const VALUE_LEN: usize> KeyValueStore
127 for MemoryKeyValueStore<ENTRIES, KEY_LEN, VALUE_LEN>
128{
129 type Error = MemoryStoreError;
130
131 async fn load(&self, key: &[u8], buf: &mut [u8]) -> Result<Option<usize>, Self::Error> {
132 let entries = self.entries.borrow();
133 let Some((_, value)) = entries
134 .iter()
135 .find(|(stored_key, _)| stored_key.as_slice() == key)
136 else {
137 return Ok(None);
138 };
139 if value.len() > buf.len() {
140 return Err(MemoryStoreError::BufferTooSmall);
141 }
142 buf[..value.len()].copy_from_slice(value.as_slice());
143 Ok(Some(value.len()))
144 }
145
146 async fn store(&self, key: &[u8], value: &[u8]) -> Result<(), Self::Error> {
147 let mut entries = self.entries.borrow_mut();
148 let value_vec =
149 to_heapless_vec::<VALUE_LEN>(value).map_err(|_| MemoryStoreError::ValueTooLarge)?;
150 if let Some((_, stored_value)) = entries
151 .iter_mut()
152 .find(|(stored_key, _)| stored_key.as_slice() == key)
153 {
154 *stored_value = value_vec;
155 return Ok(());
156 }
157 let key_vec = to_heapless_vec::<KEY_LEN>(key).map_err(|_| MemoryStoreError::KeyTooLarge)?;
158 entries
159 .push((key_vec, value_vec))
160 .map_err(|_| MemoryStoreError::Capacity)
161 }
162
163 async fn delete(&self, key: &[u8]) -> Result<(), Self::Error> {
164 let mut entries = self.entries.borrow_mut();
165 if let Some(index) = entries
166 .iter()
167 .position(|(stored_key, _)| stored_key.as_slice() == key)
168 {
169 entries.swap_remove(index);
170 }
171 Ok(())
172 }
173}
174
175#[cfg(feature = "software-crypto")]
177pub struct EmbassyPlatform<R, G, CS, KV>(PhantomData<(R, G, CS, KV)>);
178
179#[cfg(feature = "software-crypto")]
180impl<R, G, CS, KV> Platform for EmbassyPlatform<R, G, CS, KV>
181where
182 R: umsh_hal::Radio,
183 G: CryptoRng,
184 CS: CounterStore,
185 KV: KeyValueStore,
186{
187 type Identity = SoftwareIdentity;
188 type Aes = SoftwareAes;
189 type Sha = SoftwareSha256;
190 type Radio = R;
191 type Delay = EmbassyDelay;
192 type Clock = EmbassyClock;
193 type Rng = G;
194 type CounterStore = CS;
195 type KeyValueStore = KV;
196}
197
198fn to_heapless_vec<const N: usize>(bytes: &[u8]) -> Result<Vec<u8, N>, ()> {
199 let mut out = Vec::new();
200 out.extend_from_slice(bytes).map_err(|_| ())?;
201 Ok(out)
202}
203
204#[cfg(test)]
205mod tests {
206 use super::*;
207 use core::{
208 future::Future,
209 pin::pin,
210 task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
211 };
212
213 fn block_on_ready<F: Future>(future: F) -> F::Output {
214 fn raw_waker() -> RawWaker {
215 fn clone(_: *const ()) -> RawWaker {
216 raw_waker()
217 }
218 fn wake(_: *const ()) {}
219 fn wake_by_ref(_: *const ()) {}
220 fn drop(_: *const ()) {}
221
222 static VTABLE: RawWakerVTable = RawWakerVTable::new(clone, wake, wake_by_ref, drop);
223 RawWaker::new(core::ptr::null(), &VTABLE)
224 }
225
226 let waker = unsafe { Waker::from_raw(raw_waker()) };
227 let mut future = pin!(future);
228 let mut context = Context::from_waker(&waker);
229 match future.as_mut().poll(&mut context) {
230 Poll::Ready(value) => value,
231 Poll::Pending => panic!("test future unexpectedly pending"),
232 }
233 }
234
235 #[test]
236 fn memory_counter_store_round_trips() {
237 let store = MemoryCounterStore::<4, 16>::default();
238 assert_eq!(block_on_ready(store.load(b"peer")).unwrap(), 0);
239 block_on_ready(store.store(b"peer", 9)).unwrap();
240 assert_eq!(block_on_ready(store.load(b"peer")).unwrap(), 9);
241 }
242
243 #[test]
244 fn memory_key_value_store_round_trips() {
245 let store = MemoryKeyValueStore::<4, 16, 32>::default();
246 block_on_ready(store.store(b"peer", b"value")).unwrap();
247 let mut buf = [0u8; 32];
248 let len = block_on_ready(store.load(b"peer", &mut buf))
249 .unwrap()
250 .unwrap();
251 assert_eq!(&buf[..len], b"value");
252 block_on_ready(store.delete(b"peer")).unwrap();
253 assert_eq!(block_on_ready(store.load(b"peer", &mut buf)).unwrap(), None);
254 }
255}