1use bincode::de::Decoder;
2use bincode::enc::Encoder;
3use bincode::error::{DecodeError, EncodeError};
4use bincode::{Decode, Encode};
5use crsf::{LinkStatistics, RcChannels};
6use serde::{Deserialize, Serialize};
7
8#[derive(Clone, Debug)]
10pub struct RcChannelsPayload(pub RcChannels);
11
12impl RcChannelsPayload {
13 pub fn inner(&self) -> &RcChannels {
15 &self.0
16 }
17
18 pub fn inner_mut(&mut self) -> &mut RcChannels {
20 &mut self.0
21 }
22}
23
24impl From<RcChannels> for RcChannelsPayload {
25 fn from(value: RcChannels) -> Self {
26 Self(value)
27 }
28}
29
30impl From<RcChannelsPayload> for RcChannels {
31 fn from(value: RcChannelsPayload) -> Self {
32 value.0
33 }
34}
35
36impl Default for RcChannelsPayload {
37 fn default() -> Self {
38 Self(RcChannels([0; 16]))
39 }
40}
41
42impl PartialEq for RcChannelsPayload {
43 fn eq(&self, other: &Self) -> bool {
44 self.0.0 == other.0.0
45 }
46}
47
48impl Eq for RcChannelsPayload {}
49
50impl Encode for RcChannelsPayload {
51 fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
52 for value in self.0.0.iter() {
53 value.encode(encoder)?;
54 }
55 Ok(())
56 }
57}
58
59impl Decode<()> for RcChannelsPayload {
60 fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, DecodeError> {
61 let mut channels = [0u16; 16];
62 for slot in channels.iter_mut() {
63 *slot = u16::decode(decoder)?;
64 }
65 Ok(Self(RcChannels(channels)))
66 }
67}
68
69impl Serialize for RcChannelsPayload {
70 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
71 where
72 S: serde::Serializer,
73 {
74 self.inner().0.serialize(serializer)
75 }
76}
77
78impl<'de> Deserialize<'de> for RcChannelsPayload {
79 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
80 where
81 D: serde::Deserializer<'de>,
82 {
83 let channels = <[u16; 16]>::deserialize(deserializer)?;
84 Ok(Self(RcChannels(channels)))
85 }
86}
87
88#[derive(Clone, Debug)]
90pub struct LinkStatisticsPayload(pub LinkStatistics);
91
92impl LinkStatisticsPayload {
93 pub fn inner(&self) -> &LinkStatistics {
94 &self.0
95 }
96}
97
98impl From<LinkStatistics> for LinkStatisticsPayload {
99 fn from(value: LinkStatistics) -> Self {
100 Self(value)
101 }
102}
103
104impl From<LinkStatisticsPayload> for LinkStatistics {
105 fn from(value: LinkStatisticsPayload) -> Self {
106 value.0
107 }
108}
109
110impl PartialEq for LinkStatisticsPayload {
111 fn eq(&self, other: &Self) -> bool {
112 let LinkStatisticsPayload(link_a) = self;
113 let LinkStatisticsPayload(link_b) = other;
114 link_a.uplink_rssi_1 == link_b.uplink_rssi_1
115 && link_a.uplink_rssi_2 == link_b.uplink_rssi_2
116 && link_a.uplink_link_quality == link_b.uplink_link_quality
117 && link_a.uplink_snr == link_b.uplink_snr
118 && link_a.active_antenna == link_b.active_antenna
119 && link_a.rf_mode == link_b.rf_mode
120 && link_a.uplink_tx_power == link_b.uplink_tx_power
121 && link_a.downlink_rssi == link_b.downlink_rssi
122 && link_a.downlink_link_quality == link_b.downlink_link_quality
123 && link_a.downlink_snr == link_b.downlink_snr
124 }
125}
126
127impl Eq for LinkStatisticsPayload {}
128
129impl Default for LinkStatisticsPayload {
130 fn default() -> Self {
131 Self(LinkStatistics {
132 uplink_rssi_1: 0,
133 uplink_rssi_2: 0,
134 uplink_link_quality: 0,
135 uplink_snr: 0,
136 active_antenna: 0,
137 rf_mode: 0,
138 uplink_tx_power: 0,
139 downlink_rssi: 0,
140 downlink_link_quality: 0,
141 downlink_snr: 0,
142 })
143 }
144}
145impl Encode for LinkStatisticsPayload {
146 fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
147 let stats = &self.0;
148 stats.uplink_rssi_1.encode(encoder)?;
149 stats.uplink_rssi_2.encode(encoder)?;
150 stats.uplink_link_quality.encode(encoder)?;
151 stats.uplink_snr.encode(encoder)?;
152 stats.active_antenna.encode(encoder)?;
153 stats.rf_mode.encode(encoder)?;
154 stats.uplink_tx_power.encode(encoder)?;
155 stats.downlink_rssi.encode(encoder)?;
156 stats.downlink_link_quality.encode(encoder)?;
157 stats.downlink_snr.encode(encoder)?;
158 Ok(())
159 }
160}
161
162impl Decode<()> for LinkStatisticsPayload {
163 fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, DecodeError> {
164 Ok(Self(LinkStatistics {
165 uplink_rssi_1: u8::decode(decoder)?,
166 uplink_rssi_2: u8::decode(decoder)?,
167 uplink_link_quality: u8::decode(decoder)?,
168 uplink_snr: i8::decode(decoder)?,
169 active_antenna: u8::decode(decoder)?,
170 rf_mode: u8::decode(decoder)?,
171 uplink_tx_power: u8::decode(decoder)?,
172 downlink_rssi: u8::decode(decoder)?,
173 downlink_link_quality: u8::decode(decoder)?,
174 downlink_snr: i8::decode(decoder)?,
175 }))
176 }
177}
178
179impl Serialize for LinkStatisticsPayload {
180 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
181 where
182 S: serde::Serializer,
183 {
184 let stats = &self.0;
185 (
186 stats.uplink_rssi_1,
187 stats.uplink_rssi_2,
188 stats.uplink_link_quality,
189 stats.uplink_snr,
190 stats.active_antenna,
191 stats.rf_mode,
192 stats.uplink_tx_power,
193 stats.downlink_rssi,
194 stats.downlink_link_quality,
195 stats.downlink_snr,
196 )
197 .serialize(serializer)
198 }
199}
200
201impl<'de> Deserialize<'de> for LinkStatisticsPayload {
202 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
203 where
204 D: serde::Deserializer<'de>,
205 {
206 let (
207 uplink_rssi_1,
208 uplink_rssi_2,
209 uplink_link_quality,
210 uplink_snr,
211 active_antenna,
212 rf_mode,
213 uplink_tx_power,
214 downlink_rssi,
215 downlink_link_quality,
216 downlink_snr,
217 ) = <(u8, u8, u8, i8, u8, u8, u8, u8, u8, i8)>::deserialize(deserializer)?;
218 Ok(Self(LinkStatistics {
219 uplink_rssi_1,
220 uplink_rssi_2,
221 uplink_link_quality,
222 uplink_snr,
223 active_antenna,
224 rf_mode,
225 uplink_tx_power,
226 downlink_rssi,
227 downlink_link_quality,
228 downlink_snr,
229 }))
230 }
231}
232
233#[cfg(test)]
234mod tests {
235 use super::*;
236 use bincode::{config, decode_from_slice, encode_to_vec};
237
238 #[test]
239 fn rc_channels_round_trip() {
240 let mut channels = [0u16; 16];
241 for (idx, value) in channels.iter_mut().enumerate() {
242 *value = (idx as u16) * 42;
243 }
244 let payload = RcChannelsPayload(RcChannels(channels));
245 let cfg = config::standard();
246
247 let encoded = encode_to_vec(&payload, cfg).expect("RC encode");
248 let (decoded, consumed): (RcChannelsPayload, usize) =
249 decode_from_slice(&encoded, cfg).expect("RC decode");
250
251 assert_eq!(consumed, encoded.len());
252 assert_eq!(payload, decoded);
253 assert_eq!(decoded.0.0, channels);
254 }
255
256 #[test]
257 fn link_statistics_round_trip() {
258 let stats = LinkStatistics {
259 uplink_rssi_1: 100,
260 uplink_rssi_2: 98,
261 uplink_link_quality: 95,
262 uplink_snr: -12,
263 active_antenna: 1,
264 rf_mode: 2,
265 uplink_tx_power: 5,
266 downlink_rssi: 110,
267 downlink_link_quality: 90,
268 downlink_snr: -9,
269 };
270 let payload = LinkStatisticsPayload(stats);
271 let cfg = config::standard();
272
273 let encoded = encode_to_vec(&payload, cfg).expect("Link encode");
274 let (decoded, consumed): (LinkStatisticsPayload, usize) =
275 decode_from_slice(&encoded, cfg).expect("Link decode");
276
277 assert_eq!(consumed, encoded.len());
278 assert_eq!(payload, decoded);
279 }
280}