uf_crsf/packets/
mavlink_sensor.rs1use crate::packets::{CrsfPacket, PacketType};
2use crate::CrsfParsingError;
3use core::mem::size_of;
4
5#[derive(Clone, Debug, PartialEq)]
9#[cfg_attr(feature = "defmt", derive(defmt::Format))]
10pub struct MavLinkSensor {
11 pub dst_addr: u8,
12 pub src_addr: u8,
13 pub sensor_present: u32,
15 pub sensor_enabled: u32,
17 pub sensor_health: u32,
19}
20
21impl MavLinkSensor {
22 pub fn new(
23 dst_addr: u8,
24 src_addr: u8,
25 sensor_present: u32,
26 sensor_enabled: u32,
27 sensor_health: u32,
28 ) -> Result<Self, CrsfParsingError> {
29 Ok(Self {
30 dst_addr,
31 src_addr,
32 sensor_present,
33 sensor_enabled,
34 sensor_health,
35 })
36 }
37}
38
39impl CrsfPacket for MavLinkSensor {
40 const PACKET_TYPE: PacketType = PacketType::MavLinkSensor;
41 const MIN_PAYLOAD_SIZE: usize = 2 * size_of::<u8>() + 3 * size_of::<u32>();
42
43 fn from_bytes(data: &[u8]) -> Result<Self, CrsfParsingError> {
44 if data.len() < Self::MIN_PAYLOAD_SIZE {
45 return Err(CrsfParsingError::InvalidPayloadLength);
46 }
47 Ok(Self {
48 dst_addr: data[0],
49 src_addr: data[1],
50 sensor_present: u32::from_be_bytes(data[2..6].try_into().expect("infallible")),
51 sensor_enabled: u32::from_be_bytes(data[6..10].try_into().expect("infallible")),
52 sensor_health: u32::from_be_bytes(data[10..14].try_into().expect("infallible")),
53 })
54 }
55
56 fn to_bytes(&self, buffer: &mut [u8]) -> Result<usize, CrsfParsingError> {
57 self.validate_buffer_size(buffer)?;
58 buffer[0] = self.dst_addr;
59 buffer[1] = self.src_addr;
60 buffer[2..6].copy_from_slice(&self.sensor_present.to_be_bytes());
61 buffer[6..10].copy_from_slice(&self.sensor_enabled.to_be_bytes());
62 buffer[10..14].copy_from_slice(&self.sensor_health.to_be_bytes());
63 Ok(Self::MIN_PAYLOAD_SIZE)
64 }
65}
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70
71 #[test]
72 fn test_mavlink_sensor_from_bytes() {
73 assert_eq!(MavLinkSensor::MIN_PAYLOAD_SIZE, 14);
74 let data: [u8; 14] = [
75 0x00, 0x01, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
76 ];
77 let packet = MavLinkSensor::from_bytes(&data).unwrap();
78
79 assert_eq!(packet.dst_addr, 0x00);
80 assert_eq!(packet.src_addr, 0x01);
81 assert_eq!(packet.sensor_present, 0x01020304);
82 assert_eq!(packet.sensor_enabled, 0x05060708);
83 assert_eq!(packet.sensor_health, 0x090A0B0C);
84 }
85
86 #[test]
87 fn test_mavlink_sensor_to_bytes() {
88 let packet = MavLinkSensor {
89 sensor_present: 0x01020304,
90 dst_addr: 0,
91 src_addr: 1,
92 sensor_enabled: 0x05060708,
93 sensor_health: 0x090A0B0C,
94 };
95 let mut buffer = [0u8; 14];
96 let len = packet.to_bytes(&mut buffer).unwrap();
97 assert_eq!(len, 14);
98 let expected: [u8; 14] = [
99 0x00, 0x01, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
100 ];
101 assert_eq!(buffer, expected);
102 }
103
104 #[test]
105 fn test_mavlink_sensor_round_trip() {
106 let packet = MavLinkSensor {
107 dst_addr: 0,
108 src_addr: 1,
109 sensor_present: 123,
110 sensor_enabled: 456,
111 sensor_health: 789,
112 };
113 let mut buffer = [0u8; 14];
114 packet.to_bytes(&mut buffer).unwrap();
115 let round_trip = MavLinkSensor::from_bytes(&buffer).unwrap();
116 assert_eq!(packet, round_trip);
117 }
118
119 #[test]
120 fn test_mavlink_sensor_from_bytes_too_small() {
121 let data: [u8; 13] = [0; 13];
122 let result = MavLinkSensor::from_bytes(&data);
123 assert_eq!(result, Err(CrsfParsingError::InvalidPayloadLength));
124 }
125
126 #[test]
127 fn test_mavlink_sensor_to_bytes_too_small() {
128 let packet = MavLinkSensor {
129 dst_addr: 0,
130 src_addr: 1,
131 sensor_present: 1,
132 sensor_enabled: 2,
133 sensor_health: 3,
134 };
135 let mut buffer = [0u8; 13];
136 let result = packet.to_bytes(&mut buffer);
137 assert_eq!(result, Err(CrsfParsingError::BufferOverflow));
138 }
139}