diff --git a/src/codec/command.rs b/src/codec/command.rs index a13860e..e680dd4 100644 --- a/src/codec/command.rs +++ b/src/codec/command.rs @@ -1,49 +1,61 @@ +use crate::codec::misc::Backlight; + #[derive(Clone, Copy, Debug, strum::IntoStaticStr)] #[strum(serialize_all = "UPPERCASE")] pub enum Command { - /// Get current talkgroup ID status - Gid, - /// Power OFF - Pof, - /// Get status - Sts, - /// Get model info - Mdl, - /// Get firmware version - Ver, - + // Program control mode /// Enter program mode Prg, /// Exit program mode Epg, + // System information + /// Get model info + Mdl, + /// Get firmware version + Ver, + + // System settings /// Get/set backlight - Blt, // TODO: optional param + Blt(Option), /// Get/set battery save - Bsv, // TODO: optional param + Bsv(Option), /// Clear all memory /// /// Takes about 20 seconds to execute Clr, + /// Get/set band plan + Bpl, /// Get/set key beep Kbp, // TODO: optional param - /// Get/set opening message - Oms, // TODO: optional param /// Get/set priority mode Pri, // TODO: optional param - /// Get/set auto gain control - Agv, // TODO: optional param - /// Get/set bar antenna - Bar, // TODO: optional param - - /// Get system count - Sct, - /// Get system index head - Sih, - /// Get system index tail - Sit, - - /// Get/set quick lockout - Qsl, // TODO: optional params - Vol, + + // Scan Settings + // Scg, + // Dch, + // Cin, + + // Search/close call settings + // Sco + // Glf + // Ulf + // Lof + // Clc + + // Service/custom search settings + // Ssg + // Csg + // Csp + + // Wxs + // Cnt + // Vol + // Sql + + // undocumented? + /// Power OFF + Pof, + /// Get status + Sts, } diff --git a/src/codec/misc.rs b/src/codec/misc.rs new file mode 100644 index 0000000..dfe493d --- /dev/null +++ b/src/codec/misc.rs @@ -0,0 +1,13 @@ +#[derive(Clone, Copy, Debug, strum::IntoStaticStr, strum::EnumString)] +pub enum Backlight { + #[strum(to_string = "IF")] + Infinite, + #[strum(to_string = "10")] + Sec10, + #[strum(to_string = "30")] + Sec30, + #[strum(to_string = "KY")] + Keypress, + #[strum(to_string = "SQ")] + Squelch, +} diff --git a/src/codec/mod.rs b/src/codec/mod.rs index 4ed8fa0..ed5a839 100644 --- a/src/codec/mod.rs +++ b/src/codec/mod.rs @@ -1,9 +1,13 @@ mod command; +mod misc; + +use std::fmt::Write; use bytes::BufMut; use tokio_util::codec::{AnyDelimiterCodec, Decoder, Encoder}; pub use command::Command; +pub use misc::Backlight; #[derive(Clone, Debug)] pub struct Codec { @@ -33,8 +37,32 @@ impl Encoder for Codec { let cmd: &'static str = item.into(); dst.extend_from_slice(cmd.as_bytes()); + + match item { + Command::Blt(Some(backlight)) => { + let backlight: &'static str = backlight.into(); + dst.reserve(1 + backlight.len()); // 1 for the comma, the rest for the arg + dst.put_u8(b','); + dst.extend_from_slice(backlight.as_bytes()) + } + Command::Bsv(Some(battery_save)) => { + dst.reserve(2); + /* + if battery_save { + dst.extend_from_slice(b",1"); + } else { + dst.extend_from_slice(b",0"); + } + */ + write!(dst, ",{battery_save}").unwrap(); + } + _ => (), + } + dst.put_u8(b'\r'); + // dbg!(String::from_utf8_lossy(dst)); + Ok(()) } } diff --git a/src/lib.rs b/src/lib.rs index 0faadba..396fe44 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,7 +8,7 @@ use tokio_util::codec::{AnyDelimiterCodecError, Framed}; use crate::codec::Codec; -pub use crate::codec::Command; +pub use crate::codec::{Backlight, Command}; const VENDOR_ID: u16 = 0x1965; const PRODUCT_ID: u16 = 0x0017; @@ -56,6 +56,11 @@ impl Scanner { Ok(Self(framed)) } + pub async fn response(&mut self) -> Result { + let r = self.0.next().await.ok_or(Error::PortClosed)??; + Ok(r) + } + pub async fn command(&mut self, cmd: Command) -> Result { self.0.send(cmd).await?; let r = self.0.next().await.ok_or(Error::PortClosed)??; diff --git a/src/main.rs b/src/main.rs index 8b0e115..3bc68f6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -use uniden::{Command, Scanner}; +use uniden::{Backlight, Command, Scanner}; #[tokio::main] async fn main() -> Result<(), Box> { @@ -7,7 +7,9 @@ async fn main() -> Result<(), Box> { dbg!(scanner.firmware_version().await?); dbg!(scanner.command(Command::Prg).await?); // tokio::time::sleep(tokio::time::Duration::from_millis(1000)).await; - dbg!(scanner.command(Command::Blt).await?); + dbg!(scanner.command(Command::Bsv(None)).await?); + dbg!(scanner.command(Command::Bsv(Some(4))).await?); + dbg!(scanner.command(Command::Bsv(None)).await?); dbg!(scanner.command(Command::Epg).await?); Ok(()) }