1use log::trace;
17
18use crate::config::SSHStampConfig;
19use crate::handle::{
20 EventContext, SessionType, defunct, first_auth, hostkeys, open_session, password_auth,
21 pubkey_auth, session_env, session_exec, session_pty, session_shell, session_subsystem,
22};
23use crate::mem_probe::{Checkpoint, checkpoint, log_kex_elapsed};
24use crate::platform::PlatformServices;
25use crate::settings::UART_BUFFER_SIZE;
26use sunset::{ChanHandle, ServEvent};
27use sunset_async::{ProgressHolder, SSHServer, SunsetMutex};
28
29use core::result::Result;
30
31use embassy_sync::blocking_mutex::raw::NoopRawMutex;
32use embassy_sync::channel::Channel;
33
34pub async fn connection_loop<P: PlatformServices>(
42 serv: &SSHServer<'_>,
43 chan_pipe: &Channel<NoopRawMutex, SessionType, 1>,
44 config: &SunsetMutex<SSHStampConfig>,
45 platform: &P,
46 #[cfg(feature = "can")] can_queue: &Channel<NoopRawMutex, ChanHandle, 1>,
47) -> Result<(), sunset::Error> {
48 let mut session: Option<ChanHandle> = None;
49 let mut config_changed = false;
50 let mut needs_reset = false;
51 let mut auth_checked = false;
52 #[cfg(all(feature = "sftp-ota", feature = "can"))]
53 let mut can_dispatched = false;
54
55 loop {
56 let mut ph = ProgressHolder::new();
57 let ev = serv.progress(&mut ph).await?;
58
59 trace!("{ev:?}");
60
61 let mut ctx = EventContext {
62 session: &mut session,
63 auth_checked: &mut auth_checked,
64 config_changed: &mut config_changed,
65 needs_reset: &mut needs_reset,
66 #[cfg(feature = "can")]
67 can_queue,
68 #[cfg(all(feature = "sftp-ota", feature = "can"))]
69 can_dispatched: &mut can_dispatched,
70 };
71
72 match ev {
73 ServEvent::SessionSubsystem(_) => {
74 #[cfg(feature = "sftp-ota")]
75 session_subsystem(ev, &mut ctx, chan_pipe)?;
76 #[cfg(not(feature = "sftp-ota"))]
77 session_subsystem(ev, &mut ctx)?;
78 }
79 ServEvent::SessionShell(_) => {
80 session_shell(ev, &mut ctx, config, chan_pipe, platform).await?;
81 }
82 ServEvent::FirstAuth(_) => {
83 checkpoint(Checkpoint::KexComplete);
84 log_kex_elapsed("accept->firstauth");
85 first_auth(ev, config).await?;
86 }
87 ServEvent::Hostkeys(_) => {
88 hostkeys(ev, config).await?;
89 }
90 ServEvent::PasswordAuth(_) => {
91 password_auth(ev)?;
92 }
93 ServEvent::PubkeyAuth(_) => {
94 pubkey_auth(ev, &mut ctx, config).await?;
95 }
96 ServEvent::OpenSession(_) => {
97 checkpoint(Checkpoint::ChannelOpen);
98 open_session(ev, &mut ctx)?;
99 }
100 ServEvent::SessionEnv(_) => {
101 session_env(ev, &mut ctx, config).await?;
102 }
103 ServEvent::SessionPty(_) => {
104 session_pty(ev, &mut ctx, config).await?;
105 }
106 ServEvent::SessionExec(_) => {
107 session_exec(ev)?;
108 }
109 ServEvent::Defunct => {
110 defunct()?;
111 }
112 ServEvent::Authenticated => {
113 checkpoint(Checkpoint::AuthSuccess);
114 }
115 ServEvent::PollAgain => {}
116 }
117 }
118}
119
120pub fn ssh_wait_for_initialisation<'server>(
122 inbuf: &'server mut [u8; UART_BUFFER_SIZE],
123 outbuf: &'server mut [u8; UART_BUFFER_SIZE],
124) -> SSHServer<'server> {
125 SSHServer::new(inbuf, outbuf)
126}