read_line now returns String instead of Result<string>
maybe a worse interface than before ... will be revisited
This commit is contained in:
parent
a408544e4e
commit
626c47c58f
1 changed files with 30 additions and 38 deletions
68
src/modem.rs
68
src/modem.rs
|
@ -19,7 +19,7 @@ pub struct Modem<UART: serial::Uart> {
|
|||
pub enum ModemError {
|
||||
CommandError(String),
|
||||
SetupError(String),
|
||||
ReadError,
|
||||
SendDataError,
|
||||
TimeoutError,
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,11 @@ impl<UART: serial::Uart> IterableRx<UART> {
|
|||
self.timeout = timeout;
|
||||
self
|
||||
}
|
||||
|
||||
fn clear(&mut self) -> () {
|
||||
println!("clearing serial rx");
|
||||
self.reset(Duration::from_millis(500)).for_each(drop);
|
||||
}
|
||||
}
|
||||
|
||||
impl<UART: serial::Uart> Iterator for IterableRx<UART> {
|
||||
|
@ -114,23 +119,11 @@ impl<UART: serial::Uart> Modem<UART> {
|
|||
|
||||
/// Reads a whole line (that ends with \\n) within the given `timeout` passed on input.
|
||||
///
|
||||
fn read_line(&mut self, timeout: Duration) -> Result<String> {
|
||||
let line: String = self.rx.reset(timeout)
|
||||
fn read_line(&mut self, timeout: Duration) -> String {
|
||||
self.rx.reset(timeout)
|
||||
.map(|b| char::from(b))
|
||||
.take_while(|c| *c != '\n')
|
||||
.collect();
|
||||
|
||||
// A necessary check because the actual timeout is in the Iterator implementation. The
|
||||
// iterator exits when the returned Item is None, which happens when there's no data in
|
||||
// the serial port and the timeout is breached.
|
||||
//
|
||||
// This check here is tested on sim800l and works only because the modem has \r\n as CRLF.
|
||||
if line.ends_with("\r") {
|
||||
Ok(format!("{}\n", line))
|
||||
}
|
||||
else {
|
||||
Err(ModemError::ReadError)
|
||||
}
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Reads the serial RX until a \\n char is encoutered, or a timeout is reached. The timeout is
|
||||
|
@ -145,8 +138,8 @@ impl<UART: serial::Uart> Modem<UART> {
|
|||
let match_text: String = contains.unwrap_or("\n".to_string());
|
||||
|
||||
loop {
|
||||
let rdln = self.read_line(timeout.saturating_sub(start.elapsed()));
|
||||
if let Ok(line) = rdln {
|
||||
let line = self.read_line(timeout.saturating_sub(start.elapsed()));
|
||||
if line != "" {
|
||||
println!("Read {} bytes from serial ({})", line.len(), line);
|
||||
response.push_str(&line);
|
||||
if line.contains("ERROR") || line.contains(&match_text) {
|
||||
|
@ -156,7 +149,7 @@ impl<UART: serial::Uart> Modem<UART> {
|
|||
}
|
||||
} else {
|
||||
println!("-----------------------------------------------------------");
|
||||
println!("Read line {:?}", rdln);
|
||||
println!("got empty line from read_line :(");
|
||||
break Err(ModemError::TimeoutError)
|
||||
}
|
||||
}
|
||||
|
@ -168,39 +161,42 @@ impl<UART: serial::Uart> Modem<UART> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn send_bytes(&mut self, payload: &[u8]) -> Result<()> {
|
||||
fn send_bytes(&mut self, payload: &[u8], eos: char) -> Result<()> {
|
||||
for b in payload.iter() {
|
||||
self.send(*b)?;
|
||||
}
|
||||
self.send('\r' as u8)?;
|
||||
self.send(eos as u8)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn send_command(&mut self, cmd: Command) -> Result<String> {
|
||||
println!("-----------------------------------------------------------");
|
||||
println!("Sending {} ...", cmd.text);
|
||||
let _ = self.send_bytes(cmd.text.as_bytes())?;
|
||||
let _ = self.send_bytes(cmd.text.as_bytes(), '\r')?;
|
||||
self.read_response(cmd.contains, cmd.timeout)
|
||||
}
|
||||
|
||||
fn send_data(&mut self, payload: &str) -> Result<String> {
|
||||
let _ = self.send_bytes("AT+CIPSEND".as_bytes())?;
|
||||
for c in self.rx.reset(Duration::from_millis(2000)).map(char::from) {
|
||||
println!("{}", c);
|
||||
if c == '>' {
|
||||
for b in payload.as_bytes() {
|
||||
self.send(*b)?;
|
||||
self.rx.clear();
|
||||
let _ = self.send_bytes("AT+CIPSEND".as_bytes(), '\r')?;
|
||||
let send_request: String = self.rx.reset(Duration::from_millis(3000))
|
||||
.map(char::from)
|
||||
.take_while(|c| *c != '>').collect();
|
||||
|
||||
if send_request == "" {
|
||||
return Err(ModemError::SendDataError);
|
||||
}
|
||||
self.send(26)?;
|
||||
return self.read_response(Some("DATA ACCEPT".to_string()), Duration::from_millis(3000));
|
||||
}
|
||||
}
|
||||
self.send_command(Command {
|
||||
|
||||
self.send_bytes(payload.as_bytes(), 26 as char)?; // 26_u8 = Ctrl+z - to end sending data
|
||||
let _ = self.read_response(Some("DATA ACCEPT".to_string()), Duration::from_millis(3000));
|
||||
|
||||
self.rx.clear();
|
||||
let res = self.send_command(Command {
|
||||
text: "AT+CIPACK".to_string(),
|
||||
contains: Some("OK".to_string()),
|
||||
timeout: Duration::from_millis(3000),
|
||||
})?;
|
||||
Ok("OK".to_string())
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
pub fn get_ip_addr(&mut self) -> Result<String> {
|
||||
|
@ -223,10 +219,6 @@ impl<UART: serial::Uart> Modem<UART> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn probe(&mut self)-> Result<String> {
|
||||
self.send_command(Command::probe())
|
||||
}
|
||||
|
||||
pub fn is_gprs_attached(&mut self)-> Result<bool> {
|
||||
let res = self.send_command(Command::is_gprs_attached())?;
|
||||
Ok(res.contains("+CGATT: 1"))
|
||||
|
|
Loading…
Add table
Reference in a new issue