Skip to content

Commit

Permalink
edl field attribute size_prefix is now a data_type value
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanpdx committed Aug 17, 2024
1 parent 5ba1562 commit 272cf4c
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 32 deletions.
19 changes: 10 additions & 9 deletions oresat_configs/edl_cmd_defs.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ class EdlCommandField:
int: Max size in bytes for variable "str" data types. String must end with a '\0'.
This takes precedence over fix_size.
"""
size_prefix: int = 0
size_prefix: str = ""
"""
int: Number of leading prefix bytes used to determind the size of a "bytes" field.
This takes precedence over fix_size.
str: Data type of leading prefix bytes used to determind the size of a "bytes" field. Set to a
"uintX" data type. This takes precedence over fix_size.
"""
fixed_size: int = 0
"""
Expand All @@ -81,7 +81,7 @@ class EdlCommandDefinition:
"""list[EdlCommandDefinition]: List of response fields for the EDL command."""

def _dynamic_len(self, fields: list[EdlCommandField]) -> bool:
return True in [f.size_prefix != 0 for f in fields]
return True in [f.size_prefix != "" for f in fields]

def _decode(self, raw: bytes, fields: list[EdlCommandField]) -> tuple[Any]:

Expand All @@ -100,10 +100,11 @@ def _decode(self, raw: bytes, fields: list[EdlCommandField]) -> tuple[Any]:
fmt = _COMMAND_DATA_FMT[f.data_type]
data[f.name] = struct.unpack(fmt, tmp)[0]
elif f.data_type == "bytes":
if f.size_prefix != 0: # dynamic length in bits
data_type_size_raw = raw[offset : offset + f.size_prefix]
if f.size_prefix != "": # dynamic length in bits
size_prefix = int(f.size_prefix[4:]) // 8
data_type_size_raw = raw[offset : offset + size_prefix]
data_type_size = int.from_bytes(data_type_size_raw, "little") // 8
offset += f.size_prefix
offset += size_prefix
else: # fix_size
data_type_size = f.fixed_size
data[f.name] = raw[offset : offset + data_type_size]
Expand Down Expand Up @@ -142,8 +143,8 @@ def _encode(self, values: tuple[Any], fields: list[EdlCommandField]) -> bytes:
raw += struct.pack(fmt, v)
elif f.data_type == "bytes":
value = v
if f.size_prefix != 0: # dynamic length in bits
fmt = _COMMAND_DATA_FMT[f"uint{f.size_prefix * 8}"]
if f.size_prefix != "": # dynamic length in bits
fmt = _COMMAND_DATA_FMT[f.size_prefix]
raw += struct.pack(fmt, len(v) * 8)
else: # fixed length
value += b"\x00" * (f.fixed_size - len(value))
Expand Down
4 changes: 2 additions & 2 deletions oresat_configs/edl_cmd_defs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ commands:
- name: buffer
data_type: bytes
description: sdo data buffer to write
size_prefix: 4
size_prefix: "uint32"
response:
- name: error_code
data_type: uint32
Expand Down Expand Up @@ -232,4 +232,4 @@ commands:
- name: buffer
data_type: bytes
description: data buffer
size_prefix: 4
size_prefix: "uint32"
22 changes: 11 additions & 11 deletions oresat_configs/scripts/gen_xtce.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,14 +338,14 @@ def _add_edl(
loc_in_cont = ET.SubElement(
para_ref_entry, "LocationInContainerInBits", attrib={"referenceLocation": "nextEntry"}
)
fixed_value = ET.SubElement(loc_in_cont, "FixedValue")
fixed_value.text = str(32 * 8 + 16)
fixed_value_str = ET.SubElement(loc_in_cont, "FixedValue")
fixed_value_str.text = str(32 * 8 + 16)
para_ref_entry = _add_parameter_ref(uslp_entry_list, "uslp_fecf")
loc_in_cont = ET.SubElement(
para_ref_entry, "LocationInContainerInBits", attrib={"referenceLocation": "containerEnd"}
)
fixed_value = ET.SubElement(loc_in_cont, "FixedValue")
fixed_value.text = "16"
fixed_value_str = ET.SubElement(loc_in_cont, "FixedValue")
fixed_value_str.text = "16"

for cmd in config.edl_cmd_defs.values():
# add command
Expand Down Expand Up @@ -374,8 +374,8 @@ def _add_edl(
# add command argument(s)
if cmd.request:
for req_field in cmd.request:
if req_field.size_prefix > 0:
data_type = f"uint{req_field.size_prefix * 8}"
if req_field.size_prefix != "":
data_type = req_field.size_prefix
type_name = f"{data_type}_type"
name = f"{req_field.name}_size"
if type_name not in arg_types:
Expand Down Expand Up @@ -443,9 +443,9 @@ def _add_edl(
for res_field in cmd.response:
para_name = f"{cmd.name}_{res_field.name}"
para_ref = ""
if res_field.size_prefix > 0:
if res_field.size_prefix != "":
# add buffer size parameter
para_data_type = f"uint{res_field.size_prefix * 8}"
para_data_type = res_field.size_prefix
para_type_name = f"{para_name}_type"
if para_type_name not in para_types:
para_types.append(para_type_name)
Expand Down Expand Up @@ -514,7 +514,7 @@ def _add_parameter_type(
factor: float = 1,
default: Any = None,
value_descriptions: dict[str, int] = {},
size_prefix: int = 0,
size_prefix: str = "",
param_ref: str = "",
):

Expand Down Expand Up @@ -648,7 +648,7 @@ def _add_parameter_type(
bin_data_enc,
"SizeInBits",
)
if size_prefix != 0:
if size_prefix != "":
dyn_val = ET.SubElement(
size_in_bits,
"DynamicValue",
Expand Down Expand Up @@ -803,7 +803,7 @@ def _add_argument_type(arg_type_set: ET.Element, req_field: EdlCommandField, typ
attrib={"bitOrder": "mostSignificantBitFirst"},
)
size_bits = ET.SubElement(bytes_data, "SizeInBits")
if req_field.size_prefix:
if req_field.size_prefix != "":
dyn_val = ET.SubElement(size_bits, "DynamicValue")
ET.SubElement(
dyn_val,
Expand Down
20 changes: 10 additions & 10 deletions tests/test_edl.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,18 +88,18 @@ def test_edl_cmd_defs(self):
self._test_snake_case(req.name)
if req.name == "bytes":
self.assertTrue(
(req.fixed_size == 0) != (req.size_prefix == 0),
(req.fixed_size == 0) != (req.size_prefix == ""),
(
f"command {cmd.name} request field {req.name} has both fixed_size "
"and size_prefix set"
),
)
self.assertIn(
req.size_prefix,
[0, 1, 2, 4, 8],
["", "uint8", "uint16", "uint32"],
(
f"command {cmd.name} request field {req.name} size_prefix "
"size not a standard integer size or 0"
'uintX data type or ""'
),
)
elif req.name == "str":
Expand All @@ -119,9 +119,9 @@ def test_edl_cmd_defs(self):
)
size = 0
if req.data_type == "bytes":
if req.size_prefix > 0:
if req.size_prefix != "":
size = randint(1, 100) # set the random size to be reasonable
size_prefix = (size * 8).to_bytes(req.size_prefix, "little")
size_prefix = (size * 8).to_bytes(int(req.size_prefix[4:]) // 8, "little")
data = _gen_random_value(req.data_type, size)
test_values += (size_prefix + data,)
else:
Expand Down Expand Up @@ -149,18 +149,18 @@ def test_edl_cmd_defs(self):
self._test_snake_case(res.name)
if res.name == "bytes":
self.assertTrue(
(res.fixed_size == 0) != (res.size_prefix == 0),
(res.fixed_size == 0) != (res.size_prefix == ""),
(
f"command {cmd.name} request field {res.name} has both fixed_size "
"and size_prefix set"
),
)
self.assertIn(
res.size_prefix,
[0, 1, 2, 4, 8],
["", "uint8", "uint16", "uint32"],
(
f"command {cmd.name} request field {res.name} size_prefix "
"size not a standard integer size or 0"
'uintX data type or ""'
),
)
elif res.name == "str":
Expand All @@ -180,9 +180,9 @@ def test_edl_cmd_defs(self):
)
size = 0
if res.data_type == "bytes":
if res.size_prefix > 0:
if res.size_prefix != "":
size = randint(1, 100) # set the random size to be reasonable
size_prefix = (size * 8).to_bytes(res.size_prefix, "little")
size_prefix = (size * 8).to_bytes(int(res.size_prefix[4:]) // 8, "little")
data = _gen_random_value(res.data_type, size)
test_values += (size_prefix + data,)
else:
Expand Down

0 comments on commit 272cf4c

Please sign in to comment.