Skip to content

Commit

Permalink
Remove length const generic on AtatCmd
Browse files Browse the repository at this point in the history
  • Loading branch information
rmja committed Dec 7, 2023
1 parent aac2c2f commit bc7b0d4
Show file tree
Hide file tree
Showing 10 changed files with 102 additions and 102 deletions.
3 changes: 3 additions & 0 deletions atat/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ defmt = { version = "^0.3", optional = true }
[dev-dependencies]
embassy-time = { version = "0.2", features = ["std", "generic-queue"] }
critical-section = { version = "1.1", features = ["std"] }
serde_at = { path = "../serde_at", version = "^0.20.0", features = [
"heapless",
] }
tokio = { version = "1", features = ["macros", "rt"] }

[features]
Expand Down
39 changes: 21 additions & 18 deletions atat/src/asynch/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,40 +14,43 @@ pub struct Client<'a, W: Write, const INGRESS_BUF_SIZE: usize> {
res_channel: &'a ResponseChannel<INGRESS_BUF_SIZE>,
config: Config,
cooldown_timer: Option<Timer>,
buf: &'a mut [u8],
}

impl<'a, W: Write, const INGRESS_BUF_SIZE: usize> Client<'a, W, INGRESS_BUF_SIZE> {
pub fn new(
writer: W,
res_channel: &'a ResponseChannel<INGRESS_BUF_SIZE>,
config: Config,
buf: &'a mut [u8],
) -> Self {
Self {
writer,
res_channel,
config,
cooldown_timer: None,
buf,
}
}

async fn send_command(&mut self, cmd: &[u8]) -> Result<(), Error> {
async fn send_command(&mut self, len: usize) -> Result<(), Error> {
self.wait_cooldown_timer().await;

self.send_inner(cmd).await?;
self.send_inner(len).await?;

self.start_cooldown_timer();
Ok(())
}

async fn send_request(
&mut self,
cmd: &[u8],
len: usize,
timeout: Duration,
) -> Result<Response<INGRESS_BUF_SIZE>, Error> {
self.wait_cooldown_timer().await;

let mut response_subscription = self.res_channel.subscriber().unwrap();
self.send_inner(cmd).await?;
self.send_inner(len).await?;

let response = self
.with_timeout(timeout, response_subscription.next_message_pure())
Expand All @@ -58,14 +61,17 @@ impl<'a, W: Write, const INGRESS_BUF_SIZE: usize> Client<'a, W, INGRESS_BUF_SIZE
response
}

async fn send_inner(&mut self, cmd: &[u8]) -> Result<(), Error> {
if cmd.len() < 50 {
debug!("Sending command: {:?}", LossyStr(cmd));
async fn send_inner(&mut self, len: usize) -> Result<(), Error> {
if len < 50 {
debug!("Sending command: {:?}", LossyStr(&self.buf[..len]));
} else {
debug!("Sending command with long payload ({} bytes)", cmd.len(),);
debug!("Sending command with long payload ({} bytes)", len);
}

self.writer.write_all(cmd).await.map_err(|_| Error::Write)?;
self.writer
.write_all(&self.buf[..len])
.await
.map_err(|_| Error::Write)?;
self.writer.flush().await.map_err(|_| Error::Write)?;
Ok(())
}
Expand Down Expand Up @@ -107,18 +113,14 @@ impl<'a, W: Write, const INGRESS_BUF_SIZE: usize> Client<'a, W, INGRESS_BUF_SIZE
}

impl<W: Write, const INGRESS_BUF_SIZE: usize> AtatClient for Client<'_, W, INGRESS_BUF_SIZE> {
async fn send<Cmd: AtatCmd<LEN>, const LEN: usize>(
&mut self,
cmd: &Cmd,
) -> Result<Cmd::Response, Error> {
let cmd_vec = cmd.as_bytes();
let cmd_slice = cmd.get_slice(&cmd_vec);
async fn send<'a, Cmd: AtatCmd>(&'a mut self, cmd: &'a Cmd) -> Result<Cmd::Response, Error> {
let len = cmd.write(&mut self.buf);
if !Cmd::EXPECTS_RESPONSE_CODE {
self.send_command(cmd_slice).await?;
self.send_command(len).await?;
cmd.parse(Ok(&[]))
} else {
let response = self
.send_request(cmd_slice, Duration::from_millis(Cmd::MAX_TIMEOUT_MS.into()))
.send_request(len, Duration::from_millis(Cmd::MAX_TIMEOUT_MS.into()))
.await?;
cmd.parse((&response).into())
}
Expand Down Expand Up @@ -179,10 +181,11 @@ mod tests {
static TX_CHANNEL: PubSubChannel<CriticalSectionRawMutex, String<64>, 1, 1, 1> =
PubSubChannel::new();
static RES_CHANNEL: ResponseChannel<TEST_RX_BUF_LEN> = ResponseChannel::new();
static mut BUF: [u8; 1000] = [0; 1000];

let tx_mock = crate::tx_mock::TxMock::new(TX_CHANNEL.publisher().unwrap());
let client: Client<crate::tx_mock::TxMock, TEST_RX_BUF_LEN> =
Client::new(tx_mock, &RES_CHANNEL, $config);
Client::new(tx_mock, &RES_CHANNEL, $config, unsafe { BUF.as_mut() });
(
client,
TX_CHANNEL.subscriber().unwrap(),
Expand Down
11 changes: 4 additions & 7 deletions atat/src/asynch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,11 @@ pub trait AtatClient {
/// This function will also make sure that at least `self.config.cmd_cooldown`
/// has passed since the last response or URC has been received, to allow
/// the slave AT device time to deliver URC's.
async fn send<Cmd: AtatCmd<LEN>, const LEN: usize>(
&mut self,
cmd: &Cmd,
) -> Result<Cmd::Response, Error>;
async fn send<'a, Cmd: AtatCmd>(&'a mut self, cmd: &'a Cmd) -> Result<Cmd::Response, Error>;

async fn send_retry<Cmd: AtatCmd<LEN>, const LEN: usize>(
&mut self,
cmd: &Cmd,
async fn send_retry<'a, Cmd: AtatCmd>(
&'a mut self,
cmd: &'a Cmd,
) -> Result<Cmd::Response, Error> {
for attempt in 1..=Cmd::ATTEMPTS {
if attempt > 1 {
Expand Down
38 changes: 20 additions & 18 deletions atat/src/blocking/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ where
res_channel: &'a ResponseChannel<INGRESS_BUF_SIZE>,
cooldown_timer: Option<BlockingTimer>,
config: Config,
buf: &'a mut [u8],
}

impl<'a, W, const INGRESS_BUF_SIZE: usize> Client<'a, W, INGRESS_BUF_SIZE>
Expand All @@ -29,33 +30,35 @@ where
writer: W,
res_channel: &'a ResponseChannel<INGRESS_BUF_SIZE>,
config: Config,
buf: &'a mut [u8],
) -> Self {
Self {
writer,
res_channel,
cooldown_timer: None,
config,
buf,
}
}

fn send_command(&mut self, cmd: &[u8]) -> Result<(), Error> {
fn send_command(&mut self, len: usize) -> Result<(), Error> {
self.wait_cooldown_timer();

self.send_inner(cmd)?;
self.send_inner(len)?;

self.start_cooldown_timer();
Ok(())
}

fn send_request(
&mut self,
cmd: &[u8],
len: usize,
timeout: Duration,
) -> Result<Response<INGRESS_BUF_SIZE>, Error> {
self.wait_cooldown_timer();

let mut response_subscription = self.res_channel.subscriber().unwrap();
self.send_inner(cmd)?;
self.send_inner(len)?;

let response = self
.with_timeout(timeout, || response_subscription.try_next_message_pure())
Expand All @@ -65,14 +68,16 @@ where
response
}

fn send_inner(&mut self, cmd: &[u8]) -> Result<(), Error> {
if cmd.len() < 50 {
debug!("Sending command: {:?}", LossyStr(cmd));
fn send_inner(&mut self, len: usize) -> Result<(), Error> {
if len < 50 {
debug!("Sending command: {:?}", LossyStr(&self.buf[..len]));
} else {
debug!("Sending command with long payload ({} bytes)", cmd.len(),);
debug!("Sending command with long payload ({} bytes)", len,);
}

self.writer.write_all(cmd).map_err(|_| Error::Write)?;
self.writer
.write_all(&self.buf[..len])
.map_err(|_| Error::Write)?;
self.writer.flush().map_err(|_| Error::Write)?;
Ok(())
}
Expand Down Expand Up @@ -109,18 +114,14 @@ impl<W, const INGRESS_BUF_SIZE: usize> AtatClient for Client<'_, W, INGRESS_BUF_
where
W: Write,
{
fn send<Cmd: AtatCmd<LEN>, const LEN: usize>(
&mut self,
cmd: &Cmd,
) -> Result<Cmd::Response, Error> {
let cmd_vec = cmd.as_bytes();
let cmd_slice = cmd.get_slice(&cmd_vec);
fn send<Cmd: AtatCmd>(&mut self, cmd: &Cmd) -> Result<Cmd::Response, Error> {
let len = cmd.write(&mut self.buf);
if !Cmd::EXPECTS_RESPONSE_CODE {
self.send_command(cmd_slice)?;
self.send_command(len)?;
cmd.parse(Ok(&[]))
} else {
let response =
self.send_request(cmd_slice, Duration::from_millis(Cmd::MAX_TIMEOUT_MS.into()))?;
self.send_request(len, Duration::from_millis(Cmd::MAX_TIMEOUT_MS.into()))?;
cmd.parse((&response).into())
}
}
Expand Down Expand Up @@ -263,10 +264,11 @@ mod test {
static TX_CHANNEL: PubSubChannel<CriticalSectionRawMutex, String<64>, 1, 1, 1> =
PubSubChannel::new();
static RES_CHANNEL: ResponseChannel<TEST_RX_BUF_LEN> = ResponseChannel::new();
static mut BUF: [u8; 1000] = [0; 1000];

let tx_mock = crate::tx_mock::TxMock::new(TX_CHANNEL.publisher().unwrap());
let client: Client<crate::tx_mock::TxMock, TEST_RX_BUF_LEN> =
Client::new(tx_mock, &RES_CHANNEL, $config);
Client::new(tx_mock, &RES_CHANNEL, $config, unsafe { BUF.as_mut() });
(
client,
TX_CHANNEL.subscriber().unwrap(),
Expand Down
7 changes: 2 additions & 5 deletions atat/src/blocking/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,9 @@ pub trait AtatClient {
/// This function will also make sure that at least `self.config.cmd_cooldown`
/// has passed since the last response or URC has been received, to allow
/// the slave AT device time to deliver URC's.
fn send<A: AtatCmd<LEN>, const LEN: usize>(&mut self, cmd: &A) -> Result<A::Response, Error>;
fn send<A: AtatCmd>(&mut self, cmd: &A) -> Result<A::Response, Error>;

fn send_retry<A: AtatCmd<LEN>, const LEN: usize>(
&mut self,
cmd: &A,
) -> Result<A::Response, Error> {
fn send_retry<A: AtatCmd>(&mut self, cmd: &A) -> Result<A::Response, Error> {
for attempt in 1..=A::ATTEMPTS {
if attempt > 1 {
debug!("Attempt {}:", attempt);
Expand Down
18 changes: 10 additions & 8 deletions atat/src/buffers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,30 +38,32 @@ impl<
> Buffers<Urc, INGRESS_BUF_SIZE, URC_CAPACITY, URC_SUBSCRIBERS>
{
#[cfg(feature = "async")]
pub fn split<W: embedded_io_async::Write, D: Digester>(
&self,
pub fn split<'a, W: embedded_io_async::Write, D: Digester>(
&'a self,
writer: W,
digester: D,
config: Config,
buf: &'a mut [u8],
) -> (
Ingress<D, Urc, INGRESS_BUF_SIZE, URC_CAPACITY, URC_SUBSCRIBERS>,
crate::asynch::Client<W, INGRESS_BUF_SIZE>,
Ingress<'a, D, Urc, INGRESS_BUF_SIZE, URC_CAPACITY, URC_SUBSCRIBERS>,
crate::asynch::Client<'a, W, INGRESS_BUF_SIZE>,
) {
(
Ingress::new(
digester,
self.res_channel.publisher().unwrap(),
self.urc_channel.publisher(),
),
crate::asynch::Client::new(writer, &self.res_channel, config),
crate::asynch::Client::new(writer, &self.res_channel, config, buf),
)
}

pub fn split_blocking<W: Write, D: Digester>(
&self,
pub fn split_blocking<'a, W: Write, D: Digester>(
&'a self,
writer: W,
digester: D,
config: Config,
buf: &'a mut [u8],
) -> (
Ingress<D, Urc, INGRESS_BUF_SIZE, URC_CAPACITY, URC_SUBSCRIBERS>,
crate::blocking::Client<W, INGRESS_BUF_SIZE>,
Expand All @@ -72,7 +74,7 @@ impl<
self.res_channel.publisher().unwrap(),
self.urc_channel.publisher(),
),
crate::blocking::Client::new(writer, &self.res_channel, config),
crate::blocking::Client::new(writer, &self.res_channel, config, buf),
)
}
}
24 changes: 13 additions & 11 deletions atat/src/derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,18 +204,20 @@ mod tests {

#[test]
fn test_length_serialize() {
let mut buf = [0; 360];
let len = LengthTester {
x: 8,
y: String::try_from("SomeString").unwrap(),
z: 2,
w: "whatup",
a: SimpleEnum::A,
b: SimpleEnumU32::A,
c: SimpleEnumU32::B,
// d: Vec::new()
}
.write(&mut buf);
assert_eq!(
LengthTester {
x: 8,
y: String::try_from("SomeString").unwrap(),
z: 2,
w: "whatup",
a: SimpleEnum::A,
b: SimpleEnumU32::A,
c: SimpleEnumU32::B,
// d: Vec::new()
}
.as_bytes(),
&buf[..len],
Vec::<u8, 360>::from_slice(b"AT+CFUN=8,\"SomeString\",2,\"whatup\",0,0,1\r\n").unwrap()
);
}
Expand Down
18 changes: 11 additions & 7 deletions atat/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,25 +35,29 @@
//!
//! impl AtatResp for GreetingText {};
//!
//! impl<'a> AtatCmd<64> for SetGreetingText<'a> {
//! impl<'a> AtatCmd for SetGreetingText<'a> {
//! type Response = NoResponse;
//!
//! fn as_bytes(&self) -> Vec<u8, 64> {
//! let mut buf: Vec<u8, 64> = Vec::new();
//! fn write(&self, mut buf: &mut [u8]) -> usize {
//! let buf_len = buf.len();
//! use embedded_io::Write;
//! write!(buf, "AT+CSGT={}", self.text);
//! buf
//! buf_len - buf.len()
//! }
//!
//! fn parse(&self, resp: Result<&[u8], InternalError>) -> Result<Self::Response, Error> {
//! Ok(NoResponse)
//! }
//! }
//!
//! impl AtatCmd<8> for GetGreetingText {
//! impl AtatCmd for GetGreetingText {
//! type Response = GreetingText;
//!
//! fn as_bytes(&self) -> Vec<u8, 8> {
//! Vec::from_slice(b"AT+CSGT?").unwrap()
//! fn write(&self, mut buf: &mut [u8]) -> usize {
//! let cmd = b"AT+CSGT?";
//! let len = cmd.len();
//! buf[..len].copy_from_slice(cmd);
//! len
//! }
//!
//! fn parse(&self, resp: Result<&[u8], InternalError>) -> Result<Self::Response, Error> {
Expand Down
Loading

0 comments on commit bc7b0d4

Please sign in to comment.