1use bincode::de::Decoder;
2use bincode::enc::Encoder;
3use bincode::error::{DecodeError, EncodeError};
4use bincode::{Decode, Encode};
5use crsf::{LinkStatistics, RcChannels};
6use serde::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
78#[derive(Clone, Debug)]
80pub struct LinkStatisticsPayload(pub LinkStatistics);
81
82impl LinkStatisticsPayload {
83 pub fn inner(&self) -> &LinkStatistics {
84 &self.0
85 }
86}
87
88impl From<LinkStatistics> for LinkStatisticsPayload {
89 fn from(value: LinkStatistics) -> Self {
90 Self(value)
91 }
92}
93
94impl From<LinkStatisticsPayload> for LinkStatistics {
95 fn from(value: LinkStatisticsPayload) -> Self {
96 value.0
97 }
98}
99
100impl PartialEq for LinkStatisticsPayload {
101 fn eq(&self, other: &Self) -> bool {
102 let LinkStatisticsPayload(link_a) = self;
103 let LinkStatisticsPayload(link_b) = other;
104 link_a.uplink_rssi_1 == link_b.uplink_rssi_1
105 && link_a.uplink_rssi_2 == link_b.uplink_rssi_2
106 && link_a.uplink_link_quality == link_b.uplink_link_quality
107 && link_a.uplink_snr == link_b.uplink_snr
108 && link_a.active_antenna == link_b.active_antenna
109 && link_a.rf_mode == link_b.rf_mode
110 && link_a.uplink_tx_power == link_b.uplink_tx_power
111 && link_a.downlink_rssi == link_b.downlink_rssi
112 && link_a.downlink_link_quality == link_b.downlink_link_quality
113 && link_a.downlink_snr == link_b.downlink_snr
114 }
115}
116
117impl Eq for LinkStatisticsPayload {}
118
119impl Default for LinkStatisticsPayload {
120 fn default() -> Self {
121 Self(LinkStatistics {
122 uplink_rssi_1: 0,
123 uplink_rssi_2: 0,
124 uplink_link_quality: 0,
125 uplink_snr: 0,
126 active_antenna: 0,
127 rf_mode: 0,
128 uplink_tx_power: 0,
129 downlink_rssi: 0,
130 downlink_link_quality: 0,
131 downlink_snr: 0,
132 })
133 }
134}
135impl Encode for LinkStatisticsPayload {
136 fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError> {
137 let stats = &self.0;
138 stats.uplink_rssi_1.encode(encoder)?;
139 stats.uplink_rssi_2.encode(encoder)?;
140 stats.uplink_link_quality.encode(encoder)?;
141 stats.uplink_snr.encode(encoder)?;
142 stats.active_antenna.encode(encoder)?;
143 stats.rf_mode.encode(encoder)?;
144 stats.uplink_tx_power.encode(encoder)?;
145 stats.downlink_rssi.encode(encoder)?;
146 stats.downlink_link_quality.encode(encoder)?;
147 stats.downlink_snr.encode(encoder)?;
148 Ok(())
149 }
150}
151
152impl Decode<()> for LinkStatisticsPayload {
153 fn decode<D: Decoder<Context = ()>>(decoder: &mut D) -> Result<Self, DecodeError> {
154 Ok(Self(LinkStatistics {
155 uplink_rssi_1: u8::decode(decoder)?,
156 uplink_rssi_2: u8::decode(decoder)?,
157 uplink_link_quality: u8::decode(decoder)?,
158 uplink_snr: i8::decode(decoder)?,
159 active_antenna: u8::decode(decoder)?,
160 rf_mode: u8::decode(decoder)?,
161 uplink_tx_power: u8::decode(decoder)?,
162 downlink_rssi: u8::decode(decoder)?,
163 downlink_link_quality: u8::decode(decoder)?,
164 downlink_snr: i8::decode(decoder)?,
165 }))
166 }
167}
168
169impl Serialize for LinkStatisticsPayload {
170 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
171 where
172 S: serde::Serializer,
173 {
174 let stats = &self.0;
175 (
176 stats.uplink_rssi_1,
177 stats.uplink_rssi_2,
178 stats.uplink_link_quality,
179 stats.uplink_snr,
180 stats.active_antenna,
181 stats.rf_mode,
182 stats.uplink_tx_power,
183 stats.downlink_rssi,
184 stats.downlink_link_quality,
185 stats.downlink_snr,
186 )
187 .serialize(serializer)
188 }
189}
190
191#[cfg(test)]
192mod tests {
193 use super::*;
194 use bincode::{config, decode_from_slice, encode_to_vec};
195
196 #[test]
197 fn rc_channels_round_trip() {
198 let mut channels = [0u16; 16];
199 for (idx, value) in channels.iter_mut().enumerate() {
200 *value = (idx as u16) * 42;
201 }
202 let payload = RcChannelsPayload(RcChannels(channels));
203 let cfg = config::standard();
204
205 let encoded = encode_to_vec(&payload, cfg).expect("RC encode");
206 let (decoded, consumed): (RcChannelsPayload, usize) =
207 decode_from_slice(&encoded, cfg).expect("RC decode");
208
209 assert_eq!(consumed, encoded.len());
210 assert_eq!(payload, decoded);
211 assert_eq!(decoded.0 .0, channels);
212 }
213
214 #[test]
215 fn link_statistics_round_trip() {
216 let stats = LinkStatistics {
217 uplink_rssi_1: 100,
218 uplink_rssi_2: 98,
219 uplink_link_quality: 95,
220 uplink_snr: -12,
221 active_antenna: 1,
222 rf_mode: 2,
223 uplink_tx_power: 5,
224 downlink_rssi: 110,
225 downlink_link_quality: 90,
226 downlink_snr: -9,
227 };
228 let payload = LinkStatisticsPayload(stats);
229 let cfg = config::standard();
230
231 let encoded = encode_to_vec(&payload, cfg).expect("Link encode");
232 let (decoded, consumed): (LinkStatisticsPayload, usize) =
233 decode_from_slice(&encoded, cfg).expect("Link decode");
234
235 assert_eq!(consumed, encoded.len());
236 assert_eq!(payload, decoded);
237 }
238}