diff --git a/embassy/demos/std/src/main.rs b/embassy/demos/std/src/main.rs
index d8231a874da19dd4500f3e69e59ebe518c9ee8c1..ecdde261e422368fe8651b385dde2fd65c374cd3 100644
--- a/embassy/demos/std/src/main.rs
+++ b/embassy/demos/std/src/main.rs
@@ -103,32 +103,30 @@ async fn listener(stack: &'static Stack<TunTapDevice>) -> ! {
     }
 }
 
-struct DemoServer {
+struct DemoServer<'a> {
     keys: [SignKey; 1],
 
     sess: Option<u32>,
-    want_shell: bool,
     shell_started: bool,
 
-    notify: Signal<CriticalSectionRawMutex, ()>,
+    shell: &'a DemoShell,
 }
 
-impl DemoServer {
-    fn new() -> Result<Self> {
+impl<'a> DemoServer<'a> {
+    fn new(shell: &'a DemoShell) -> Result<Self> {
 
         let keys = [SignKey::generate(KeyType::Ed25519)?];
 
         Ok(Self {
             sess: None,
             keys,
-            want_shell: false,
             shell_started: false,
-            notify: Signal::new(),
+            shell,
         })
     }
 }
 
-impl ServBehaviour for DemoServer {
+impl<'a> ServBehaviour for DemoServer<'a> {
     fn hostkeys(&mut self) -> BhResult<&[SignKey]> {
         Ok(&self.keys)
     }
@@ -148,9 +146,9 @@ impl ServBehaviour for DemoServer {
     }
 
     fn sess_shell(&mut self, chan: u32) -> bool {
-        let r = !self.want_shell && self.sess == Some(chan);
-        self.want_shell = true;
-        self.notify.signal(());
+        let r = !self.shell_started && self.sess == Some(chan);
+        self.shell_started = true;
+        self.shell.notify.signal(chan);
         trace!("req want shell");
         r
     }
@@ -160,36 +158,49 @@ impl ServBehaviour for DemoServer {
     }
 }
 
-async fn shell_fut<'f>(serv: &SSHServer<'f>, app: &Mutex<NoopRawMutex, DemoServer>) -> Result<()>
-{
-    let session = async {
-        // self.notify.wait()?;
-        let chan = app.lock().await.sess.trap()?;
-
-        loop {
-            let mut b = [0u8; 100];
-            let lr = serv.read_channel(chan, None, &mut b).await?;
-            let lw = serv.write_channel(chan, None, &b[..lr]).await?;
-            if lr != lw {
-                trace!("read/write mismatch {} {}", lr, lw);
+#[derive(Default)]
+struct DemoShell {
+    notify: Signal<CriticalSectionRawMutex, u32>,
+}
+
+impl DemoShell {
+    async fn run<'f>(&self, serv: &SSHServer<'f>) -> Result<()>
+    {
+        let session = async {
+            let chan = self.notify.wait().await;
+
+            loop {
+                let mut b = [0u8; 100];
+                let lr = serv.read_channel(chan, None, &mut b).await?;
+                let b = &mut b[..lr];
+                for c in b.iter_mut() {
+                    if *c >= b'0' && *c <= b'9' {
+                        *c = b'0' + (b'9' - *c)
+                    }
+                }
+                let lw = serv.write_channel(chan, None, b).await?;
+                if lr != lw {
+                    trace!("read/write mismatch {} {}", lr, lw);
+                }
             }
-        }
-        Ok(())
-    };
-    session.await
+            Ok(())
+        };
+        session.await
+    }
 }
 
 async fn session(socket: &mut TcpSocket<'_>) -> sunset::Result<()> {
-    let mut app = DemoServer::new()?;
+    let shell = DemoShell::default();
+    let app = DemoServer::new(&shell)?;
 
     let mut ssh_rxbuf = [0; 2000];
     let mut ssh_txbuf = [0; 2000];
-    let serv = SSHServer::new(&mut ssh_rxbuf, &mut ssh_txbuf, &mut app)?;
+    let serv = SSHServer::new(&mut ssh_rxbuf, &mut ssh_txbuf)?;
     let serv = &serv;
 
     let app = Mutex::<NoopRawMutex, _>::new(app);
 
-    let session = shell_fut(serv, &app);
+    let session = shell.run(serv);
 
     let app = &app as &Mutex::<NoopRawMutex, dyn ServBehaviour>;
     let run = serv.run(socket, app);
diff --git a/embassy/src/server.rs b/embassy/src/server.rs
index b7e59f6e0fd0888b2a8b5aad114b4308f47e7c7d..2017c9792ce34cea90b055c55a848793f7a1006b 100644
--- a/embassy/src/server.rs
+++ b/embassy/src/server.rs
@@ -13,9 +13,8 @@ pub struct SSHServer<'a> {
 
 impl<'a> SSHServer<'a> {
     pub fn new(inbuf: &'a mut [u8], outbuf: &'a mut [u8],
-        b: &mut (dyn ServBehaviour + Send),
         ) -> Result<Self> {
-        let runner = Runner::new_server(inbuf, outbuf, b)?;
+        let runner = Runner::new_server(inbuf, outbuf)?;
         let sunset = EmbassySunset::new(runner);
         Ok(Self { sunset })
     }
diff --git a/src/conn.rs b/src/conn.rs
index b2830a92dad60509269e5acac9dd824514b530bf..465a25500e07b54420a03becae3f9770f2f55fe1 100644
--- a/src/conn.rs
+++ b/src/conn.rs
@@ -93,11 +93,10 @@ impl Conn {
     }
 
     pub fn new_server(
-        b: &mut dyn ServBehaviour,
         ) -> Result<Self> {
         // XXX
         let algo_conf = AlgoConfig::new(false);
-        Self::new(ClientServer::Server(server::Server::new(b)), algo_conf)
+        Self::new(ClientServer::Server(server::Server::new()), algo_conf)
     }
 
     fn new(cliserv: ClientServer, algo_conf: AlgoConfig) -> Result<Self, Error> {
diff --git a/src/runner.rs b/src/runner.rs
index 413aff8247630f83807facaeacfc3c1d7545bb15..3b22fa34c34250013cafa153d775892a3e1a2c7a 100644
--- a/src/runner.rs
+++ b/src/runner.rs
@@ -66,10 +66,8 @@ impl<'a> Runner<'a> {
     pub fn new_server(
         inbuf: &'a mut [u8],
         outbuf: &'a mut [u8],
-        // TODO: can probably get rid of b argument here (and in callees)
-        b: &mut dyn ServBehaviour,
     ) -> Result<Runner<'a>, Error> {
-        let conn = Conn::new_server(b)?;
+        let conn = Conn::new_server()?;
         let runner = Runner {
             conn,
             traf_in: TrafIn::new(inbuf),
diff --git a/src/servauth.rs b/src/servauth.rs
index 32ad66daa878ebbc4962e54f9678890941289b98..b0de74753344dd555787e1c3e2b8b004b2b9a8dd 100644
--- a/src/servauth.rs
+++ b/src/servauth.rs
@@ -16,7 +16,7 @@ pub(crate) struct ServAuth {
 }
 
 impl ServAuth {
-    pub fn new(_b: &mut dyn ServBehaviour) -> Self {
+    pub fn new() -> Self {
         Self { authed: false }
     }
 
diff --git a/src/server.rs b/src/server.rs
index cc1bfa403a9f9ebaabe623ae301eaa2e2bdd8a2d..08be00a55483a465c07a49494a28dfa7bbbe6bd2 100644
--- a/src/server.rs
+++ b/src/server.rs
@@ -16,9 +16,8 @@ pub(crate) struct Server {
 
 impl Server {
     pub fn new(
-        b: &mut dyn ServBehaviour,
         ) -> Self {
-        Server { auth: ServAuth::new(b) }
+        Server { auth: ServAuth::new() }
     }
 
     pub fn service_request(&self, p: &ServiceRequest, s: &mut TrafSend) -> Result<()> {