1use umsh_core::{ChannelId, ChannelKey, PublicKey};
2use umsh_mac::{
3 AddPeerError, CachedRoute, CapacityError, LocalIdentityId, MacError, MacEventRef, MacHandle,
4 PeerId, Platform, SendError, SendOptions, SendReceipt,
5};
6
7pub trait MacBackend: Clone {
15 type SendError;
17 type CapacityError;
19 type RunError;
21
22 async fn next_event(
29 &self,
30 on_event: impl FnMut(LocalIdentityId, MacEventRef<'_>),
31 ) -> Result<(), Self::RunError>;
32
33 async fn add_peer(
35 &self,
36 key: PublicKey,
37 ) -> Result<PeerId, MacBackendError<Self::SendError, Self::CapacityError>>;
38 async fn remove_peer(&self, key: &PublicKey) -> bool {
41 let _ = key;
42 false
43 }
44 async fn ensure_transient_peer(&self, key: &PublicKey) -> bool {
48 let _ = key;
49 false
50 }
51 async fn add_private_channel(
53 &self,
54 key: ChannelKey,
55 ) -> Result<(), MacBackendError<Self::SendError, Self::CapacityError>>;
56 async fn add_named_channel(
58 &self,
59 name: &str,
60 ) -> Result<(), MacBackendError<Self::SendError, Self::CapacityError>>;
61 async fn remove_channel(&self, key: &ChannelKey) -> bool {
64 let _ = key;
65 false
66 }
67 async fn send_broadcast(
69 &self,
70 from: LocalIdentityId,
71 payload: &[u8],
72 options: &SendOptions,
73 ) -> Result<SendReceipt, MacBackendError<Self::SendError, Self::CapacityError>>;
74 async fn send_multicast(
76 &self,
77 from: LocalIdentityId,
78 channel: &ChannelId,
79 payload: &[u8],
80 options: &SendOptions,
81 ) -> Result<SendReceipt, MacBackendError<Self::SendError, Self::CapacityError>>;
82 async fn send_unicast(
84 &self,
85 from: LocalIdentityId,
86 dst: &PublicKey,
87 payload: &[u8],
88 options: &SendOptions,
89 ) -> Result<Option<SendReceipt>, MacBackendError<Self::SendError, Self::CapacityError>>;
90 async fn send_blind_unicast(
92 &self,
93 from: LocalIdentityId,
94 dst: &PublicKey,
95 channel: &ChannelId,
96 payload: &[u8],
97 options: &SendOptions,
98 ) -> Result<Option<SendReceipt>, MacBackendError<Self::SendError, Self::CapacityError>>;
99 async fn fill_random(&self, dest: &mut [u8]);
101 async fn now_ms(&self) -> u64;
103
104 #[cfg(feature = "software-crypto")]
105 async fn register_ephemeral(
106 &self,
107 parent: LocalIdentityId,
108 identity: umsh_crypto::software::SoftwareIdentity,
109 ) -> Result<LocalIdentityId, MacBackendError<Self::SendError, Self::CapacityError>>;
110
111 #[cfg(feature = "software-crypto")]
112 async fn remove_ephemeral(&self, id: LocalIdentityId) -> bool;
113
114 async fn frame_counter(&self, from: LocalIdentityId) -> Option<u32> {
116 let _ = from;
117 None
118 }
119
120 async fn persisted_frame_counter(&self, from: LocalIdentityId) -> Option<u32> {
122 let _ = from;
123 None
124 }
125
126 async fn for_each_peer(&self, f: &mut dyn FnMut(umsh_core::PublicKey)) {
130 let _ = f;
131 }
132
133 async fn for_each_peer_counter(
136 &self,
137 from: LocalIdentityId,
138 f: &mut dyn FnMut(umsh_core::PublicKey, u32, u32),
139 ) {
140 let _ = (from, f);
141 }
142
143 async fn peer_route(&self, peer: &PublicKey) -> Option<CachedRoute> {
145 let _ = peer;
146 None
147 }
148
149 async fn clear_peer_route(&self, peer: &PublicKey) -> bool {
151 let _ = peer;
152 false
153 }
154}
155
156#[derive(Clone, Debug, PartialEq, Eq)]
158pub enum MacBackendError<S, C> {
159 Send(S),
161 Capacity(C),
163 InvalidPublicKey,
165 InvalidChannelName(umsh_crypto::ChannelNameError),
167}
168
169impl<
170 'a,
171 P: Platform,
172 const IDENTITIES: usize,
173 const PEERS: usize,
174 const CHANNELS: usize,
175 const ACKS: usize,
176 const TX: usize,
177 const FRAME: usize,
178 const DUP: usize,
179 const RN: usize,
180 const HN: usize,
181> MacBackend for MacHandle<'a, P, IDENTITIES, PEERS, CHANNELS, ACKS, TX, FRAME, DUP, RN, HN>
182{
183 type SendError = SendError;
184 type CapacityError = CapacityError;
185 type RunError = MacError<<P::Radio as umsh_hal::Radio>::Error>;
186
187 async fn next_event(
188 &self,
189 on_event: impl FnMut(LocalIdentityId, MacEventRef<'_>),
190 ) -> Result<(), Self::RunError> {
191 self.next_event(on_event).await
192 }
193
194 async fn add_peer(
195 &self,
196 key: PublicKey,
197 ) -> Result<PeerId, MacBackendError<Self::SendError, Self::CapacityError>> {
198 self.add_peer(key).await.map_err(|err| match err {
199 AddPeerError::Capacity => MacBackendError::Capacity(CapacityError),
200 AddPeerError::InvalidPublicKey => MacBackendError::InvalidPublicKey,
201 })
202 }
203
204 async fn remove_peer(&self, key: &PublicKey) -> bool {
205 self.remove_peer(key).await
206 }
207
208 async fn ensure_transient_peer(&self, key: &PublicKey) -> bool {
209 self.ensure_transient_peer(key).await
210 }
211
212 async fn add_private_channel(
213 &self,
214 key: ChannelKey,
215 ) -> Result<(), MacBackendError<Self::SendError, Self::CapacityError>> {
216 self.add_channel(key)
217 .await
218 .map_err(MacBackendError::Capacity)
219 }
220
221 async fn add_named_channel(
222 &self,
223 name: &str,
224 ) -> Result<(), MacBackendError<Self::SendError, Self::CapacityError>> {
225 self.add_named_channel(name).await.map_err(|err| match err {
226 umsh_mac::AddChannelError::Capacity => MacBackendError::Capacity(CapacityError),
227 umsh_mac::AddChannelError::InvalidName(reason) => {
228 MacBackendError::InvalidChannelName(reason)
229 }
230 })
231 }
232
233 async fn remove_channel(&self, key: &ChannelKey) -> bool {
234 self.remove_channel(key).await
235 }
236
237 async fn send_broadcast(
238 &self,
239 from: LocalIdentityId,
240 payload: &[u8],
241 options: &SendOptions,
242 ) -> Result<SendReceipt, MacBackendError<Self::SendError, Self::CapacityError>> {
243 self.send_broadcast(from, payload, options)
244 .await
245 .map_err(MacBackendError::Send)
246 }
247
248 async fn send_multicast(
249 &self,
250 from: LocalIdentityId,
251 channel: &ChannelId,
252 payload: &[u8],
253 options: &SendOptions,
254 ) -> Result<SendReceipt, MacBackendError<Self::SendError, Self::CapacityError>> {
255 self.send_multicast(from, channel, payload, options)
256 .await
257 .map_err(MacBackendError::Send)
258 }
259
260 async fn send_unicast(
261 &self,
262 from: LocalIdentityId,
263 dst: &PublicKey,
264 payload: &[u8],
265 options: &SendOptions,
266 ) -> Result<Option<SendReceipt>, MacBackendError<Self::SendError, Self::CapacityError>> {
267 self.send_unicast(from, dst, payload, options)
268 .await
269 .map_err(MacBackendError::Send)
270 }
271
272 async fn send_blind_unicast(
273 &self,
274 from: LocalIdentityId,
275 dst: &PublicKey,
276 channel: &ChannelId,
277 payload: &[u8],
278 options: &SendOptions,
279 ) -> Result<Option<SendReceipt>, MacBackendError<Self::SendError, Self::CapacityError>> {
280 self.send_blind_unicast(from, dst, channel, payload, options)
281 .await
282 .map_err(MacBackendError::Send)
283 }
284
285 async fn fill_random(&self, dest: &mut [u8]) {
286 self.fill_random(dest).await
287 }
288
289 async fn now_ms(&self) -> u64 {
290 self.now_ms().await
291 }
292
293 #[cfg(feature = "software-crypto")]
294 async fn register_ephemeral(
295 &self,
296 parent: LocalIdentityId,
297 identity: umsh_crypto::software::SoftwareIdentity,
298 ) -> Result<LocalIdentityId, MacBackendError<Self::SendError, Self::CapacityError>> {
299 self.register_ephemeral(parent, identity)
300 .await
301 .map_err(MacBackendError::Capacity)
302 }
303
304 #[cfg(feature = "software-crypto")]
305 async fn remove_ephemeral(&self, id: LocalIdentityId) -> bool {
306 self.remove_ephemeral(id).await
307 }
308
309 async fn frame_counter(&self, from: LocalIdentityId) -> Option<u32> {
310 self.frame_counter(from).await
311 }
312
313 async fn persisted_frame_counter(&self, from: LocalIdentityId) -> Option<u32> {
314 self.persisted_frame_counter(from).await
315 }
316
317 async fn for_each_peer(&self, f: &mut dyn FnMut(umsh_core::PublicKey)) {
318 self.for_each_peer(f).await
319 }
320
321 async fn for_each_peer_counter(
322 &self,
323 from: LocalIdentityId,
324 f: &mut dyn FnMut(umsh_core::PublicKey, u32, u32),
325 ) {
326 self.for_each_peer_counter(from, f).await
327 }
328
329 async fn peer_route(&self, peer: &PublicKey) -> Option<CachedRoute> {
330 self.peer_route(peer).await
331 }
332
333 async fn clear_peer_route(&self, peer: &PublicKey) -> bool {
334 self.clear_peer_route(peer).await
335 }
336}