Skip to content
Merged
Show file tree
Hide file tree
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
4 changes: 3 additions & 1 deletion docs/CANMODULE-UTILS.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ Examples of CAN frames are:

```bash
001#AA // Message of 1 byte (AA) and standard id 1
FFFA#BB.BB // Message of 2 bytes (BB BB) and extended if FFFA
FFFA#BB.BB // Message of 2 bytes (BB BB) and extended id FFFA
001#R4 // Remote request message with length 4 and standard id 1
00000123#AA // Message of 1 byte (AA) with small ID sent as extended format
00000123#R4 // Remote request of length 4 with small ID sent as extended format
```

### gen
Expand Down
54 changes: 40 additions & 14 deletions python/canmodule-utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,18 +125,46 @@ def parse_can_frame(can_frame_str):
- "len" (int): The number of data bytes for a remote request frame.
- "data" (list of str): The hexadecimal representation of the CAN data bytes for a data frame.
"""
if "R" in can_frame_str:
can_id, len_data = can_frame_str.split("#R")
frame = {
"can_id": can_id,
"len": int(len_data),
}
if "#" not in can_frame_str:
raise ValueError("Missing '#' delimiter")

can_id, payload = can_frame_str.split("#", 1)
if not can_id:
raise ValueError("Missing CAN ID")

try:
can_id_value = int(can_id, 16)
except ValueError as error:
raise ValueError(f"Invalid CAN ID '{can_id}'") from error

if can_id_value > 0x1FFFFFFF:
raise ValueError(f"CAN ID 0x{can_id_value:X} is out of range (max 0x1FFFFFFF)")

frame = {
"can_id": can_id,
# cansend-like rule: 8 hex digits force extended format even for small IDs.
"id_format_hint": "extended" if len(can_id) == 8 else "auto",
}

if payload.startswith(("R", "r")):
len_data = payload[1:]
if len_data:
try:
requested_len = int(len_data)
except ValueError as error:
raise ValueError(
f"Invalid remote request length '{len_data}'"
) from error
else:
requested_len = 0

if requested_len < 0 or requested_len > 8:
raise ValueError("Remote request length must be between 0 and 8")

frame["len"] = requested_len
else:
can_id, data = can_frame_str.split("#")
frame = {
"can_id": can_id,
"data": data.split("."),
}
frame["data"] = payload.split(".")

return frame


Expand Down Expand Up @@ -222,9 +250,7 @@ def process_frame(frame):
"""
can_id = int(frame["can_id"], 16)

extended_id = False
if can_id > 0x7FF: # More than 11 bits long
extended_id = True
extended_id = frame.get("id_format_hint") == "extended" or can_id > 0x7FF

remote_request = False
flags = 0
Expand Down