Skip to content

Commit 902eac0

Browse files
authored
Merge pull request #852 from zariiii9003/vectorbus_recv_refactoring
Add Tx/Rx message direction to VectorBus
2 parents 035cedb + fe1051e commit 902eac0

File tree

1 file changed

+106
-95
lines changed

1 file changed

+106
-95
lines changed

can/interfaces/vector/canlib.py

Lines changed: 106 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import logging
1111
import time
1212
import os
13+
from typing import Optional, Tuple
1314

1415
try:
1516
# Try builtin Python 3 Windows API
@@ -342,113 +343,32 @@ def _apply_filters(self, filters):
342343
except VectorError as exc:
343344
LOG.warning("Could not reset filters: %s", exc)
344345

345-
def _recv_internal(self, timeout):
346+
def _recv_internal(
347+
self, timeout: Optional[float]
348+
) -> Tuple[Optional[Message], bool]:
346349
end_time = time.time() + timeout if timeout is not None else None
347350

348-
if self.fd:
349-
event = xlclass.XLcanRxEvent()
350-
else:
351-
event = xlclass.XLevent()
352-
event_count = ctypes.c_uint()
353-
354351
while True:
355-
if self.fd:
356-
try:
357-
xldriver.xlCanReceive(self.port_handle, event)
358-
except VectorError as exc:
359-
if exc.error_code != xldefine.XL_Status.XL_ERR_QUEUE_IS_EMPTY.value:
360-
raise
352+
try:
353+
if self.fd:
354+
msg = self._recv_canfd()
361355
else:
362-
if (
363-
event.tag
364-
== xldefine.XL_CANFD_RX_EventTags.XL_CAN_EV_TAG_RX_OK.value
365-
or event.tag
366-
== xldefine.XL_CANFD_RX_EventTags.XL_CAN_EV_TAG_TX_OK.value
367-
):
368-
msg_id = event.tagData.canRxOkMsg.canId
369-
dlc = dlc2len(event.tagData.canRxOkMsg.dlc)
370-
flags = event.tagData.canRxOkMsg.msgFlags
371-
timestamp = event.timeStamp * 1e-9
372-
channel = self.index_to_channel.get(event.chanIndex)
373-
msg = Message(
374-
timestamp=timestamp + self._time_offset,
375-
arbitration_id=msg_id & 0x1FFFFFFF,
376-
is_extended_id=bool(
377-
msg_id
378-
& xldefine.XL_MessageFlagsExtended.XL_CAN_EXT_MSG_ID.value
379-
),
380-
is_remote_frame=bool(
381-
flags
382-
& xldefine.XL_CANFD_RX_MessageFlags.XL_CAN_RXMSG_FLAG_RTR.value
383-
),
384-
is_error_frame=bool(
385-
flags
386-
& xldefine.XL_CANFD_RX_MessageFlags.XL_CAN_RXMSG_FLAG_EF.value
387-
),
388-
is_fd=bool(
389-
flags
390-
& xldefine.XL_CANFD_RX_MessageFlags.XL_CAN_RXMSG_FLAG_EDL.value
391-
),
392-
error_state_indicator=bool(
393-
flags
394-
& xldefine.XL_CANFD_RX_MessageFlags.XL_CAN_RXMSG_FLAG_ESI.value
395-
),
396-
bitrate_switch=bool(
397-
flags
398-
& xldefine.XL_CANFD_RX_MessageFlags.XL_CAN_RXMSG_FLAG_BRS.value
399-
),
400-
dlc=dlc,
401-
data=event.tagData.canRxOkMsg.data[:dlc],
402-
channel=channel,
403-
)
404-
return msg, self._is_filtered
405-
else:
406-
self.handle_canfd_event(event)
356+
msg = self._recv_can()
407357

358+
except VectorError as exc:
359+
if exc.error_code != xldefine.XL_Status.XL_ERR_QUEUE_IS_EMPTY.value:
360+
raise
408361
else:
409-
event_count.value = 1
410-
try:
411-
xldriver.xlReceive(self.port_handle, event_count, event)
412-
except VectorError as exc:
413-
if exc.error_code != xldefine.XL_Status.XL_ERR_QUEUE_IS_EMPTY.value:
414-
raise
415-
else:
416-
if event.tag == xldefine.XL_EventTags.XL_RECEIVE_MSG.value:
417-
msg_id = event.tagData.msg.id
418-
dlc = event.tagData.msg.dlc
419-
flags = event.tagData.msg.flags
420-
timestamp = event.timeStamp * 1e-9
421-
channel = self.index_to_channel.get(event.chanIndex)
422-
msg = Message(
423-
timestamp=timestamp + self._time_offset,
424-
arbitration_id=msg_id & 0x1FFFFFFF,
425-
is_extended_id=bool(
426-
msg_id
427-
& xldefine.XL_MessageFlagsExtended.XL_CAN_EXT_MSG_ID.value
428-
),
429-
is_remote_frame=bool(
430-
flags
431-
& xldefine.XL_MessageFlags.XL_CAN_MSG_FLAG_REMOTE_FRAME.value
432-
),
433-
is_error_frame=bool(
434-
flags
435-
& xldefine.XL_MessageFlags.XL_CAN_MSG_FLAG_ERROR_FRAME.value
436-
),
437-
is_fd=False,
438-
dlc=dlc,
439-
data=event.tagData.msg.data[:dlc],
440-
channel=channel,
441-
)
442-
return msg, self._is_filtered
443-
else:
444-
self.handle_can_event(event)
362+
if msg:
363+
return msg, self._is_filtered
445364

