leodos_protocols/datalink/framing/sdlp/
tc.rs1use bon::bon;
9use zerocopy::FromBytes;
10use zerocopy::Immutable;
11use zerocopy::IntoBytes;
12use zerocopy::KnownLayout;
13use zerocopy::Unaligned;
14use zerocopy::byteorder::network_endian::U16;
15
16use super::super::{FrameRead, FrameWrite, PushError};
17use crate::utils::get_bits_u16;
18use crate::utils::set_bits_u16;
19
20#[repr(C, packed)]
53#[derive(FromBytes, IntoBytes, Unaligned, KnownLayout, Immutable)]
54pub struct TelecommandTransferFrame {
55 header: TelecommandTransferFrameHeader,
56 data_field: [u8],
57}
58
59#[repr(C)]
61#[derive(FromBytes, IntoBytes, KnownLayout, Unaligned, Immutable, Debug, Copy, Clone)]
62pub struct TelecommandTransferFrameHeader {
63 id_and_scid: U16,
65 vcid_and_length: U16,
67 sequence_num: u8,
69}
70
71#[rustfmt::skip]
73pub mod bitmask {
74 pub const VERSION_MASK: u16 = 0b_1100_0000_0000_0000;
76 pub const BYPASS_FLAG_MASK: u16 = 0b_0010_0000_0000_0000;
78 pub const CONTROL_FLAG_MASK: u16 = 0b_0001_0000_0000_0000;
80 pub const _RESERVED_MASK: u16 = 0b_0000_1100_0000_0000;
82 pub const SCID_MASK: u16 = 0b_0000_0011_1111_1111;
84
85 pub const VCID_MASK: u16 = 0b_1111_1100_0000_0000;
87 pub const FRAME_LEN_MASK: u16 = 0b_0000_0011_1111_1111;
89}
90
91use bitmask::*;
92use crate::ids::{Scid, Vcid};
93
94#[derive(Debug, Copy, Clone, Eq, PartialEq)]
96pub enum BuildError {
97 InvalidScid(Scid),
99 InvalidVcid(Vcid),
101 DataTooLong(usize),
103 BufferTooSmall {
105 required: usize,
107 provided: usize,
109 },
110}
111
112#[derive(Debug, Copy, Clone, Eq, PartialEq)]
114pub enum ParseError {
115 TooShortForHeader {
117 actual: usize,
119 },
120 IncompleteFrame {
122 header_len: usize,
124 buffer_len: usize,
126 },
127}
128
129#[derive(Debug, Copy, Clone, Eq, PartialEq)]
132#[repr(u8)]
133pub enum BypassFlag {
134 TypeA = 0,
136 TypeB = 1,
138}
139
140#[derive(Debug, Copy, Clone, Eq, PartialEq)]
143#[repr(u8)]
144pub enum ControlFlag {
145 TypeD = 0,
147 TypeC = 1,
149}
150
151#[bon]
152impl TelecommandTransferFrame {
153 pub const HEADER_SIZE: usize = 5;
155 pub const MAX_DATA_FIELD_LEN: usize = 1019;
157
158 pub fn parse(bytes: &[u8]) -> Result<&Self, ParseError> {
160 if bytes.len() < Self::HEADER_SIZE {
161 return Err(ParseError::TooShortForHeader {
162 actual: bytes.len(),
163 });
164 }
165 let (header, _) = TelecommandTransferFrameHeader::ref_from_prefix(bytes).unwrap();
166 let specified_len = header.frame_len();
167
168 if specified_len > bytes.len() {
169 return Err(ParseError::IncompleteFrame {
170 header_len: specified_len,
171 buffer_len: bytes.len(),
172 });
173 }
174
175 Ok(TelecommandTransferFrame::ref_from_bytes(&bytes[..specified_len]).unwrap())
176 }
177
178 pub fn header(&self) -> &TelecommandTransferFrameHeader {
180 &self.header
181 }
182
183 pub fn data_field_mut(&mut self) -> &mut [u8] {
185 &mut self.data_field
186 }
187
188 pub fn data_field(&self) -> &[u8] {
190 &self.data_field
191 }
192
193 pub fn frame_len(&self) -> usize {
195 Self::HEADER_SIZE + self.data_field.len()
196 }
197
198 #[builder]
200 pub fn new(
201 buffer: &mut [u8],
202 scid: Scid,
203 vcid: Vcid,
204 bypass_flag: BypassFlag,
205 control_flag: ControlFlag,
206 seq: u8,
207 data_field_len: usize,
208 ) -> Result<&mut Self, BuildError> {
209 if scid.num_bits() > 10 {
210 return Err(BuildError::InvalidScid(scid));
211 }
212 if vcid.num_bits() > 6 {
213 return Err(BuildError::InvalidVcid(vcid));
214 }
215 if data_field_len > Self::MAX_DATA_FIELD_LEN {
216 return Err(BuildError::DataTooLong(data_field_len));
217 }
218
219 let total_len = Self::HEADER_SIZE + data_field_len;
220 if buffer.len() < total_len {
221 return Err(BuildError::BufferTooSmall {
222 required: total_len,
223 provided: buffer.len(),
224 });
225 }
226
227 let frame_buf = &mut buffer[..total_len];
228 let frame = TelecommandTransferFrame::mut_from_bytes(frame_buf).unwrap();
229
230 frame.header.set_scid(scid);
231 frame.header.set_vcid(vcid);
232 frame.header.set_bypass_flag(bypass_flag);
233 frame.header.set_control_flag(control_flag);
234 frame.header.set_sequence_num(seq);
235 frame.header.set_frame_len(total_len);
236
237 Ok(frame)
238 }
239}
240
241impl TelecommandTransferFrameHeader {
242 pub fn scid(&self) -> Scid {
244 Scid::new(get_bits_u16(self.id_and_scid, SCID_MASK) as u32)
245 }
246 pub fn set_scid(&mut self, scid: Scid) {
248 set_bits_u16(&mut self.id_and_scid, SCID_MASK, scid.get() as u16);
249 }
250
251 pub fn vcid(&self) -> Vcid {
253 Vcid::new(get_bits_u16(self.vcid_and_length, VCID_MASK) as u32)
254 }
255 pub fn set_vcid(&mut self, vcid: Vcid) {
257 set_bits_u16(&mut self.vcid_and_length, VCID_MASK, vcid.get() as u16);
258 }
259
260 pub fn frame_len(&self) -> usize {
262 get_bits_u16(self.vcid_and_length, FRAME_LEN_MASK) as usize + 1
263 }
264 pub fn set_frame_len(&mut self, length: usize) {
266 let len_field = (length - 1) as u16;
267 set_bits_u16(&mut self.vcid_and_length, FRAME_LEN_MASK, len_field);
268 }
269
270 pub fn sequence_num(&self) -> u8 {
272 self.sequence_num
273 }
274 pub fn set_sequence_num(&mut self, seq: u8) {
276 self.sequence_num = seq;
277 }
278
279 pub fn bypass_flag(&self) -> BypassFlag {
281 if get_bits_u16(self.id_and_scid, BYPASS_FLAG_MASK) == 1 {
282 BypassFlag::TypeB
283 } else {
284 BypassFlag::TypeA
285 }
286 }
287 pub fn set_bypass_flag(&mut self, flag: BypassFlag) {
289 set_bits_u16(&mut self.id_and_scid, BYPASS_FLAG_MASK, flag as u16);
290 }
291
292 pub fn control_flag(&self) -> ControlFlag {
294 if get_bits_u16(self.id_and_scid, CONTROL_FLAG_MASK) == 1 {
295 ControlFlag::TypeC
296 } else {
297 ControlFlag::TypeD
298 }
299 }
300 pub fn set_control_flag(&mut self, flag: ControlFlag) {
302 set_bits_u16(&mut self.id_and_scid, CONTROL_FLAG_MASK, flag as u16);
303 }
304}
305
306#[derive(Debug, Clone)]
310pub struct TcFrameWriterConfig {
311 pub scid: Scid,
313 pub vcid: Vcid,
315 pub bypass: BypassFlag,
317 pub control: ControlFlag,
319 pub max_data_field_len: usize,
321}
322
323pub struct TcFrameWriter<const BUF: usize> {
330 config: TcFrameWriterConfig,
331 sequence: u8,
332 data_len: usize,
333 buf: [u8; BUF],
334}
335
336impl<const BUF: usize> TcFrameWriter<BUF> {
337 pub fn new(config: TcFrameWriterConfig) -> Self {
339 Self {
340 config,
341 sequence: 0,
342 data_len: 0,
343 buf: [0u8; BUF],
344 }
345 }
346}
347
348impl<const BUF: usize> TcFrameWriter<BUF> {
349 fn remaining(&self) -> usize {
350 self.config.max_data_field_len.saturating_sub(self.data_len)
351 }
352}
353
354impl<const BUF: usize> FrameWrite for TcFrameWriter<BUF> {
355 type Error = BuildError;
356
357 fn is_empty(&self) -> bool {
358 self.data_len == 0
359 }
360
361 fn push(&mut self, data: &[u8]) -> Result<(), PushError> {
362 if data.len() > self.config.max_data_field_len {
363 return Err(PushError::TooLarge);
364 }
365 if data.len() > self.remaining() {
366 return Err(PushError::Full);
367 }
368 let off = TelecommandTransferFrame::HEADER_SIZE + self.data_len;
369 self.buf[off..off + data.len()].copy_from_slice(data);
370 self.data_len += data.len();
371 Ok(())
372 }
373
374 fn finish(&mut self) -> Result<&[u8], BuildError> {
375 let total = TelecommandTransferFrame::HEADER_SIZE + self.data_len;
376 let seq = self.sequence;
377 self.sequence = self.sequence.wrapping_add(1);
378
379 TelecommandTransferFrame::builder()
380 .buffer(&mut self.buf[..total])
381 .scid(self.config.scid)
382 .vcid(self.config.vcid)
383 .bypass_flag(self.config.bypass)
384 .control_flag(self.config.control)
385 .seq(seq)
386 .data_field_len(self.data_len)
387 .build()?;
388
389 self.data_len = 0;
390 Ok(&self.buf[..total])
391 }
392}
393
394pub struct TcFrameReader<const BUF: usize> {
402 buf: [u8; BUF],
403 data_start: usize,
404 data_end: usize,
405}
406
407impl<const BUF: usize> TcFrameReader<BUF> {
408 pub fn new() -> Self {
410 Self {
411 buf: [0u8; BUF],
412 data_start: 0,
413 data_end: 0,
414 }
415 }
416}
417
418impl<const BUF: usize> FrameRead for TcFrameReader<BUF> {
419 type Error = ParseError;
420
421 fn buffer_mut(&mut self) -> &mut [u8] {
422 &mut self.buf
423 }
424
425 fn feed(&mut self, len: usize) -> Result<(), ParseError> {
426 let parsed =
427 TelecommandTransferFrame::parse(&self.buf[..len])?;
428 let data = parsed.data_field();
429 self.data_start = TelecommandTransferFrame::HEADER_SIZE;
430 self.data_end = self.data_start + data.len();
431 Ok(())
432 }
433
434 fn data_field(&self) -> &[u8] {
435 &self.buf[self.data_start..self.data_end]
436 }
437}