Skip to content

Commit 47f7452

Browse files
dispatch: Make Dispatch generic over buffer size
The fixed buffer size can be problematic for some use cases, see: - #15 To avoid adding support for different buffer sizes to the crate, we can just make the dispatch implementation generic over the buffer size. For simple cases, a type alias is provided using the old buffer size.
1 parent 2001761 commit 47f7452

File tree

4 files changed

+34
-33
lines changed

4 files changed

+34
-33
lines changed

dispatch/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

77
## [Unreleased]
8-
-
8+
9+
- Make `Dispatch` generic over the buffer size, rename `MESSAGE_SIZE` to `DEFAULT_MESSAGE_SIZE`, remove the `Message` type and add a `DefaultDispatch` type alias for `Dispatch<_, _, DEFAULT_MESSAGE_SIZE>`.
910

1011
## [0.2.0] - 2025-01-08
1112

dispatch/src/dispatch.rs

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,29 @@
11
use core::sync::atomic::Ordering;
22

3-
use crate::types::{InterchangeResponse, Message, Responder, MESSAGE_SIZE};
3+
use crate::types::{InterchangeResponse, Responder};
44

55
use ctaphid_app::{App, Command, Error};
6+
use heapless_bytes::Bytes;
67
use ref_swap::OptionRefSwap;
78
use trussed_core::InterruptFlag;
89

