use crate::at_command::{AtRequest, AtResponse};
use crate::{at_command, AtError, BUFFER_SIZE, ERROR_TERMINATOR, OK_TERMINATOR};
use embedded_io_async::{Read, Write};
use crate::at_command::cmee::ReportMobileEquipmentErrorSetting;
#[cfg(feature = "defmt")]
use defmt::*;
#[cfg(feature = "defmt")]
use embedded_io::Error;
use log::error;
pub struct AsyncModem<T: Write, U: Read> {
pub writer: T,
pub reader: U,
}
impl<'a, T: Write, U: Read> AsyncModem<T, U> {
pub async fn new(writer: T, reader: U) -> Result<Self, AtError> {
let mut modem = Self { writer, reader };
modem.disable_echo().await?;
Ok(modem)
}
async fn disable_echo(&mut self) -> Result<AtResponse, AtError> {
self.send_and_wait_reply(at_command::ate::AtEcho {
status: at_command::ate::Echo::Disable,
})
.await
}
pub async fn verbosity(
&mut self,
verbosity: ReportMobileEquipmentErrorSetting,
) -> Result<AtResponse, AtError> {
self.send_and_wait_reply(at_command::cmee::SetReportMobileEquipmentError {
setting: verbosity,
})
.await
}
pub async fn send_and_wait_reply<V: AtRequest + 'a>(
&'a mut self,
payload: V,
) -> Result<AtResponse, crate::AtError> {
let mut buffer = [0; BUFFER_SIZE];
let data = payload.get_command_no_error(&mut buffer);
#[cfg(feature = "defmt")]
debug!("payload: {=[u8]:a}", &data);
self.writer.write(data).await.unwrap();
match self.read_response(&mut buffer).await {
Ok(response_size) => {
#[cfg(feature = "defmt")]
debug!("received response: {=[u8]:a}", buffer[..response_size]);
let response = payload.parse_response(&buffer);
#[cfg(feature = "defmt")]
debug!("parsed response: {}", response);
response
}
Err(at_error) => {
match at_error {
AtError::ErrorReply(response_size) => {
#[cfg(feature = "defmt")]
debug!("received response: {=[u8]:a}", buffer[..response_size]);
}
_ => {
#[cfg(feature = "defmt")]
debug!("error: {:?}", at_error);
}
}
Err(at_error)
}
}
}
pub async fn read_next_response(&mut self) -> Result<AtResponse, crate::AtError> {
let mut buffer = [0; BUFFER_SIZE];
#[cfg(feature = "defmt")]
let response_size = self.read_response(&mut buffer).await?;
#[cfg(feature = "defmt")]
debug!("received response: {=[u8]:a}", buffer[..response_size]);
Ok(AtResponse::Ok)
}
async fn read_response(
&mut self,
response_out: &mut [u8; BUFFER_SIZE],
) -> Result<usize, crate::AtError> {
let mut offset = 0_usize;
let mut read_buffer: [u8; 10] = [0; 10];
loop {
match self.reader.read(&mut read_buffer).await {
Ok(num_bytes) => {
for i in 0..num_bytes {
response_out[offset + i] = read_buffer[i];
if offset + i < 5 {
continue;
}
let start = offset + i - 5;
let stop = offset + i + 1;
match &response_out[start..stop] {
OK_TERMINATOR => return Ok(offset + i),
ERROR_TERMINATOR => return Err(AtError::ErrorReply(offset + i)),
_ => continue,
}
}
offset += num_bytes;
}
Err(e) => {
#[cfg(feature = "defmt")]
error!("no data: {:?}", e.kind());
}
}
}
}
}