From e34121d5a61fb2105fc1d4e32b07a34d0e2ecf99 Mon Sep 17 00:00:00 2001 From: Sofia Date: Sat, 30 May 2026 18:32:35 +0300 Subject: [PATCH] Parse ATInformation --- src/at_commands.rs | 63 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 12 deletions(-) diff --git a/src/at_commands.rs b/src/at_commands.rs index c05cfdd..99359ec 100644 --- a/src/at_commands.rs +++ b/src/at_commands.rs @@ -134,7 +134,7 @@ impl<'a, 'd> ATCommands<'a, 'd> { if i == 0 { continue; } - response.push(line); + response.push(line.trim().to_string()); let mut parser = ATResponseParser::from(response.clone()); @@ -150,13 +150,10 @@ impl<'a, 'd> ATCommands<'a, 'd> { } return Some(output_lines); } - Err(err) => { - log::info!("{:?}", err); - match err { - ATParseError::EOF => {} - ATParseError::InvalidResponse => panic!("Invalid response"), - } - } + Err(err) => match err { + ATParseError::EOF => {} + ATParseError::InvalidResponse => panic!("Invalid response"), + }, } } } @@ -190,6 +187,7 @@ impl<'a, 'd> ATCommands<'a, 'd> { } pub struct ATResponseParser { + curr_line: Option, text: Vec, index: usize, lines: usize, @@ -198,19 +196,38 @@ pub struct ATResponseParser { impl ATResponseParser { pub fn from(text: Vec) -> ATResponseParser { ATResponseParser { + curr_line: None, text, index: 0, lines: 0, } } - pub fn readline<'s>(&'s mut self) -> Option<&'s String> { + pub fn readline(&mut self) -> Option { + if let Some(curr_line) = self.curr_line.take() { + return Some(curr_line); + } let result = self.text.get(self.index); self.index += 1; if let Some(_) = result { self.lines += 1; } - result + result.cloned() + } + + pub fn expect(&mut self, text: String) -> Result<(), ATParseError> { + let line = if let Some(curr_line) = self.curr_line.take() { + curr_line + } else { + self.readline().ok_or(ATParseError::EOF)? + }; + + if let Some(text) = line.strip_prefix(&text) { + self.curr_line = Some(text.to_string()); + Ok(()) + } else { + Err(ATParseError::InvalidResponse) + } } } @@ -242,19 +259,41 @@ impl SimpleATCommand for T { } } +#[derive(Debug, Clone)] +pub struct ATInformation { + manufacturer: String, + model: String, + revision: String, + imei: String, +} + #[derive(Debug, Clone)] pub struct ATInformationCommand; impl ATCommand for ATInformationCommand { - type Response = String; + type Response = ATInformation; fn execute(&self, at_commands: &mut ATCommands) -> Vec { at_commands.raw_command(self, "ATI".to_string()) } fn parse_response(parser: &mut ATResponseParser) -> Result { + parser.expect("Manufacturer: ".to_string())?; + let manufacturer = parser.readline().unwrap(); + parser.expect("Model: ".to_string())?; + let model = parser.readline().unwrap(); + parser.expect("Revision: ".to_string())?; + let revision = parser.readline().unwrap(); + parser.expect("IMEI: ".to_string())?; + let imei = parser.readline().unwrap(); + while let Some(line) = parser.readline() { if line.starts_with("OK") { - return Ok("OK".to_owned()); + return Ok(ATInformation { + manufacturer, + model, + revision, + imei, + }); } } Err(ATParseError::EOF)