9-
pub struct Dispatch<'pipe, 'interrupt> {
10-
responder: Responder<'pipe>,
10+
pub struct Dispatch<'pipe, 'interrupt, const N: usize> {
11+
responder: Responder<'pipe, N>,
1112
interrupt: Option<&'interrupt OptionRefSwap<'interrupt, InterruptFlag>>,
1213
}
1314

14-
impl<'pipe> Dispatch<'pipe, '_> {
15-
pub fn new(responder: Responder<'pipe>) -> Self {
15+
impl<'pipe, const N: usize> Dispatch<'pipe, '_, N> {
16+
pub fn new(responder: Responder<'pipe, N>) -> Self {
1617
Dispatch {
1718
responder,
1819
interrupt: None,
1920
}
2021
}
2122
}
2223

23-
impl<'pipe, 'interrupt> Dispatch<'pipe, 'interrupt> {
24+
impl<'pipe, 'interrupt, const N: usize> Dispatch<'pipe, 'interrupt, N> {
2425
pub fn with_interrupt(
25-
responder: Responder<'pipe>,
26+
responder: Responder<'pipe, N>,
2627
interrupt: Option<&'interrupt OptionRefSwap<'interrupt, InterruptFlag>>,
2728
) -> Self {
2829
Dispatch {
@@ -33,8 +34,8 @@ impl<'pipe, 'interrupt> Dispatch<'pipe, 'interrupt> {
3334

3435
fn find_app<'a, 'b>(
3536
command: Command,
36-
apps: &'a mut [&'b mut dyn App<'interrupt, MESSAGE_SIZE>],
37-
) -> Option<&'a mut &'b mut dyn App<'interrupt, MESSAGE_SIZE>> {
37+
apps: &'a mut [&'b mut dyn App<'interrupt, N>],
38+
) -> Option<&'a mut &'b mut dyn App<'interrupt, N>> {
3839
apps.iter_mut()
3940
.find(|app| app.commands().contains(&command))
4041
}
@@ -53,7 +54,7 @@ impl<'pipe, 'interrupt> Dispatch<'pipe, 'interrupt> {
5354
self.reply_or_cancel(InterchangeResponse(Err(error)))
5455
}
5556

56-
fn reply_or_cancel(&mut self, response: InterchangeResponse) {
57+
fn reply_or_cancel(&mut self, response: InterchangeResponse<N>) {
5758
if self.responder.respond(response).is_ok() {
5859
return;
5960
}
@@ -62,6 +63,7 @@ impl<'pipe, 'interrupt> Dispatch<'pipe, 'interrupt> {
6263
panic!("Unexpected state: {:?}", self.responder.state());
6364
}
6465
}
66+
6567
fn send_reply_or_cancel(&mut self) {
6668
if self.responder.send_response().is_ok() {
6769
return;
@@ -73,12 +75,7 @@ impl<'pipe, 'interrupt> Dispatch<'pipe, 'interrupt> {
7375
}
7476

7577
#[inline(never)]
76-
fn call_app(
77-
&mut self,
78-
app: &mut dyn App<'interrupt, MESSAGE_SIZE>,
79-
command: Command,
80-
request: &Message,
81-
) {
78+
fn call_app(&mut self, app: &mut dyn App<'interrupt, N>, command: Command, request: &Bytes<N>) {
8279
let response_buffer = self
8380
.responder
8481
.response_mut()
@@ -109,9 +106,9 @@ impl<'pipe, 'interrupt> Dispatch<'pipe, 'interrupt> {
109106
}
110107

111108
#[inline(never)]
112-
pub fn poll(&mut self, apps: &mut [&mut dyn App<'interrupt, MESSAGE_SIZE>]) -> bool {
109+
pub fn poll(&mut self, apps: &mut [&mut dyn App<'interrupt, N>]) -> bool {
113110
// We could call take_request directly, but for some reason this doubles stack usage.
114-
let mut message_buffer = Message::new();
111+
let mut message_buffer = Bytes::new();
115112
if let Ok((command, message)) = self.responder.request() {
116113
// info_now!("cmd: {}", u8::from(command));
117114
// info_now!("cmd: {:?}", command);

dispatch/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,6 @@ mod types;
1919
pub use ctaphid_app as app;
2020

2121
pub use dispatch::Dispatch;
22-
pub use types::{Channel, InterchangeResponse, Message, Requester, Responder, MESSAGE_SIZE};
22+
pub use types::{Channel, InterchangeResponse, Requester, Responder, DEFAULT_MESSAGE_SIZE};
23+
24+
pub type DefaultDispatch<'pipe, 'interrupt> = Dispatch<'pipe, 'interrupt, DEFAULT_MESSAGE_SIZE>;

dispatch/src/types.rs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,32 @@
11
use ctaphid_app::{Command, Error};
22
use heapless_bytes::Bytes;
33

4-
pub const MESSAGE_SIZE: usize = 7609;
5-
6-
pub type Message = Bytes<MESSAGE_SIZE>;
4+
pub const DEFAULT_MESSAGE_SIZE: usize = 7609;
75

86
/// Wrapper struct that implements [`Default`][] to be able to use [`response_mut`](interchange::Responder::response_mut)
9-
pub struct InterchangeResponse(pub Result<Message, Error>);
7+
pub struct InterchangeResponse<const N: usize>(pub Result<Bytes<N>, Error>);
108

11-
impl Default for InterchangeResponse {
9+
impl<const N: usize> Default for InterchangeResponse<N> {
1210
fn default() -> Self {
13-
InterchangeResponse(Ok(Message::new()))
11+
InterchangeResponse(Ok(Default::default()))
1412
}
1513
}
1614

17-
impl From<Result<Message, Error>> for InterchangeResponse {
18-
fn from(value: Result<Message, Error>) -> Self {
15+
impl<const N: usize> From<Result<Bytes<N>, Error>> for InterchangeResponse<N> {
16+
fn from(value: Result<Bytes<N>, Error>) -> Self {
1917
Self(value)
2018
}
2119
}
2220

23-
impl From<InterchangeResponse> for Result<Message, Error> {
24-
fn from(value: InterchangeResponse) -> Self {
21+
impl<const N: usize> From<InterchangeResponse<N>> for Result<Bytes<N>, Error> {
22+
fn from(value: InterchangeResponse<N>) -> Self {
2523
value.0
2624
}
2725
}
2826

29-
pub type Responder<'pipe> = interchange::Responder<'pipe, (Command, Message), InterchangeResponse>;
30-
pub type Requester<'pipe> = interchange::Requester<'pipe, (Command, Message), InterchangeResponse>;
31-
pub type Channel = interchange::Channel<(Command, Message), InterchangeResponse>;
27+
pub type Responder<'pipe, const N: usize> =
28+
interchange::Responder<'pipe, (Command, Bytes<N>), InterchangeResponse<N>>;
29+
pub type Requester<'pipe, const N: usize> =
30+
interchange::Requester<'pipe, (Command, Bytes<N>), InterchangeResponse<N>>;
31+
pub type Channel<const N: usize> =
32+
interchange::Channel<(Command, Bytes<N>), InterchangeResponse<N>>;

0 commit comments

Comments
 (0)