365+
# if no message was received, wait or return on timeout
446366
if end_time is not None and time.time() > end_time:
447367
return None, self._is_filtered
448368

449369
if HAS_EVENTS:
450370
# Wait for receive event to occur
451-
if timeout is None:
371+
if end_time is None:
452372
time_left_ms = INFINITE
453373
else:
454374
time_left = end_time - time.time()
@@ -458,6 +378,97 @@ def _recv_internal(self, timeout):
458378
# Wait a short time until we try again
459379
time.sleep(self.poll_interval)
460380

381+
def _recv_canfd(self) -> Optional[Message]:
382+
xl_can_rx_event = xlclass.XLcanRxEvent()
383+
xldriver.xlCanReceive(self.port_handle, xl_can_rx_event)
384+
385+
if (
386+
xl_can_rx_event.tag
387+
== xldefine.XL_CANFD_RX_EventTags.XL_CAN_EV_TAG_RX_OK.value
388+
):
389+
is_rx = True
390+
data_struct = xl_can_rx_event.tagData.canRxOkMsg
391+
elif (
392+
xl_can_rx_event.tag
393+
== xldefine.XL_CANFD_RX_EventTags.XL_CAN_EV_TAG_TX_OK.value
394+
):
395+
is_rx = False
396+
data_struct = xl_can_rx_event.tagData.canTxOkMsg
397+
else:
398+
self.handle_canfd_event(xl_can_rx_event)
399+
return
400+
401+
msg_id = data_struct.canId
402+
dlc = dlc2len(data_struct.dlc)
403+
flags = data_struct.msgFlags
404+
timestamp = xl_can_rx_event.timeStamp * 1e-9
405+
channel = self.index_to_channel.get(xl_can_rx_event.chanIndex)
406+
407+
msg = Message(
408+
timestamp=timestamp + self._time_offset,
409+
arbitration_id=msg_id & 0x1FFFFFFF,
410+
is_extended_id=bool(
411+
msg_id & xldefine.XL_MessageFlagsExtended.XL_CAN_EXT_MSG_ID.value
412+
),
413+
is_remote_frame=bool(
414+
flags & xldefine.XL_CANFD_RX_MessageFlags.XL_CAN_RXMSG_FLAG_RTR.value
415+
),
416+
is_error_frame=bool(
417+
flags & xldefine.XL_CANFD_RX_MessageFlags.XL_CAN_RXMSG_FLAG_EF.value
418+
),
419+
is_fd=bool(
420+
flags & xldefine.XL_CANFD_RX_MessageFlags.XL_CAN_RXMSG_FLAG_EDL.value
421+
),
422+
bitrate_switch=bool(
423+
flags & xldefine.XL_CANFD_RX_MessageFlags.XL_CAN_RXMSG_FLAG_BRS.value
424+
),
425+
error_state_indicator=bool(
426+
flags & xldefine.XL_CANFD_RX_MessageFlags.XL_CAN_RXMSG_FLAG_ESI.value
427+
),
428+
is_rx=is_rx,
429+
channel=channel,
430+
dlc=dlc,
431+
data=data_struct.data[:dlc],
432+
)
433+
return msg
434+
435+
def _recv_can(self) -> Optional[Message]:
436+
xl_event = xlclass.XLevent()
437+
event_count = ctypes.c_uint(1)
438+
xldriver.xlReceive(self.port_handle, event_count, xl_event)
439+
440+
if xl_event.tag != xldefine.XL_EventTags.XL_RECEIVE_MSG.value:
441+
self.handle_can_event(xl_event)
442+
return
443+
444+
msg_id = xl_event.tagData.msg.id
445+
dlc = xl_event.tagData.msg.dlc
446+
flags = xl_event.tagData.msg.flags
447+
timestamp = xl_event.timeStamp * 1e-9
448+
channel = self.index_to_channel.get(xl_event.chanIndex)
449+
450+
msg = Message(
451+
timestamp=timestamp + self._time_offset,
452+
arbitration_id=msg_id & 0x1FFFFFFF,
453+
is_extended_id=bool(
454+
msg_id & xldefine.XL_MessageFlagsExtended.XL_CAN_EXT_MSG_ID.value
455+
),
456+
is_remote_frame=bool(
457+
flags & xldefine.XL_MessageFlags.XL_CAN_MSG_FLAG_REMOTE_FRAME.value
458+
),
459+
is_error_frame=bool(
460+
flags & xldefine.XL_MessageFlags.XL_CAN_MSG_FLAG_ERROR_FRAME.value
461+
),
462+
is_rx=not bool(
463+
flags & xldefine.XL_MessageFlags.XL_CAN_MSG_FLAG_TX_COMPLETED.value
464+
),
465+
is_fd=False,
466+
dlc=dlc,
467+
data=xl_event.tagData.msg.data[:dlc],
468+
channel=channel,
469+
)
470+
return msg
471+
461472
def handle_can_event(self, event: xlclass.XLevent) -> None:
462473
"""Handle non-message CAN events.
463474

0 commit comments

Comments
 (0)