#![no_std]
#![no_main]
#![allow(dead_code, unused_variables)]
extern crate at_parser_rs;
use at_parser_rs::context::AtContext;
use at_parser_rs::{Args, AtError, AtResult, Bytes};
const SIZE: usize = 64;
pub struct EchoModule {
pub echo: bool,
}
impl AtContext<SIZE> for EchoModule {
fn exec(&self) -> AtResult<SIZE> {
if self.echo {
Ok(Bytes::from_str("ECHO: ON"))
} else {
Ok(Bytes::from_str("ECHO: OFF"))
}
}
fn query(&mut self) -> AtResult<SIZE> {
if self.echo {
Ok(Bytes::from_str("1"))
} else {
Ok(Bytes::from_str("0"))
}
}
fn test(&mut self) -> AtResult<SIZE> {
Ok(Bytes::from_str("Valid values: 0 (OFF), 1 (ON)"))
}
fn set(&mut self, args: Args) -> AtResult<SIZE> {
let value = args.get(0).ok_or(AtError::InvalidArgs)?;
match value {
"0" => {
self.echo = false;
Ok(Bytes::from_str("ECHO OFF"))
}
"1" => {
self.echo = true;
Ok(Bytes::from_str("ECHO ON"))
}
_ => Err(AtError::InvalidArgs),
}
}
}
pub struct ResetModule;
impl AtContext<SIZE> for ResetModule {
fn exec(&self) -> AtResult<SIZE> {
Ok(Bytes::from_str("OK - System reset"))
}
fn test(&mut self) -> AtResult<SIZE> {
Ok(Bytes::from_str("Reset the system"))
}
}
pub struct InfoModule {
pub version: &'static str,
}
impl AtContext<SIZE> for InfoModule {
fn exec(&self) -> AtResult<SIZE> {
Ok(Bytes::from_str(self.version))
}
fn query(&mut self) -> AtResult<SIZE> {
Ok(Bytes::from_str("AT-Parser-RS v1.0.0 - AT Command Parser Library"))
}
}
pub struct LedModule {
pub state: bool,
pub brightness: u8,
}
impl AtContext<SIZE> for LedModule {
fn exec(&self) -> AtResult<SIZE> {
if self.state {
Ok(Bytes::from_str("LED: ON"))
} else {
Ok(Bytes::from_str("LED: OFF"))
}
}
fn query(&mut self) -> AtResult<SIZE> {
if self.state {
Ok(Bytes::from_str("1,100"))
} else {
Ok(Bytes::from_str("0,0"))
}
}
fn test(&mut self) -> AtResult<SIZE> {
Ok(Bytes::from_str("AT+LED=<state>,<brightness> where state: 0|1, brightness: 0-100"))
}
fn set(&mut self, args: Args) -> AtResult<SIZE> {
let state_str = args.get(0).ok_or(AtError::InvalidArgs)?;
self.state = match state_str {
"0" => false,
"1" => true,
_ => return Err(AtError::InvalidArgs),
};
if let Some(brightness_str) = args.get(1) {
self.brightness = brightness_str
.parse::<u8>()
.map_err(|_| AtError::InvalidArgs)?;
if self.brightness > 100 {
return Err(AtError::InvalidArgs);
}
}
if self.state {
Ok(Bytes::from_str("LED ON"))
} else {
Ok(Bytes::from_str("LED OFF"))
}
}
}
fn execute_command(cmd: &str, name: &str, module: &mut dyn AtContext<SIZE>) {
let result = if let Some(rest) = cmd.strip_prefix(name) {
if rest.is_empty() {
module.exec()
} else if rest == "?" {
module.query()
} else if rest == "=?" {
module.test()
} else if let Some(args_str) = rest.strip_prefix('=') {
module.set(Args { raw: args_str })
} else {
Err(AtError::InvalidArgs)
}
} else {
Err(AtError::UnknownCommand)
};
let _ = result;
}
#[unsafe(no_mangle)]
pub extern "C" fn main() -> ! {
let mut echo = EchoModule { echo: false };
let mut reset = ResetModule;
let mut info = InfoModule { version: "v1.0.0" };
let mut led = LedModule { state: false, brightness: 0 };
execute_command("AT+INFO", "AT+INFO", &mut info);
execute_command("AT+INFO?", "AT+INFO", &mut info);
execute_command("AT+ECHO", "AT+ECHO", &mut echo);
execute_command("AT+ECHO=?", "AT+ECHO", &mut echo);
execute_command("AT+ECHO=1", "AT+ECHO", &mut echo);
execute_command("AT+ECHO?", "AT+ECHO", &mut echo);
execute_command("AT+ECHO=0", "AT+ECHO", &mut echo);
execute_command("AT+LED=?", "AT+LED", &mut led);
execute_command("AT+LED=1", "AT+LED", &mut led);
execute_command("AT+LED?", "AT+LED", &mut led);
execute_command("AT+LED=1,75","AT+LED", &mut led);
execute_command("AT+LED=0", "AT+LED", &mut led);
execute_command("AT+RST=?", "AT+RST", &mut reset);
execute_command("AT+RST", "AT+RST", &mut reset);
execute_command("AT+ECHO=2", "AT+ECHO", &mut echo); execute_command("AT+INFO=1", "AT+INFO", &mut info);
loop {}
}