From d9cdf45cb6409eac46569853c69526147eecd27e Mon Sep 17 00:00:00 2001
From: Matt Johnston <matt@ucc.asn.au>
Date: Sat, 19 Nov 2022 21:49:47 +0800
Subject: [PATCH] Add separate DemoShell

Now successfully connects to std embassy demo

Removed Behaviour argument to server constructors
---
 embassy/demos/std/src/main.rs | 71 ++++++++++++++++++++---------------
 embassy/src/server.rs         |  3 +-
 src/conn.rs                   |  3 +-
 src/runner.rs                 |  4 +-
 src/servauth.rs               |  2 +-
 src/server.rs                 |  3 +-
 6 files changed, 46 insertions(+), 40 deletions(-)

diff --git a/embassy/demos/std/src/main.rs b/embassy/demos/std/src/main.rs
index d8231a8..ecdde26 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 b7e59f6..2017c97 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 b2830a9..465a255 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 413aff8..3b22fa3 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 32ad66d..b0de747 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 cc1bfa4..08be00a 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<()> {
-- 
GitLab