Skip to content

Commit c24ff8c

Browse files
committed
Rework common demo code
DemoServer trait is simplified, now a DemoServer reference is passed to demo_common::listen(), the Init has been removed. picow GlobalState is renamed to PicoDemo, and DemoServer implemented using that.
1 parent ab9a9bc commit c24ff8c

File tree

7 files changed

+44
-60
lines changed

7 files changed

+44
-60
lines changed

embassy/demos/common/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ pub mod takepipe;
1111

1212
pub use config::SSHConfig;
1313
pub use menu_buf::AsyncMenuBuf;
14-
pub use server::{listener, DemoServer, ServerApp};
14+
pub use server::{listen, DemoCommon, DemoServer};
1515

1616
// needed for derive
1717
use sunset::sshwire;

embassy/demos/common/src/server.rs

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,16 @@ use sunset_embassy::{SSHServer, SunsetMutex};
1414

1515
use crate::SSHConfig;
1616

17+
pub trait DemoServer {
18+
/// A handler to run for each incoming connection.
19+
async fn run(&self, serv: &SSHServer<'_>, common: DemoCommon) -> Result<()>;
20+
}
21+
1722
// common entry point
18-
pub async fn listener<S: DemoServer>(
23+
pub async fn listen(
1924
stack: Stack<'_>,
2025
config: &SunsetMutex<SSHConfig>,
21-
init: S::Init,
26+
demo: &impl DemoServer,
2227
) -> ! {
2328
// TODO: buffer size?
2429
// Does it help to be larger than ethernet MTU?
@@ -37,7 +42,7 @@ pub async fn listener<S: DemoServer>(
3742
continue;
3843
}
3944

40-
let r = session::<S>(&mut socket, &config, &init).await;
45+
let r = session(&mut socket, &config, demo).await;
4146
if let Err(e) = r {
4247
warn!("Ended with error {e:#?}");
4348
}
@@ -51,10 +56,10 @@ pub async fn listener<S: DemoServer>(
5156
}
5257

5358
/// Run a SSH session when a socket accepts a connection
54-
async fn session<S: DemoServer>(
59+
async fn session(
5560
socket: &mut TcpSocket<'_>,
5661
config: &SunsetMutex<SSHConfig>,
57-
init: &S::Init,
62+
demo: &impl DemoServer,
5863
) -> sunset::Result<()> {
5964
// OK unwrap: has been accepted
6065
let src = socket.remote_endpoint().unwrap();
@@ -66,11 +71,10 @@ async fn session<S: DemoServer>(
6671
let mut ssh_txbuf = [0; 1000];
6772
let serv = SSHServer::new(&mut ssh_rxbuf, &mut ssh_txbuf)?;
6873

69-
// Create the handler. ServerApp is common handling (this file),
74+
// Create the handler. DemoCommon is common handling (this file),
7075
// demo is the specific demo (std or picow).
71-
let demo = S::new(init);
7276
let conf = config.lock().await.clone();
73-
let app = ServerApp::new(conf)?;
77+
let app = DemoCommon::new(conf)?;
7478
// .run returns a future that runs for the life of the session
7579
let session = demo.run(&serv, app);
7680

@@ -89,15 +93,15 @@ async fn session<S: DemoServer>(
8993
/// Provides `ServBehaviour` for the server
9094
///
9195
/// Further customisations are provided by `DemoServer` generic
92-
pub struct ServerApp {
96+
pub struct DemoCommon {
9397
config: SSHConfig,
9498

9599
opened: bool,
96100
// Can be taken by the demoserver to run an interactive session.
97101
pub sess: Option<ChanHandle>,
98102
}
99103

100-
impl ServerApp {
104+
impl DemoCommon {
101105
const ADMIN_USER: &'static str = "config";
102106

103107
fn new(config: SSHConfig) -> Result<Self> {
@@ -180,13 +184,3 @@ impl ServerApp {
180184
username == Self::ADMIN_USER
181185
}
182186
}
183-
184-
pub trait DemoServer {
185-
/// State to be passed to each new connection by the server
186-
type Init;
187-
188-
fn new(init: &Self::Init) -> Self;
189-
190-
/// A task to run for each incoming connection.
191-
async fn run(&self, serv: &SSHServer<'_>, common: ServerApp) -> Result<()>;
192-
}

embassy/demos/picow/src/keyboard.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use embassy_usb_driver::Driver;
99
use crate::*;
1010

1111
pub(crate) async fn run<'a, D: Driver<'a>>(
12-
_global: &'static GlobalState,
12+
_global: &'static PicoDemo,
1313
hid: HidReaderWriter<'a, D, 1, 8>,
1414
) -> ! {
1515
let (reader, _writer) = hid.split();

embassy/demos/picow/src/main.rs

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use embassy_sync::blocking_mutex::raw::NoopRawMutex;
2121
use embassy_sync::channel::Channel;
2222
use embassy_sync::mutex::Mutex;
2323

24-
use demo_common::{takepipe, DemoServer, SSHConfig, ServerApp};
24+
use demo_common::{takepipe, DemoCommon, DemoServer, SSHConfig};
2525
use sunset::*;
2626
use sunset_demo_embassy_common as demo_common;
2727
use sunset_embassy::{ProgressHolder, SSHServer, SunsetMutex};
@@ -107,8 +107,8 @@ async fn main(spawner: Spawner) {
107107

108108
// state depends on the mac for cyw43 vs w5500
109109
let net_mac = SunsetMutex::new([0; 6]);
110-
static STATE: StaticCell<GlobalState> = StaticCell::new();
111-
let state = STATE.init_with(|| GlobalState {
110+
static STATE: StaticCell<PicoDemo> = StaticCell::new();
111+
let state = STATE.init_with(|| PicoDemo {
112112
usb_pipe,
113113
serial1_pipe,
114114
config,
@@ -158,12 +158,16 @@ async fn main(spawner: Spawner) {
158158
async fn net_listener(
159159
stack: Stack<'static>,
160160
config: &'static SunsetMutex<SSHConfig>,
161-
global: &'static GlobalState,
161+
demo: &'static PicoDemo,
162162
) -> ! {
163-
demo_common::listener::<PicoServer>(stack, config, global).await
163+
demo_common::listen(stack, config, &demo).await
164164
}
165165

166-
pub(crate) struct GlobalState {
166+
/// Shared state for the device.
167+
///
168+
/// This is shared between all connections.
169+
/// `PicoDemo` implements `DemoServer` to handle incoming connections.
170+
pub(crate) struct PicoDemo {
167171
// If locking multiple mutexes, always lock in the order below to avoid inversion.
168172
pub usb_pipe: &'static TakePipe<'static>,
169173
pub serial1_pipe: &'static TakePipe<'static>,
@@ -175,18 +179,14 @@ pub(crate) struct GlobalState {
175179
pub net_mac: SunsetMutex<[u8; 6]>,
176180
}
177181

178-
struct PicoServer {
179-
global: &'static GlobalState,
180-
}
181-
182182
// Presents a menu, either on serial or incoming SSH
183183
//
184184
// `local` is set for usb serial menus which require different auth
185185
async fn menu<R, W>(
186186
chanr: &mut R,
187187
chanw: &mut W,
188188
local: bool,
189-
state: &'static GlobalState,
189+
state: &'static PicoDemo,
190190
) -> Result<()>
191191
where
192192
R: Read<Error = sunset::Error>,
@@ -288,14 +288,9 @@ where
288288
info!("serial task completed");
289289
Ok(())
290290
}
291-
impl DemoServer for PicoServer {
292-
type Init = &'static GlobalState;
293-
294-
fn new(global: &Self::Init) -> Self {
295-
Self { global }
296-
}
297291

298-
async fn run(&self, serv: &SSHServer<'_>, mut common: ServerApp) -> Result<()> {
292+
impl DemoServer for &'static PicoDemo {
293+
async fn run(&self, serv: &SSHServer<'_>, mut common: DemoCommon) -> Result<()> {
299294
let username = Mutex::<NoopRawMutex, _>::new(String::<20>::new());
300295
let chan_pipe = Channel::<NoopRawMutex, ChanHandle, 1>::new();
301296

@@ -337,14 +332,14 @@ impl DemoServer for PicoServer {
337332
#[cfg(feature = "serial1")]
338333
let default_pipe = self.global.serial1_pipe;
339334
#[cfg(not(feature = "serial1"))]
340-
let default_pipe = self.global.usb_pipe;
335+
let default_pipe = self.usb_pipe;
341336

342337
let mut stdio2 = stdio.clone();
343338
match username.lock().await.as_str() {
344339
// Open the config menu
345-
"config" => menu(&mut stdio, &mut stdio2, false, self.global).await,
340+
"config" => menu(&mut stdio, &mut stdio2, false, self).await,
346341
// Open the usb serial directly
347-
"usb" => serial(&mut stdio, &mut stdio2, self.global.usb_pipe).await,
342+
"usb" => serial(&mut stdio, &mut stdio2, self.usb_pipe).await,
348343
// Open the normal (?) serial directly (either usb or uart)
349344
_ => serial(&mut stdio, &mut stdio2, default_pipe).await,
350345
}

embassy/demos/picow/src/picowmenu.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use pretty_hex::PrettyHex;
2222

2323
use crate::demo_common;
2424
use crate::flashconfig;
25-
use crate::GlobalState;
25+
use crate::PicoDemo;
2626
use demo_common::{AsyncMenuBuf, SSHConfig};
2727

2828
use demo_common::menu::*;
@@ -35,7 +35,7 @@ const MAX_PW_LEN: usize = 50;
3535

3636
pub(crate) struct MenuCtx {
3737
pub out: AsyncMenuBuf,
38-
state: &'static GlobalState,
38+
state: &'static PicoDemo,
3939

4040
// true for local serial console menu, false for SSH menu
4141
local: bool,
@@ -50,7 +50,7 @@ pub(crate) struct MenuCtx {
5050
}
5151

5252
impl MenuCtx {
53-
pub fn new(state: &'static GlobalState, local: bool) -> Self {
53+
pub fn new(state: &'static PicoDemo, local: bool) -> Self {
5454
Self {
5555
state,
5656
local,

embassy/demos/picow/src/usb.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ bind_interrupts!(struct Irqs {
2525
#[embassy_executor::task]
2626
pub(crate) async fn task(
2727
usb: embassy_rp::peripherals::USB,
28-
global: &'static GlobalState,
28+
global: &'static PicoDemo,
2929
) -> ! {
3030
let driver = embassy_rp::usb::Driver::new(usb, Irqs);
3131

@@ -100,7 +100,7 @@ pub(crate) async fn task(
100100
}
101101

102102
async fn console_if00_run<'a, D: Driver<'a>>(
103-
global: &'static GlobalState,
103+
global: &'static PicoDemo,
104104
cdc: CdcAcmClass<'a, D>,
105105
) -> ! {
106106
let (mut cdc_tx, mut cdc_rx) = cdc.split();
@@ -123,7 +123,7 @@ async fn console_if00_run<'a, D: Driver<'a>>(
123123
}
124124

125125
async fn menu_if02_run<'a, D: Driver<'a>>(
126-
global: &'static GlobalState,
126+
global: &'static PicoDemo,
127127
cdc: CdcAcmClass<'a, D>,
128128
) -> ! {
129129
let (mut cdc_tx, mut cdc_rx) = cdc.split();

embassy/demos/std/src/main.rs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use sunset_embassy::{ProgressHolder, SSHServer, SunsetMutex, SunsetRawMutex};
1919
mod setupmenu;
2020
pub(crate) use sunset_demo_embassy_common as demo_common;
2121

22-
use demo_common::{DemoServer, SSHConfig, ServerApp};
22+
use demo_common::{DemoCommon, DemoServer, SSHConfig};
2323

2424
const NUM_LISTENERS: usize = 4;
2525
// +1 for dhcp
@@ -73,21 +73,15 @@ async fn main_task(spawner: Spawner) {
7373
spawner.spawn(net_task(runner)).unwrap();
7474

7575
for _ in 0..NUM_LISTENERS {
76-
spawner.spawn(listener(stack, config)).unwrap();
76+
spawner.spawn(listen(stack, config)).unwrap();
7777
}
7878
}
7979

8080
#[derive(Default)]
8181
struct StdDemo;
8282

8383
impl DemoServer for StdDemo {
84-
type Init = ();
85-
86-
fn new(_init: &Self::Init) -> Self {
87-
Default::default()
88-
}
89-
90-
async fn run(&self, serv: &SSHServer<'_>, mut common: ServerApp) -> Result<()> {
84+
async fn run(&self, serv: &SSHServer<'_>, mut common: DemoCommon) -> Result<()> {
9185
let chan_pipe = Channel::<SunsetRawMutex, ChanHandle, 1>::new();
9286

9387
let prog_loop = async {
@@ -158,11 +152,12 @@ impl DemoServer for StdDemo {
158152

159153
// TODO: pool_size should be NUM_LISTENERS but needs a literal
160154
#[embassy_executor::task(pool_size = 4)]
161-
async fn listener(
155+
async fn listen(
162156
stack: Stack<'static>,
163157
config: &'static SunsetMutex<SSHConfig>,
164158
) -> ! {
165-
demo_common::listener::<StdDemo>(stack, config, ()).await
159+
let demo = StdDemo::default();
160+
demo_common::listen(stack, config, &demo).await
166161
}
167162

168163
#[embassy_executor::main]

0 commit comments

Comments
 (0)