Parse SMS error better

This commit is contained in:
Sofia 2026-05-30 19:29:58 +03:00
parent fe648fdb88
commit c1241798fe
2 changed files with 98 additions and 8 deletions

View File

@ -239,7 +239,7 @@ pub enum ATParseError {
} }
pub trait ATCommand: Send + Sync { pub trait ATCommand: Send + Sync {
type Response: core::fmt::Debug; type Response: core::fmt::Debug + ATResponse;
fn execute(&self, at_commands: &mut ATCommands) -> Vec<String>; fn execute(&self, at_commands: &mut ATCommands) -> Vec<String>;
fn parse_response(parser: &mut ATResponseParser) -> Result<Self::Response, ATParseError>; fn parse_response(parser: &mut ATResponseParser) -> Result<Self::Response, ATParseError>;
} }
@ -260,12 +260,25 @@ impl<T: ATCommand> SimpleATCommand for T {
} }
} }
pub trait ATResponse {
fn is_error(&self) -> bool;
}
#[derive(Debug)] #[derive(Debug)]
pub enum SimpleATResponse { pub enum SimpleATResponse {
Ok, Ok,
Error, Error,
} }
impl ATResponse for SimpleATResponse {
fn is_error(&self) -> bool {
match self {
SimpleATResponse::Ok => false,
SimpleATResponse::Error => true,
}
}
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct ATInformation { pub struct ATInformation {
manufacturer: String, manufacturer: String,
@ -274,6 +287,12 @@ pub struct ATInformation {
imei: String, imei: String,
} }
impl ATResponse for ATInformation {
fn is_error(&self) -> bool {
false
}
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct ATInformationCommand; pub struct ATInformationCommand;
impl ATCommand for ATInformationCommand { impl ATCommand for ATInformationCommand {
@ -314,6 +333,15 @@ pub enum EnterPinResult {
ErrorMessage(String), ErrorMessage(String),
} }
impl ATResponse for EnterPinResult {
fn is_error(&self) -> bool {
match self {
EnterPinResult::Ok => false,
_ => true,
}
}
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct EnterPinCommand(pub String); pub struct EnterPinCommand(pub String);
impl ATCommand for EnterPinCommand { impl ATCommand for EnterPinCommand {
@ -343,6 +371,15 @@ pub enum CheckPinResult {
ErrorMessage(String), ErrorMessage(String),
} }
impl ATResponse for CheckPinResult {
fn is_error(&self) -> bool {
match self {
CheckPinResult::Status(_) => false,
_ => true,
}
}
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct CheckPinCommand; pub struct CheckPinCommand;
impl ATCommand for CheckPinCommand { impl ATCommand for CheckPinCommand {
@ -406,6 +443,15 @@ pub enum CheckSMSFormatResult {
Error, Error,
} }
impl ATResponse for CheckSMSFormatResult {
fn is_error(&self) -> bool {
match self {
CheckSMSFormatResult::Mode(_) => false,
_ => true,
}
}
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct CheckSMSFormatCommand; pub struct CheckSMSFormatCommand;
impl ATCommand for CheckSMSFormatCommand { impl ATCommand for CheckSMSFormatCommand {
@ -439,6 +485,14 @@ pub enum TECharacterSets {
Charsets(Vec<String>), Charsets(Vec<String>),
} }
impl ATResponse for TECharacterSets {
fn is_error(&self) -> bool {
match self {
_ => false,
}
}
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct ListTECharacterSetsCommand; pub struct ListTECharacterSetsCommand;
impl ATCommand for ListTECharacterSetsCommand { impl ATCommand for ListTECharacterSetsCommand {
@ -510,6 +564,15 @@ pub enum SendSMSResponse {
ErrorMessage(String), ErrorMessage(String),
} }
impl ATResponse for SendSMSResponse {
fn is_error(&self) -> bool {
match self {
SendSMSResponse::MessageRefrence(_) => false,
_ => true,
}
}
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct SendSMSCommand { pub struct SendSMSCommand {
pub destination: String, pub destination: String,
@ -528,6 +591,11 @@ impl ATCommand for SendSMSCommand {
} }
fn parse_response(parser: &mut ATResponseParser) -> Result<Self::Response, ATParseError> { fn parse_response(parser: &mut ATResponseParser) -> Result<Self::Response, ATParseError> {
if let Ok(_) = parser.expect("+CMS ERROR: ".to_owned()) {
let result = parser.readline().unwrap();
return Ok(SendSMSResponse::ErrorMessage(result));
}
// Read first line out // Read first line out
parser.readline(); parser.readline();

View File

@ -11,7 +11,7 @@ use esp_hal::time::{Duration, Instant};
use crate::{ use crate::{
async_io::{ATPromise, KeypadButton}, async_io::{ATPromise, KeypadButton},
at_commands::{ at_commands::{
ATCommand, ATInformationCommand, CheckPinCommand, EnterPinCommand, SMSFormat, ATCommand, ATInformationCommand, ATResponse, CheckPinCommand, EnterPinCommand, SMSFormat,
SelectSMSFormatCommand, SendSMSCommand, SetTECharsetCommand, TECharset, SelectSMSFormatCommand, SendSMSCommand, SetTECharsetCommand, TECharset,
}, },
display::{Position, Rgb565}, display::{Position, Rgb565},
@ -20,17 +20,23 @@ use crate::{
}; };
#[derive(Clone)] #[derive(Clone)]
pub struct ATCommandState<T: State, Cmd: ATCommand> { pub struct ATCommandState<T: State, TErr: State, Cmd: ATCommand> {
message: String, message: String,
command: Cmd, command: Cmd,
dots: u8, dots: u8,
prev_dots: Instant, prev_dots: Instant,
promise: Option<ATPromise<Cmd>>, promise: Option<ATPromise<Cmd>>,
after_state: T, after_state: T,
err_state: TErr,
} }
impl<T: State + Clone, Cmd: ATCommand> ATCommandState<T, Cmd> { impl<T: State + Clone, TErr: State + Clone, Cmd: ATCommand> ATCommandState<T, TErr, Cmd> {
pub fn with(message: String, command: Cmd, after: T) -> ATCommandState<T, Cmd> { pub fn with(
message: String,
command: Cmd,
after: T,
err: TErr,
) -> ATCommandState<T, TErr, Cmd> {
ATCommandState { ATCommandState {
message, message,
command, command,
@ -38,12 +44,13 @@ impl<T: State + Clone, Cmd: ATCommand> ATCommandState<T, Cmd> {
prev_dots: Instant::now(), prev_dots: Instant::now(),
promise: None, promise: None,
after_state: after, after_state: after,
err_state: err,
} }
} }
} }
impl<T: State + Clone + 'static, Cmd: ATCommand + Clone + 'static> State impl<T: State + Clone + 'static, TErr: State + Clone + 'static, Cmd: ATCommand + Clone + 'static>
for ATCommandState<T, Cmd> State for ATCommandState<T, TErr, Cmd>
{ {
fn init(&mut self, data: &mut StateData) { fn init(&mut self, data: &mut StateData) {
self.promise = Some(data.io.send_at_command(self.command.clone()).unwrap()); self.promise = Some(data.io.send_at_command(self.command.clone()).unwrap());
@ -60,7 +67,13 @@ impl<T: State + Clone + 'static, Cmd: ATCommand + Clone + 'static> State
match promise.poll(&mut data.io) { match promise.poll(&mut data.io) {
Some(response) => match response { Some(response) => match response {
Some(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; self.promise = None;
} }
None => {} None => {}
@ -84,6 +97,7 @@ impl<T: State + Clone + 'static, Cmd: ATCommand + Clone + 'static> State
} }
} }
#[derive(Debug, Clone)]
pub struct InitATState; pub struct InitATState;
impl Default for InitATState { impl Default for InitATState {
@ -112,10 +126,15 @@ impl State for InitATState {
TextState { TextState {
text: "All done!".to_owned(), text: "All done!".to_owned(),
}, },
InitATState::default(),
), ),
InitATState::default(),
), ),
InitATState::default(),
), ),
InitATState::default(),
), ),
InitATState::default(),
); );
Some(Box::new(state)) Some(Box::new(state))
@ -240,6 +259,9 @@ impl State for MessageState {
TextState { TextState {
text: "SMS Sent!".to_owned(), text: "SMS Sent!".to_owned(),
}, },
TextState {
text: "Error!".to_owned(),
},
))) )))
} else { } else {
None None