satrs_core/encoding/
cobs.rs1use crate::tmtc::ReceivesTcCore;
2use cobs::{decode_in_place, encode, max_encoding_length};
3
4pub fn encode_packet_with_cobs(
32 packet: &[u8],
33 encoded_buf: &mut [u8],
34 current_idx: &mut usize,
35) -> bool {
36 let max_encoding_len = max_encoding_length(packet.len());
37 if *current_idx + max_encoding_len + 2 > encoded_buf.len() {
38 return false;
39 }
40 encoded_buf[*current_idx] = 0;
41 *current_idx += 1;
42 *current_idx += encode(packet, &mut encoded_buf[*current_idx..]);
43 encoded_buf[*current_idx] = 0;
44 *current_idx += 1;
45 true
46}
47
48pub fn parse_buffer_for_cobs_encoded_packets<E>(
59 buf: &mut [u8],
60 tc_receiver: &mut dyn ReceivesTcCore<Error = E>,
61 next_write_idx: &mut usize,
62) -> Result<u32, E> {
63 let mut start_index_packet = 0;
64 let mut start_found = false;
65 let mut last_byte = false;
66 let mut packets_found = 0;
67 for i in 0..buf.len() {
68 if i == buf.len() - 1 {
69 last_byte = true;
70 }
71 if buf[i] == 0 {
72 if !start_found && !last_byte && buf[i + 1] == 0 {
73 continue;
76 }
77 if start_found {
78 let decode_result = decode_in_place(&mut buf[start_index_packet..i]);
79 if let Ok(packet_len) = decode_result {
80 packets_found += 1;
81 tc_receiver
82 .pass_tc(&buf[start_index_packet..start_index_packet + packet_len])?;
83 }
84 start_found = false;
85 } else {
86 start_index_packet = i + 1;
87 start_found = true;
88 }
89 }
90 }
91 if start_index_packet > 0 && start_found && packets_found > 0 {
93 buf.copy_within(start_index_packet - 1.., 0);
94 *next_write_idx = buf.len() - start_index_packet + 1;
95 }
96 Ok(packets_found)
97}
98
99#[cfg(test)]
100pub(crate) mod tests {
101 use cobs::encode;
102
103 use crate::encoding::tests::{encode_simple_packet, TcCacher, INVERTED_PACKET, SIMPLE_PACKET};
104
105 use super::parse_buffer_for_cobs_encoded_packets;
106
107 #[test]
108 fn test_parsing_simple_packet() {
109 let mut test_sender = TcCacher::default();
110 let mut encoded_buf: [u8; 16] = [0; 16];
111 let mut current_idx = 0;
112 encode_simple_packet(&mut encoded_buf, &mut current_idx);
113 let mut next_read_idx = 0;
114 let packets = parse_buffer_for_cobs_encoded_packets(
115 &mut encoded_buf[0..current_idx],
116 &mut test_sender,
117 &mut next_read_idx,
118 )
119 .unwrap();
120 assert_eq!(packets, 1);
121 assert_eq!(test_sender.tc_queue.len(), 1);
122 let packet = &test_sender.tc_queue[0];
123 assert_eq!(packet, &SIMPLE_PACKET);
124 }
125
126 #[test]
127 fn test_parsing_consecutive_packets() {
128 let mut test_sender = TcCacher::default();
129 let mut encoded_buf: [u8; 16] = [0; 16];
130 let mut current_idx = 0;
131 encode_simple_packet(&mut encoded_buf, &mut current_idx);
132
133 encoded_buf[current_idx] = 0;
135 current_idx += 1;
136 current_idx += encode(&INVERTED_PACKET, &mut encoded_buf[current_idx..]);
137 encoded_buf[current_idx] = 0;
138 current_idx += 1;
139 let mut next_read_idx = 0;
140 let packets = parse_buffer_for_cobs_encoded_packets(
141 &mut encoded_buf[0..current_idx],
142 &mut test_sender,
143 &mut next_read_idx,
144 )
145 .unwrap();
146 assert_eq!(packets, 2);
147 assert_eq!(test_sender.tc_queue.len(), 2);
148 let packet0 = &test_sender.tc_queue[0];
149 assert_eq!(packet0, &SIMPLE_PACKET);
150 let packet1 = &test_sender.tc_queue[1];
151 assert_eq!(packet1, &INVERTED_PACKET);
152 }
153
154 #[test]
155 fn test_split_tail_packet_only() {
156 let mut test_sender = TcCacher::default();
157 let mut encoded_buf: [u8; 16] = [0; 16];
158 let mut current_idx = 0;
159 encode_simple_packet(&mut encoded_buf, &mut current_idx);
160 let mut next_read_idx = 0;
161 let packets = parse_buffer_for_cobs_encoded_packets(
162 &mut encoded_buf[0..current_idx - 1],
164 &mut test_sender,
165 &mut next_read_idx,
166 )
167 .unwrap();
168 assert_eq!(packets, 0);
169 assert_eq!(test_sender.tc_queue.len(), 0);
170 assert_eq!(next_read_idx, 0);
171 }
172
173 fn generic_test_split_packet(cut_off: usize) {
174 let mut test_sender = TcCacher::default();
175 let mut encoded_buf: [u8; 16] = [0; 16];
176 assert!(cut_off < INVERTED_PACKET.len() + 1);
177 let mut current_idx = 0;
178 encode_simple_packet(&mut encoded_buf, &mut current_idx);
179 encoded_buf[current_idx] = 0;
181 let packet_start = current_idx;
182 current_idx += 1;
183 let encoded_len = encode(&INVERTED_PACKET, &mut encoded_buf[current_idx..]);
184 assert_eq!(encoded_len, 6);
185 current_idx += encoded_len;
186 let next_expected_write_idx = 1 + encoded_len - cut_off + 1;
189 encoded_buf[current_idx] = 0;
190 current_idx += 1;
191 let mut next_write_idx = 0;
192 let expected_at_start = encoded_buf[packet_start..current_idx - cut_off].to_vec();
193 let packets = parse_buffer_for_cobs_encoded_packets(
194 &mut encoded_buf[0..current_idx - cut_off],
196 &mut test_sender,
197 &mut next_write_idx,
198 )
199 .unwrap();
200 assert_eq!(packets, 1);
201 assert_eq!(test_sender.tc_queue.len(), 1);
202 assert_eq!(&test_sender.tc_queue[0], &SIMPLE_PACKET);
203 assert_eq!(next_write_idx, next_expected_write_idx);
204 assert_eq!(encoded_buf[..next_expected_write_idx], expected_at_start);
205 }
206
207 #[test]
208 fn test_one_packet_and_split_tail_packet_0() {
209 generic_test_split_packet(1);
210 }
211
212 #[test]
213 fn test_one_packet_and_split_tail_packet_1() {
214 generic_test_split_packet(2);
215 }
216
217 #[test]
218 fn test_one_packet_and_split_tail_packet_2() {
219 generic_test_split_packet(3);
220 }
221
222 #[test]
223 fn test_zero_at_end() {
224 let mut test_sender = TcCacher::default();
225 let mut encoded_buf: [u8; 16] = [0; 16];
226 let mut next_write_idx = 0;
227 let mut current_idx = 0;
228 encoded_buf[current_idx] = 5;
229 current_idx += 1;
230 encode_simple_packet(&mut encoded_buf, &mut current_idx);
231 encoded_buf[current_idx] = 0;
232 current_idx += 1;
233 let packets = parse_buffer_for_cobs_encoded_packets(
234 &mut encoded_buf[0..current_idx],
236 &mut test_sender,
237 &mut next_write_idx,
238 )
239 .unwrap();
240 assert_eq!(packets, 1);
241 assert_eq!(test_sender.tc_queue.len(), 1);
242 assert_eq!(&test_sender.tc_queue[0], &SIMPLE_PACKET);
243 assert_eq!(next_write_idx, 1);
244 assert_eq!(encoded_buf[0], 0);
245 }
246
247 #[test]
248 fn test_all_zeroes() {
249 let mut test_sender = TcCacher::default();
250 let mut all_zeroes: [u8; 5] = [0; 5];
251 let mut next_write_idx = 0;
252 let packets = parse_buffer_for_cobs_encoded_packets(
253 &mut all_zeroes,
255 &mut test_sender,
256 &mut next_write_idx,
257 )
258 .unwrap();
259 assert_eq!(packets, 0);
260 assert!(test_sender.tc_queue.is_empty());
261 assert_eq!(next_write_idx, 0);
262 }
263}