From c1241798fefa464c05a37367064befebf7f50439 Mon Sep 17 00:00:00 2001 From: Sofia Date: Sat, 30 May 2026 19:29:58 +0300 Subject: [PATCH] Parse SMS error better --- src/at_commands.rs | 70 +++++++++++++++++++++++++++++++++++++++++++++- src/states.rs | 36 +++++++++++++++++++----- 2 files changed, 98 insertions(+), 8 deletions(-) diff --git a/src/at_commands.rs b/src/at_commands.rs index 2d50095..8d0f094 100644 --- a/src/at_commands.rs +++ b/src/at_commands.rs @@ -239,7 +239,7 @@ pub enum ATParseError { } pub trait ATCommand: Send + Sync { - type Response: core::fmt::Debug; + type Response: core::fmt::Debug + ATResponse; fn execute(&self, at_commands: &mut ATCommands) -> Vec; fn parse_response(parser: &mut ATResponseParser) -> Result; } @@ -260,12 +260,25 @@ impl SimpleATCommand for T { } } +pub trait ATResponse { + fn is_error(&self) -> bool; +} + #[derive(Debug)] pub enum SimpleATResponse { Ok, Error, } +impl ATResponse for SimpleATResponse { + fn is_error(&self) -> bool { + match self { + SimpleATResponse::Ok => false, + SimpleATResponse::Error => true, + } + } +} + #[derive(Debug, Clone)] pub struct ATInformation { manufacturer: String, @@ -274,6 +287,12 @@ pub struct ATInformation { imei: String, } +impl ATResponse for ATInformation { + fn is_error(&self) -> bool { + false + } +} + #[derive(Debug, Clone)] pub struct ATInformationCommand; impl ATCommand for ATInformationCommand { @@ -314,6 +333,15 @@ pub enum EnterPinResult { ErrorMessage(String), } +impl ATResponse for EnterPinResult { + fn is_error(&self) -> bool { + match self { + EnterPinResult::Ok => false, + _ => true, + } + } +} + #[derive(Debug, Clone)] pub struct EnterPinCommand(pub String); impl ATCommand for EnterPinCommand { @@ -343,6 +371,15 @@ pub enum CheckPinResult { ErrorMessage(String), } +impl ATResponse for CheckPinResult { + fn is_error(&self) -> bool { + match self { + CheckPinResult::Status(_) => false, + _ => true, + } + } +} + #[derive(Debug, Clone)] pub struct CheckPinCommand; impl ATCommand for CheckPinCommand { @@ -406,6 +443,15 @@ pub enum CheckSMSFormatResult { Error, } +impl ATResponse for CheckSMSFormatResult { + fn is_error(&self) -> bool { + match self { + CheckSMSFormatResult::Mode(_) => false, + _ => true, + } + } +} + #[derive(Debug, Clone)] pub struct CheckSMSFormatCommand; impl ATCommand for CheckSMSFormatCommand { @@ -439,6 +485,14 @@ pub enum TECharacterSets { Charsets(Vec), } +impl ATResponse for TECharacterSets { + fn is_error(&self) -> bool { + match self { + _ => false, + } + } +} + #[derive(Debug, Clone)] pub struct ListTECharacterSetsCommand; impl ATCommand for ListTECharacterSetsCommand { @@ -510,6 +564,15 @@ pub enum SendSMSResponse { ErrorMessage(String), } +impl ATResponse for SendSMSResponse { + fn is_error(&self) -> bool { + match self { + SendSMSResponse::MessageRefrence(_) => false, + _ => true, + } + } +} + #[derive(Debug, Clone)] pub struct SendSMSCommand { pub destination: String, @@ -528,6 +591,11 @@ impl ATCommand for SendSMSCommand { } fn parse_response(parser: &mut ATResponseParser) -> Result { + if let Ok(_) = parser.expect("+CMS ERROR: ".to_owned()) { + let result = parser.readline().unwrap(); + return Ok(SendSMSResponse::ErrorMessage(result)); + } + // Read first line out parser.readline(); diff --git a/src/states.rs b/src/states.rs index 8a85169..808cb34 100644 --- a/src/states.rs +++ b/src/states.rs @@ -11,7 +11,7 @@ use esp_hal::time::{Duration, Instant}; use crate::{ async_io::{ATPromise, KeypadButton}, at_commands::{ - ATCommand, ATInformationCommand, CheckPinCommand, EnterPinCommand, SMSFormat, + ATCommand, ATInformationCommand, ATResponse, CheckPinCommand, EnterPinCommand, SMSFormat, SelectSMSFormatCommand, SendSMSCommand, SetTECharsetCommand, TECharset, }, display::{Position, Rgb565}, @@ -20,17 +20,23 @@ use crate::{ }; #[derive(Clone)] -pub struct ATCommandState { +pub struct ATCommandState { message: String, command: Cmd, dots: u8, prev_dots: Instant, promise: Option>, after_state: T, + err_state: TErr, } -impl ATCommandState { - pub fn with(message: String, command: Cmd, after: T) -> ATCommandState { +impl ATCommandState { + pub fn with( + message: String, + command: Cmd, + after: T, + err: TErr, + ) -> ATCommandState { ATCommandState { message, command, @@ -38,12 +44,13 @@ impl ATCommandState { prev_dots: Instant::now(), promise: None, after_state: after, + err_state: err, } } } -impl State - for ATCommandState +impl + State for ATCommandState { fn init(&mut self, data: &mut StateData) { self.promise = Some(data.io.send_at_command(self.command.clone()).unwrap()); @@ -60,7 +67,13 @@ impl State match promise.poll(&mut data.io) { Some(response) => match response { Some(response) => { - log::info!("Response: {:?}", response); + match response { + Ok(response) => match response.is_error() { + true => return Some(Box::new(self.err_state.clone())), + false => log::info!("Response: {:?}", response), + }, + Err(_) => return Some(Box::new(self.err_state.clone())), + } self.promise = None; } None => {} @@ -84,6 +97,7 @@ impl State } } +#[derive(Debug, Clone)] pub struct InitATState; impl Default for InitATState { @@ -112,10 +126,15 @@ impl State for InitATState { TextState { text: "All done!".to_owned(), }, + InitATState::default(), ), + InitATState::default(), ), + InitATState::default(), ), + InitATState::default(), ), + InitATState::default(), ); Some(Box::new(state)) @@ -240,6 +259,9 @@ impl State for MessageState { TextState { text: "SMS Sent!".to_owned(), }, + TextState { + text: "Error!".to_owned(), + }, ))) } else { None