Skip to content

Add APP_TEXT object type to BLFReader #1942

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion can/io/blf.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,13 @@ class BLFParseError(Exception):
# group name length, marker name length, description length
GLOBAL_MARKER_STRUCT = struct.Struct("<LLL3xBLLL12x")

# APP_TEXT object type, 4 reserved bytes, text length, 4 more
# reserved bytes
APP_TEXT_HEADER_STRUCT = struct.Struct("<I4sI4s")

CAN_MESSAGE = 1
LOG_CONTAINER = 10
APP_TEXT = 65
CAN_ERROR_EXT = 73
CAN_MESSAGE2 = 86
GLOBAL_MARKER = 96
Expand Down Expand Up @@ -142,7 +146,12 @@ class BLFReader(BinaryIOMessageReader):
Iterator of CAN messages from a Binary Logging File.

Only CAN messages and error frames are supported. Other object types are
silently ignored.
silently ignored. APP_TEXT objects are parsed into `self.app_text` when
they are encountered while iterating.

self.app_text is a list of tuples containing the parsed app_text objects. The
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Take a look at the sphinx documention on how to properly document instance attributes.

interpretation of this data is context-specific and out of scope of the
BLFReader class.
"""

file: BinaryIO
Expand Down Expand Up @@ -173,6 +182,11 @@ def __init__(
)
# Read rest of header
self.file.read(header[1] - FILE_HEADER_STRUCT.size)

# APP_TEXT objects are appended when type 65 is encountered
# while iterating
self.app_text: List[Tuple] = []
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of a tuple, i'd prefer an AppText or BlfAppText dataclass with timestamp, source and text attributes.


self._tail = b""
self._pos = 0

Expand Down Expand Up @@ -230,6 +244,8 @@ def _parse_data(self, data):
unpack_can_fd_64_msg = CAN_FD_MSG_64_STRUCT.unpack_from
can_fd_64_msg_size = CAN_FD_MSG_64_STRUCT.size
unpack_can_error_ext = CAN_ERROR_EXT_STRUCT.unpack_from
app_text_header = APP_TEXT_HEADER_STRUCT.unpack_from
app_text_header_size = APP_TEXT_HEADER_STRUCT.size

start_timestamp = self.start_timestamp
max_pos = len(data)
Expand Down Expand Up @@ -370,6 +386,17 @@ def _parse_data(self, data):
data=msg_data,
channel=channel - 1,
)
elif obj_type == APP_TEXT:
# When we encounter an app_text object, parse it and save it in
# self.app_text and continue looping for a message to return
source, reserved1, text_size, reserved2 = app_text_header(data, pos)
# Read until the end of the block rather than using the
# untrusted size bytes
text = data[pos + app_text_header_size : next_pos]
# Append the app_text block, including the size bytes read
# from the header. Caller may determine what to do if there's
# a mismatch in the actual text length
self.app_text.append((source, reserved1, text_size, reserved2, text))

pos = next_pos

Expand Down
Loading