Skip to content

Commit

Permalink
Socketcand ext ID bug fixes, and implement channel{_info} and Message…
Browse files Browse the repository at this point in the history
… attributes (#1508)

* Handle extended arbitration id properly

socketcand uses the length of the arbitration id field to indicate
whether a frame is using extended id or not. 3 characters for standard,
8 for extended.

Prior to this fix, the arbitration id would be truncated to the lower 11
bits, or at times even garbage.

* Add is_rx attribute

* Populate channel{_info} and Message attributes
  • Loading branch information
faisal-shah committed Jan 28, 2023
1 parent 356f6f9 commit e96abcf
Showing 1 changed file with 15 additions and 2 deletions.
17 changes: 15 additions & 2 deletions can/interfaces/socketcand/socketcand.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,17 @@ def convert_ascii_message_to_can_message(ascii_msg: str) -> can.Message:
frame_string = ascii_msg[8:-2]
parts = frame_string.split(" ", 3)
can_id, timestamp = int(parts[0], 16), float(parts[1])
is_ext = len(parts[0]) != 3

data = bytearray.fromhex(parts[2])
can_dlc = len(data)
can_message = can.Message(
timestamp=timestamp, arbitration_id=can_id, data=data, dlc=can_dlc
timestamp=timestamp,
arbitration_id=can_id,
data=data,
dlc=can_dlc,
is_extended_id=is_ext,
is_rx=True,
)
return can_message

Expand All @@ -40,11 +46,15 @@ def convert_can_message_to_ascii_message(can_message: can.Message) -> str:
# Note: socketcan bus adds extended flag, remote_frame_flag & error_flag to id
# not sure if that is necessary here
can_id = can_message.arbitration_id
if can_message.is_extended_id:
can_id_string = f"{(can_id&0x1FFFFFFF):08X}"
else:
can_id_string = f"{(can_id&0x7FF):03X}"
# Note: seems like we cannot add CANFD_BRS (bitrate_switch) and CANFD_ESI (error_state_indicator) flags
data = can_message.data
length = can_message.dlc
bytes_string = " ".join(f"{x:x}" for x in data[0:length])
return f"< send {can_id:X} {length:X} {bytes_string} >"
return f"< send {can_id_string} {length:X} {bytes_string} >"


def connect_to_server(s, host, port):
Expand All @@ -70,6 +80,8 @@ def __init__(self, channel, host, port, can_filters=None, **kwargs):
self.__socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.__message_buffer = deque()
self.__receive_buffer = "" # i know string is not the most efficient here
self.channel = channel
self.channel_info = f"socketcand on {channel}@{host}:{port}"
connect_to_server(self.__socket, self.__host, self.__port)
self._expect_msg("< hi >")

Expand Down Expand Up @@ -139,6 +151,7 @@ def _recv_internal(self, timeout):
if parsed_can_message is None:
log.warning(f"Invalid Frame: {single_message}")
else:
parsed_can_message.channel = self.channel
self.__message_buffer.append(parsed_can_message)
buffer_view = buffer_view[end + 1 :]

Expand Down

0 comments on commit e96abcf

Please sign in to comment.