From 730373a09bd4fdcd2e3ce629deab99790db45605 Mon Sep 17 00:00:00 2001 From: Sofia Date: Thu, 28 May 2026 23:39:38 +0300 Subject: [PATCH] Update how InitATState works --- src/async_io.rs | 2 +- src/at_commands.rs | 15 ++++- src/state.rs | 6 +- src/states.rs | 146 +++++++++++++++++++-------------------------- 4 files changed, 80 insertions(+), 89 deletions(-) diff --git a/src/async_io.rs b/src/async_io.rs index e209703..c9285bd 100644 --- a/src/async_io.rs +++ b/src/async_io.rs @@ -82,7 +82,7 @@ impl Default for AsyncIO { unsafe impl Send for AsyncIO {} unsafe impl Sync for AsyncIO {} -#[derive(Default)] +#[derive(Default, Clone)] pub struct ATPromise { _data: PhantomData, } diff --git a/src/at_commands.rs b/src/at_commands.rs index a37c124..035d38d 100644 --- a/src/at_commands.rs +++ b/src/at_commands.rs @@ -160,11 +160,12 @@ impl<'a, 'd> ATCommands<'a, 'd> { } pub trait ATCommand: Send + Sync { - type Response; + type Response: core::fmt::Debug; fn execute(&self) -> ConstructedATCommand; fn parse_response(text: String) -> Self::Response; } +#[derive(Debug, Clone)] pub struct StubATCommand(()); impl ATCommand for StubATCommand { type Response = String; @@ -178,6 +179,7 @@ impl ATCommand for StubATCommand { } } +#[derive(Debug, Clone)] pub struct ATInformationCommand; impl ATCommand for ATInformationCommand { type Response = String; @@ -191,6 +193,7 @@ impl ATCommand for ATInformationCommand { } } +#[derive(Debug, Clone)] pub struct EnterPinCommand(pub String); impl ATCommand for EnterPinCommand { type Response = String; @@ -204,6 +207,7 @@ impl ATCommand for EnterPinCommand { } } +#[derive(Debug, Clone)] pub struct CheckPinCommand; impl ATCommand for CheckPinCommand { type Response = String; @@ -217,12 +221,13 @@ impl ATCommand for CheckPinCommand { } } -#[derive(Clone, Copy)] +#[derive(Debug, Clone, Copy)] pub enum SMSFormat { PDUMode = 0, TextMode = 1, } +#[derive(Debug, Clone)] pub struct SelectSMSFormatCommand(pub SMSFormat); impl ATCommand for SelectSMSFormatCommand { type Response = String; @@ -236,6 +241,7 @@ impl ATCommand for SelectSMSFormatCommand { } } +#[derive(Debug, Clone)] pub struct CheckSMSFormatCommand; impl ATCommand for CheckSMSFormatCommand { type Response = String; @@ -249,6 +255,7 @@ impl ATCommand for CheckSMSFormatCommand { } } +#[derive(Debug, Clone)] pub struct ListTECharacterSetsCommand; impl ATCommand for ListTECharacterSetsCommand { type Response = String; @@ -262,7 +269,7 @@ impl ATCommand for ListTECharacterSetsCommand { } } -#[derive(Clone)] +#[derive(Debug, Clone)] pub enum TECharset { IRA, UCS2, @@ -281,6 +288,7 @@ impl TECharset { } } +#[derive(Debug, Clone)] pub struct SetTECharsetCommand(pub TECharset); impl ATCommand for SetTECharsetCommand { type Response = String; @@ -294,6 +302,7 @@ impl ATCommand for SetTECharsetCommand { } } +#[derive(Debug, Clone)] pub struct SendSMSCommand { pub destination: String, pub message: String, diff --git a/src/state.rs b/src/state.rs index a130e1d..03d670c 100644 --- a/src/state.rs +++ b/src/state.rs @@ -67,6 +67,7 @@ impl<'a> StateData<'a> { } pub trait State { + fn init(&mut self, data: &mut StateData) {} fn update(&mut self, data: &mut StateData) -> Option>; fn draw(&self, data: &mut StateData); } @@ -79,7 +80,10 @@ pub struct StateManager<'a> { impl<'a> StateManager<'a> { pub fn update(&mut self) { match self.curr_state.update(&mut self.data) { - Some(next_state) => self.curr_state = next_state, + Some(next_state) => { + self.curr_state = next_state; + self.curr_state.init(&mut self.data); + } None => {} } self.data.io.button.clear(); diff --git a/src/states.rs b/src/states.rs index 12e4e71..d1ce3ab 100644 --- a/src/states.rs +++ b/src/states.rs @@ -11,36 +11,43 @@ use esp_hal::time::{Duration, Instant}; use crate::{ async_io::ATPromise, at_commands::{ - ATInformationCommand, CheckPinCommand, EnterPinCommand, ListTECharacterSetsCommand, - SMSFormat, SelectSMSFormatCommand, SendSMSCommand, SetTECharsetCommand, StubATCommand, - TECharset, + ATCommand, ATInformationCommand, CheckPinCommand, EnterPinCommand, + ListTECharacterSetsCommand, SMSFormat, SelectSMSFormatCommand, SendSMSCommand, + SetTECharsetCommand, StubATCommand, TECharset, }, display::{Position, Rgb565}, font::{HorizontalAlignment, VerticalAlignment}, state::{State, StateData, TextSettings}, }; -pub struct InitATState { - inner_state: u8, +#[derive(Clone)] +pub struct ATCommandState { message: String, + command: Cmd, dots: u8, prev_dots: Instant, - promise: Option>, + promise: Option>, + after_state: T, } -impl Default for InitATState { - fn default() -> Self { - Self { - inner_state: 0, - message: "Initializing AT..".to_string(), +impl ATCommandState { + pub fn with(message: String, command: Cmd, after: T) -> ATCommandState { + ATCommandState { + message, + command, dots: 0, prev_dots: Instant::now(), promise: None, + after_state: after, } } } -impl State for InitATState { +impl State for ATCommandState { + fn init(&mut self, data: &mut StateData) { + self.promise = Some(data.io.send_at_command(self.command.clone()).unwrap()); + } + fn update(&mut self, data: &mut StateData) -> Option> { // Update dots if self.prev_dots.elapsed() > Duration::from_millis(200) { @@ -52,7 +59,7 @@ impl State for InitATState { match promise.poll(&mut data.io) { Some(response) => match response { Some(response) => { - log::info!("Response: {}", response); + log::info!("Response: {:?}", response); self.promise = None; } None => {} @@ -62,77 +69,7 @@ impl State for InitATState { return None; } - // Send next AT command - let res: Option> = match self.inner_state { - 0 => { - self.promise = Some( - data.io - .send_at_command(ATInformationCommand) - .unwrap() - .downgrade(), - ); - self.message = "Checking info".to_owned(); - None - } - 1 => { - self.promise = Some( - data.io - .send_at_command(EnterPinCommand("1234".to_owned())) - .unwrap() - .downgrade(), - ); - self.message = "Entering PIN".to_owned(); - None - } - 2 => { - self.promise = Some( - data.io - .send_at_command(CheckPinCommand) - .unwrap() - .downgrade(), - ); - None - } - 3 => { - self.promise = Some( - data.io - .send_at_command(ListTECharacterSetsCommand) - .unwrap() - .downgrade(), - ); - self.message = "Checking\ncharsets".to_owned(); - None - } - 4 => { - self.promise = Some( - data.io - .send_at_command(SelectSMSFormatCommand(SMSFormat::TextMode)) - .unwrap() - .downgrade(), - ); - self.message = "Selecting SMS\nformat".to_owned(); - None - } - 5 => { - self.promise = Some( - data.io - .send_at_command(SetTECharsetCommand(TECharset::IRA)) - .unwrap() - .downgrade(), - ); - self.message = "Selecting SMS\nformat".to_owned(); - None - } - _ => { - data.delay.delay_millis(1000); - Some(Box::new(TextState { - text: "AT init done!".to_owned(), - })) - } - }; - - self.inner_state = (self.inner_state + 1).min(200); - res + return Some(Box::new(self.after_state.clone())); } fn draw(&self, data: &mut StateData) { @@ -146,6 +83,47 @@ impl State for InitATState { } } +pub struct InitATState; + +impl Default for InitATState { + fn default() -> Self { + Self {} + } +} + +impl State for InitATState { + fn update(&mut self, _: &mut StateData) -> Option> { + let state = ATCommandState::with( + "Checking info".to_owned(), + ATInformationCommand, + ATCommandState::with( + "Entering PIN".to_owned(), + EnterPinCommand("1234".to_owned()), + ATCommandState::with( + "Checking PIN".to_owned(), + CheckPinCommand, + ATCommandState::with( + "Selecting SMS\ncharset".to_owned(), + SelectSMSFormatCommand(SMSFormat::TextMode), + ATCommandState::with( + "Setting\nTE charset".to_owned(), + SetTECharsetCommand(TECharset::IRA), + TextState { + text: "All done!".to_owned(), + }, + ), + ), + ), + ), + ); + + Some(Box::new(state)) + } + + fn draw(&self, data: &mut StateData) {} +} + +#[derive(Clone)] pub struct TextState { text: String, }