4
4
import struct
5
5
from typing import Union
6
6
7
+ from spacepackets .crc import CRC16_CCITT_FUNC
8
+
7
9
from .defs import (
10
+ UslpChecksumError ,
8
11
UslpFhpVhopFieldMissingError ,
9
12
UslpInvalidConstructionRulesError ,
10
13
UslpInvalidFrameHeaderError ,
@@ -30,28 +33,19 @@ def __init__(self, present: bool, size: int):
30
33
self .size = size
31
34
32
35
33
- class FecfProperties :
34
- def __init__ (self , present : bool , size : int ):
35
- self .present = present
36
- self .size = size
37
-
38
-
39
36
class FramePropertiesBase :
40
37
def __init__ (
41
38
self ,
42
39
has_insert_zone : bool ,
43
40
has_fecf : bool ,
44
41
insert_zone_len : int | None = None ,
45
- fecf_len : int | None = None ,
46
42
):
47
43
if has_insert_zone and insert_zone_len is None :
48
44
raise ValueError
49
- if has_fecf and fecf_len is None :
50
- raise ValueError
51
45
self .insert_zone_properties = InsertZoneProperties (
52
46
present = has_insert_zone , size = insert_zone_len
53
47
)
54
- self .fecf_properties = FecfProperties ( present = has_fecf , size = fecf_len )
48
+ self .has_fecf = has_fecf
55
49
56
50
57
51
class FixedFrameProperties (FramePropertiesBase ):
@@ -61,7 +55,6 @@ def __init__(
61
55
has_insert_zone : bool ,
62
56
has_fecf : bool ,
63
57
insert_zone_len : int | None = None ,
64
- fecf_len : int | None = None ,
65
58
):
66
59
"""Contains properties required when unpacking fixed USLP frames. These properties
67
60
can not be determined by parsing the frame. The standard refers to these properties
@@ -76,7 +69,6 @@ def __init__(
76
69
has_insert_zone = has_insert_zone ,
77
70
has_fecf = has_fecf ,
78
71
insert_zone_len = insert_zone_len ,
79
- fecf_len = fecf_len ,
80
72
)
81
73
self .fixed_len = fixed_len
82
74
@@ -88,7 +80,6 @@ def __init__(
88
80
has_fecf : bool ,
89
81
truncated_frame_len : int ,
90
82
insert_zone_len : int | None = None ,
91
- fecf_len : int | None = None ,
92
83
):
93
84
"""Contains properties required when unpacking variable USLP frames. These properties
94
85
can not be determined by parsing the frame. The standard refers to these properties
@@ -104,7 +95,6 @@ def __init__(
104
95
has_insert_zone = has_insert_zone ,
105
96
has_fecf = has_fecf ,
106
97
insert_zone_len = insert_zone_len ,
107
- fecf_len = fecf_len ,
108
98
)
109
99
self .truncated_frame_len = truncated_frame_len
110
100
@@ -324,13 +314,13 @@ def __init__(
324
314
tfdf : TransferFrameDataField ,
325
315
insert_zone : bytes | None = None ,
326
316
op_ctrl_field : bytes | None = None ,
327
- fecf : bytes | None = None ,
317
+ has_fecf : bool = True ,
328
318
):
329
319
self .header = header
330
320
self .tfdf = tfdf
331
321
self .insert_zone = insert_zone
332
322
self .op_ctrl_field = op_ctrl_field
333
- self .fecf = fecf
323
+ self .has_fecf = has_fecf
334
324
335
325
def pack (self , truncated : bool = False , frame_type : FrameType | None = None ) -> bytearray :
336
326
frame = bytearray ()
@@ -346,8 +336,8 @@ def pack(self, truncated: bool = False, frame_type: FrameType | None = None) ->
346
336
frame .extend (self .op_ctrl_field )
347
337
elif not truncated and self .header .op_ctrl_flag :
348
338
raise UslpInvalidFrameHeaderError
349
- if self .fecf is not None :
350
- frame .extend (self . fecf )
339
+ if self .has_fecf :
340
+ frame .extend (struct . pack ( "!H" , CRC16_CCITT_FUNC ( frame )) )
351
341
return frame
352
342
353
343
def set_frame_len_in_header (self ) -> None :
@@ -363,8 +353,8 @@ def len(self) -> int:
363
353
size += len (self .insert_zone )
364
354
if self .op_ctrl_field is not None :
365
355
size += len (self .op_ctrl_field )
366
- if self .fecf is not None :
367
- size += len ( self . fecf )
356
+ if self .has_fecf :
357
+ size += 2
368
358
return size
369
359
370
360
@classmethod
@@ -383,13 +373,16 @@ def __empty(cls) -> TransferFrame:
383
373
tfdf = empty_data_field ,
384
374
insert_zone = None ,
385
375
op_ctrl_field = None ,
386
- fecf = None ,
376
+ has_fecf = False ,
387
377
)
388
378
389
379
# TODO: Fix lint by creating helper methods.
390
380
@classmethod
391
381
def unpack ( # noqa: PLR0912 too many branches
392
- cls , raw_frame : bytes , frame_type : FrameType , frame_properties : FramePropertiesT
382
+ cls ,
383
+ raw_frame : bytes | bytearray ,
384
+ frame_type : FrameType ,
385
+ frame_properties : FramePropertiesT ,
393
386
) -> TransferFrame :
394
387
"""Unpack a USLP transfer frame from a raw bytearray. All managed parameters have
395
388
to be passed explicitly.
@@ -457,11 +450,11 @@ def unpack( # noqa: PLR0912 too many branches
457
450
frame .op_ctrl_field = raw_frame [current_idx : current_idx + 4 ]
458
451
current_idx += 4
459
452
# Parse Frame Error Control field if present
460
- if frame_properties .fecf_properties . present :
461
- frame . fecf = raw_frame [
462
- current_idx : current_idx + frame_properties . fecf_properties . size
463
- ]
464
- current_idx += frame_properties . fecf_properties . size
453
+ if frame_properties .has_fecf :
454
+ crc_check = CRC16_CCITT_FUNC ( raw_frame [0 : current_idx + 2 ])
455
+ if crc_check != 0 :
456
+ raise UslpChecksumError
457
+
465
458
return frame
466
459
467
460
@staticmethod
@@ -497,8 +490,8 @@ def __get_tfdf_len(
497
490
exact_tfdf_len = properties .truncated_frame_len - header_len
498
491
else :
499
492
exact_tfdf_len = header .frame_len + 1 - header_len
500
- if properties .fecf_properties . present :
501
- exact_tfdf_len -= properties . fecf_properties . size
493
+ if properties .has_fecf :
494
+ exact_tfdf_len -= 2
502
495
if header_type != HeaderType .TRUNCATED and header .op_ctrl_flag :
503
496
exact_tfdf_len -= 4
504
497
if properties .insert_zone_properties .present :
0 commit comments