Skip to content

Adding direction to virutal bus messages #779

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

Merged
merged 10 commits into from
Mar 3, 2020
20 changes: 11 additions & 9 deletions can/interfaces/virtual.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,18 +85,20 @@ def _recv_internal(self, timeout):
def send(self, msg, timeout=None):
self._check_if_open()

msg_copy = deepcopy(msg)
msg_copy.timestamp = time.time()
msg_copy.channel = self.channel_id

timestamp = time.time()
# Add message to all listening on this channel
all_sent = True
for bus_queue in self.channel:
if bus_queue is not self.queue or self.receive_own_messages:
try:
bus_queue.put(msg_copy, block=True, timeout=timeout)
except queue.Full:
all_sent = False
if bus_queue is self.queue and not self.receive_own_messages:
continue
msg_copy = deepcopy(msg)
msg_copy.timestamp = timestamp
msg_copy.channel = self.channel_id
msg_copy.is_rx = bus_queue is not self.queue
try:
bus_queue.put(msg_copy, block=True, timeout=timeout)
except queue.Full:
all_sent = False
if not all_sent:
raise CanError("Could not send message to one or more recipients")

Expand Down
60 changes: 60 additions & 0 deletions test/back2back_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,66 @@ def test_dlc_less_than_eight(self):
msg = can.Message(is_extended_id=False, arbitration_id=0x300, data=[4, 5, 6])
self._send_and_receive(msg)

def test_message_direction(self):
# Verify that own message received has is_rx set to False while message
# received on the other virtual interfaces have is_rx set to True
if self.INTERFACE_1 != "virtual":
raise unittest.SkipTest(
"Message direction not yet implemented for socketcan"
)
bus3 = can.Bus(
channel=self.CHANNEL_2,
bustype=self.INTERFACE_2,
bitrate=self.BITRATE,
fd=TEST_CAN_FD,
single_handle=True,
receive_own_messages=True,
)
try:
msg = can.Message(
is_extended_id=False, arbitration_id=0x300, data=[2, 1, 3]
)
bus3.send(msg)
recv_msg_bus1 = self.bus1.recv(self.TIMEOUT)
recv_msg_bus2 = self.bus2.recv(self.TIMEOUT)
self_recv_msg_bus3 = bus3.recv(self.TIMEOUT)

self.assertTrue(recv_msg_bus1.is_rx)
self.assertTrue(recv_msg_bus2.is_rx)
self.assertFalse(self_recv_msg_bus3.is_rx)
finally:
bus3.shutdown()

def test_unique_message_instances(self):
# Verify that we have a different instances of message for each bus
if self.INTERFACE_1 != "virtual":
raise unittest.SkipTest("Not relevant for socketcan")
bus3 = can.Bus(
channel=self.CHANNEL_2,
bustype=self.INTERFACE_2,
bitrate=self.BITRATE,
fd=TEST_CAN_FD,
single_handle=True,
receive_own_messages=True,
)
try:
msg = can.Message(
is_extended_id=False, arbitration_id=0x300, data=[2, 1, 3]
)
bus3.send(msg)
recv_msg_bus1 = self.bus1.recv(self.TIMEOUT)
recv_msg_bus2 = self.bus2.recv(self.TIMEOUT)
self_recv_msg_bus3 = bus3.recv(self.TIMEOUT)

self._check_received_message(recv_msg_bus1, recv_msg_bus2)
self._check_received_message(recv_msg_bus2, self_recv_msg_bus3)

recv_msg_bus1.data[0] = 4
self.assertNotEqual(recv_msg_bus1.data, recv_msg_bus2.data)
self.assertEqual(recv_msg_bus2.data, self_recv_msg_bus3.data)
finally:
bus3.shutdown()

@unittest.skipUnless(TEST_CAN_FD, "Don't test CAN-FD")
def test_fd_message(self):
msg = can.Message(
Expand Down