kenwood_thd75/radio/
memory.rs1use crate::error::{Error, ProtocolError};
4use crate::protocol::{Command, Response};
5use crate::transport::Transport;
6use crate::types::ChannelMemory;
7
8use super::Radio;
9
10impl<T: Transport> Radio<T> {
11 pub async fn read_channel(&mut self, channel: u16) -> Result<ChannelMemory, Error> {
17 tracing::debug!(channel, "reading memory channel");
18 let response = self.execute(Command::GetMemoryChannel { channel }).await?;
19 match response {
20 Response::MemoryChannel { data, .. } => Ok(data),
21 other => Err(Error::Protocol(ProtocolError::UnexpectedResponse {
22 expected: "MemoryChannel".into(),
23 actual: format!("{other:?}").into_bytes(),
24 })),
25 }
26 }
27
28 pub async fn read_channels(
38 &mut self,
39 range: std::ops::Range<u16>,
40 ) -> Result<Vec<(u16, ChannelMemory)>, Error> {
41 tracing::debug!(
42 start = range.start,
43 end = range.end,
44 "reading memory channels"
45 );
46 let mut results = Vec::new();
47 for ch in range {
48 match self.read_channel(ch).await {
49 Ok(data) => {
50 if data.rx_frequency.as_hz() != 0 {
52 results.push((ch, data));
53 }
54 }
55 Err(Error::NotAvailable) => {
56 }
58 Err(e) => return Err(e),
59 }
60 }
61 Ok(results)
62 }
63
64 pub async fn write_channel(&mut self, channel: u16, data: &ChannelMemory) -> Result<(), Error> {
70 tracing::info!(channel, "writing memory channel");
71 let response = self
72 .execute(Command::SetMemoryChannel {
73 channel,
74 data: data.clone(),
75 })
76 .await?;
77 match response {
78 Response::MemoryChannel { .. } => Ok(()),
79 other => Err(Error::Protocol(ProtocolError::UnexpectedResponse {
80 expected: "MemoryChannel".into(),
81 actual: format!("{other:?}").into_bytes(),
82 })),
83 }
84 }
85}
86
87#[cfg(test)]
88mod tests {
89 use super::*;
90 use crate::transport::MockTransport;
91
92 const ME_RESP_005: &[u8] =
94 b"ME 005,0440000000,0005000000,5,2,0,0,0,0,0,0,0,0,0,0,08,08,000,0,,0,00,0\r";
95
96 #[tokio::test]
97 async fn read_channels_returns_populated() {
98 let mut mock = MockTransport::new();
99 mock.expect(b"ME 000\r", b"N\r");
101 mock.expect(
103 b"ME 001\r",
104 b"ME 001,0146520000,0000600000,5,0,0,0,0,0,0,0,0,0,0,0,08,08,000,0,,0,00,0\r",
105 );
106 mock.expect(b"ME 002\r", b"N\r");
108
109 let mut radio = Radio::connect(mock).await.unwrap();
110 let channels = radio.read_channels(0..3).await.unwrap();
111 assert_eq!(channels.len(), 1);
112 assert_eq!(channels[0].0, 1);
113 assert_eq!(channels[0].1.rx_frequency.as_hz(), 146_520_000);
114 }
115
116 #[tokio::test]
117 async fn read_channels_empty_range() {
118 let mock = MockTransport::new();
119 let mut radio = Radio::connect(mock).await.unwrap();
120 let channels = radio.read_channels(0..0).await.unwrap();
121 assert!(channels.is_empty());
122 }
123
124 #[tokio::test]
125 async fn read_channel_populated() {
126 let mut mock = MockTransport::new();
127 mock.expect(b"ME 005\r", ME_RESP_005);
128 let mut radio = Radio::connect(mock).await.unwrap();
129 let data = radio.read_channel(5).await.unwrap();
130 assert_eq!(data.rx_frequency.as_hz(), 440_000_000);
131 }
132
133 #[tokio::test]
134 async fn read_channel_not_available() {
135 let mut mock = MockTransport::new();
136 mock.expect(b"ME 999\r", b"N\r");
137 let mut radio = Radio::connect(mock).await.unwrap();
138 let result = radio.read_channel(999).await;
139 assert!(matches!(result, Err(Error::NotAvailable)));
140 }
141}