1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
use heapless::{String, Vec}; use crate::{MaxCommandLen, MaxResponseLines}; use crate::error::Error; /// Trait to be implemented by device driver crates. /// /// # Examples /// /// ``` /// #[derive(Debug, Clone)] /// enum Command { /// AT, /// GetSerialNum, /// GetUMSM, /// GetCSGT, /// SetDefaultPeer { /// peer_id: u8, /// url: String<MaxCommandLen>, /// connect_scheme: u8, /// }, /// } /// #[derive(Debug, Clone, PartialEq)] /// enum Response { /// None, /// SerialNum { serial: String<MaxCommandLen> }, /// UMSM { start_mode: u8 }, /// CSGT { mode: u8, text: String<MaxCommandLen> }, /// // Unsolicited responses /// PeerDisconnected { peer_handle: u8 }, /// } /// impl ATCommandInterface<Response> for Command { /// fn get_cmd(&self) -> String<MaxCommandLen> { /// let mut buffer = String::new(); /// match self { /// Command::AT => String::from("AT"), /// Command::GetUMSM => String::from("AT+UMSM?\r\n"), /// Command::GetCSGT => String::from("AT+CSGT?\r\n"), /// Command::GetSerialNum => String::from("AT+CGSN"), /// Command::SetDefaultPeer { /// ref peer_id, /// ref url, /// ref connect_scheme, /// } => { /// write!( /// buffer, /// "AT+UDDRP={},{},{}", /// peer_id, url, *connect_scheme as u8 /// ) /// .unwrap(); /// buffer /// } /// } /// } /// fn parse_resp(&self, response_lines: &mut Vec<String<MaxCommandLen>, MaxResponseLines>) -> Response { /// if response_lines.is_empty() { /// return Response::None; /// } /// let mut responses: Vec<Vec<&str, MaxResponseLines>, MaxResponseLines> = utils::split_parameterized_resp(response_lines); /// let response = responses.pop().unwrap(); /// match *self { /// Command::AT => Response::None, /// Command::GetUMSM => Response::UMSM { /// start_mode: response[0].parse::<u8>().unwrap(), /// }, /// Command::GetCSGT => Response::CSGT { /// mode: response[0].parse::<u8>().unwrap(), /// text: String::from(response[1]), /// }, /// Command::GetSerialNum => Response::SerialNum { /// serial: String::from(response[0]), /// }, /// Command::SetDefaultPeer { .. } => Response::None, /// } /// } /// fn parse_unsolicited(response_line: &str) -> Response { /// let (cmd, parameters) = utils::split_parameterized_unsolicited(response_line); /// match cmd { /// "+UUDPD" => Response::PeerDisconnected { /// peer_handle: parameters[0].parse::<u8>().unwrap(), /// }, /// _ => Response::None, /// } /// } /// } /// ``` pub trait ATCommandInterface<R> { fn get_cmd(&self) -> String<MaxCommandLen>; fn parse_resp(&self, response_lines: &mut Vec<String<MaxCommandLen>, MaxResponseLines>) -> R; fn parse_unsolicited(response_line: &str) -> R; } pub trait ATInterface<Command, Response> { fn send(&mut self, cmd: Command) -> Result<Response, Error>; fn send_timeout(&mut self, cmd: Command, timeout: u32) -> Result<Response, Error>; // Can these be made using rusts new shiny async/await? fn wait_responses(&mut self, timeout: u32) -> Result<Response, Error>; // fn is_wifi_enabled(&self) -> Result<bool, WifiError>; // /// Turn on the wifi interface of host machine. // fn turn_on(&mut self) -> Result<(), WifiError>; // /// Turn off the wifi interface of host machine. // fn turn_off(&mut self) -> Result<(), WifiError>; }