diff --git a/can/interfaces/socketcand/socketcand.py b/can/interfaces/socketcand/socketcand.py index d401102f7..2cea78b9e 100644 --- a/can/interfaces/socketcand/socketcand.py +++ b/can/interfaces/socketcand/socketcand.py @@ -176,6 +176,13 @@ def convert_ascii_message_to_can_message(ascii_msg: str) -> can.Message: 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 + if can_message.is_remote_frame: + # The send command is "< send id dlc [data]* >", there is no field for + # the remote request flag, so the frame would go out as a normal one + raise can.CanOperationError( + "socketcand cannot send remote frames, its send command has no " + "remote request flag" + ) can_id = can_message.arbitration_id if can_message.is_extended_id: can_id_string = f"{(can_id&0x1FFFFFFF):08X}" diff --git a/doc/changelog.d/2091.fixed.rst b/doc/changelog.d/2091.fixed.rst new file mode 100644 index 000000000..43d0e1d90 --- /dev/null +++ b/doc/changelog.d/2091.fixed.rst @@ -0,0 +1 @@ +Refuse to send remote frames on the ``socketcand`` interface instead of sending them as normal frames. The socketcand protocol has no remote request flag. (:issue:`2091`) diff --git a/test/test_socketcand.py b/test/test_socketcand.py index 7050b9f20..9d168d012 100644 --- a/test/test_socketcand.py +++ b/test/test_socketcand.py @@ -42,5 +42,32 @@ def test_missing_ending_character(self): self.assertIsNone(msg) +class TestConvertCanMessageToAsciiMessage(unittest.TestCase): + def test_standard_frame(self): + msg = can.Message( + arbitration_id=0x123, data=[0x01, 0x02, 0x03, 0x04], is_extended_id=False + ) + self.assertEqual( + socketcand.convert_can_message_to_ascii_message(msg), + "< send 123 4 1 2 3 4 >", + ) + + def test_extended_frame(self): + msg = can.Message( + arbitration_id=0x1AAAAAAA, data=[0x01, 0xF1], is_extended_id=True + ) + self.assertEqual( + socketcand.convert_can_message_to_ascii_message(msg), + "< send 1AAAAAAA 2 1 f1 >", + ) + + def test_remote_frame_is_refused(self): + msg = can.Message( + arbitration_id=0x403, is_remote_frame=True, is_extended_id=False + ) + with self.assertRaises(can.CanOperationError): + socketcand.convert_can_message_to_ascii_message(msg) + + if __name__ == "__main__": unittest.main()