1010import logging
1111import time
1212import os
13- from typing import Tuple , List
13+ from typing import List , Optional , Tuple
1414
1515try :
1616 # Try builtin Python 3 Windows API
@@ -333,112 +333,32 @@ def _apply_filters(self, filters):
333333 except VectorError as exc :
334334 LOG .warning ("Could not reset filters: %s" , exc )
335335
336- def _recv_internal (self , timeout ):
336+ def _recv_internal (
337+ self , timeout : Optional [float ]
338+ ) -> Tuple [Optional [Message ], bool ]:
337339 end_time = time .time () + timeout if timeout is not None else None
338340
339- if self .fd :
340- event = xlclass .XLcanRxEvent ()
341- else :
342- event = xlclass .XLevent ()
343-
344341 while True :
345- if self .fd :
346- try :
347- xldriver .xlCanReceive (self .port_handle , event )
348- except VectorError as exc :
349- if exc .error_code != xldefine .XL_Status .XL_ERR_QUEUE_IS_EMPTY .value :
350- raise
342+ try :
343+ if self .fd :
344+ msg = self ._recv_canfd ()
351345 else :
352- if (
353- event .tag
354- == xldefine .XL_CANFD_RX_EventTags .XL_CAN_EV_TAG_RX_OK .value
355- or event .tag
356- == xldefine .XL_CANFD_RX_EventTags .XL_CAN_EV_TAG_TX_OK .value
357- ):
358- msg_id = event .tagData .canRxOkMsg .canId
359- dlc = dlc2len (event .tagData .canRxOkMsg .dlc )
360- flags = event .tagData .canRxOkMsg .msgFlags
361- timestamp = event .timeStamp * 1e-9
362- channel = self .index_to_channel .get (event .chanIndex )
363- msg = Message (
364- timestamp = timestamp + self ._time_offset ,
365- arbitration_id = msg_id & 0x1FFFFFFF ,
366- is_extended_id = bool (
367- msg_id
368- & xldefine .XL_MessageFlagsExtended .XL_CAN_EXT_MSG_ID .value
369- ),
370- is_remote_frame = bool (
371- flags
372- & xldefine .XL_CANFD_RX_MessageFlags .XL_CAN_RXMSG_FLAG_RTR .value
373- ),
374- is_error_frame = bool (
375- flags
376- & xldefine .XL_CANFD_RX_MessageFlags .XL_CAN_RXMSG_FLAG_EF .value
377- ),
378- is_fd = bool (
379- flags
380- & xldefine .XL_CANFD_RX_MessageFlags .XL_CAN_RXMSG_FLAG_EDL .value
381- ),
382- error_state_indicator = bool (
383- flags
384- & xldefine .XL_CANFD_RX_MessageFlags .XL_CAN_RXMSG_FLAG_ESI .value
385- ),
386- bitrate_switch = bool (
387- flags
388- & xldefine .XL_CANFD_RX_MessageFlags .XL_CAN_RXMSG_FLAG_BRS .value
389- ),
390- dlc = dlc ,
391- data = event .tagData .canRxOkMsg .data [:dlc ],
392- channel = channel ,
393- )
394- return msg , self ._is_filtered
395- else :
396- self .handle_canfd_event (event )
346+ msg = self ._recv_can ()
397347
348+ except VectorError as exc :
349+ if exc .error_code != xldefine .XL_Status .XL_ERR_QUEUE_IS_EMPTY .value :
350+ raise
398351 else :
399- event_count = ctypes .c_uint (1 )
400- try :
401- xldriver .xlReceive (self .port_handle , event_count , event )
402- except VectorError as exc :
403- if exc .error_code != xldefine .XL_Status .XL_ERR_QUEUE_IS_EMPTY .value :
404- raise
405- else :
406- if event .tag == xldefine .XL_EventTags .XL_RECEIVE_MSG .value :
407- msg_id = event .tagData .msg .id
408- dlc = event .tagData .msg .dlc
409- flags = event .tagData .msg .flags
410- timestamp = event .timeStamp * 1e-9
411- channel = self .index_to_channel .get (event .chanIndex )
412- msg = Message (
413- timestamp = timestamp + self ._time_offset ,
414- arbitration_id = msg_id & 0x1FFFFFFF ,
415- is_extended_id = bool (
416- msg_id
417- & xldefine .XL_MessageFlagsExtended .XL_CAN_EXT_MSG_ID .value
418- ),
419- is_remote_frame = bool (
420- flags
421- & xldefine .XL_MessageFlags .XL_CAN_MSG_FLAG_REMOTE_FRAME .value
422- ),
423- is_error_frame = bool (
424- flags
425- & xldefine .XL_MessageFlags .XL_CAN_MSG_FLAG_ERROR_FRAME .value
426- ),
427- is_fd = False ,
428- dlc = dlc ,
429- data = event .tagData .msg .data [:dlc ],
430- channel = channel ,
431- )
432- return msg , self ._is_filtered
433- else :
434- self .handle_can_event (event )
352+ if msg :
353+ return msg , self ._is_filtered
435354
355+ # if no message was received, wait or return on timeout
436356 if end_time is not None and time .time () > end_time :
437357 return None , self ._is_filtered
438358
439359 if HAS_EVENTS :
440360 # Wait for receive event to occur
441- if timeout is None :
361+ if end_time is None :
442362 time_left_ms = INFINITE
443363 else :
444364 time_left = end_time - time .time ()
@@ -448,6 +368,97 @@ def _recv_internal(self, timeout):
448368 # Wait a short time until we try again
449369 time .sleep (self .poll_interval )
450370
371+ def _recv_canfd (self ) -> Optional [Message ]:
372+ xl_can_rx_event = xlclass .XLcanRxEvent ()
373+ xldriver .xlCanReceive (self .port_handle , xl_can_rx_event )
374+
375+ if (
376+ xl_can_rx_event .tag
377+ == xldefine .XL_CANFD_RX_EventTags .XL_CAN_EV_TAG_RX_OK .value
378+ ):
379+ is_rx = True
380+ data_struct = xl_can_rx_event .tagData .canRxOkMsg
381+ elif (
382+ xl_can_rx_event .tag
383+ == xldefine .XL_CANFD_RX_EventTags .XL_CAN_EV_TAG_TX_OK .value
384+ ):
385+ is_rx = False
386+ data_struct = xl_can_rx_event .tagData .canTxOkMsg
387+ else :
388+ self .handle_canfd_event (xl_can_rx_event )
389+ return
390+
391+ msg_id = data_struct .canId
392+ dlc = dlc2len (data_struct .dlc )
393+ flags = data_struct .msgFlags
394+ timestamp = xl_can_rx_event .timeStamp * 1e-9
395+ channel = self .index_to_channel .get (xl_can_rx_event .chanIndex )
396+
397+ msg = Message (
398+ timestamp = timestamp + self ._time_offset ,
399+ arbitration_id = msg_id & 0x1FFFFFFF ,
400+ is_extended_id = bool (
401+ msg_id & xldefine .XL_MessageFlagsExtended .XL_CAN_EXT_MSG_ID .value
402+ ),
403+ is_remote_frame = bool (
404+ flags & xldefine .XL_CANFD_RX_MessageFlags .XL_CAN_RXMSG_FLAG_RTR .value
405+ ),
406+ is_error_frame = bool (
407+ flags & xldefine .XL_CANFD_RX_MessageFlags .XL_CAN_RXMSG_FLAG_EF .value
408+ ),
409+ is_fd = bool (
410+ flags & xldefine .XL_CANFD_RX_MessageFlags .XL_CAN_RXMSG_FLAG_EDL .value
411+ ),
412+ bitrate_switch = bool (
413+ flags & xldefine .XL_CANFD_RX_MessageFlags .XL_CAN_RXMSG_FLAG_BRS .value
414+ ),
415+ error_state_indicator = bool (
416+ flags & xldefine .XL_CANFD_RX_MessageFlags .XL_CAN_RXMSG_FLAG_ESI .value
417+ ),
418+ is_rx = is_rx ,
419+ channel = channel ,
420+ dlc = dlc ,
421+ data = data_struct .data [:dlc ],
422+ )
423+ return msg
424+
425+ def _recv_can (self ) -> Optional [Message ]:
426+ xl_event = xlclass .XLevent ()
427+ event_count = ctypes .c_uint (1 )
428+ xldriver .xlReceive (self .port_handle , event_count , xl_event )
429+
430+ if xl_event .tag != xldefine .XL_EventTags .XL_RECEIVE_MSG .value :
431+ self .handle_can_event (xl_event )
432+ return
433+
434+ msg_id = xl_event .tagData .msg .id
435+ dlc = xl_event .tagData .msg .dlc
436+ flags = xl_event .tagData .msg .flags
437+ timestamp = xl_event .timeStamp * 1e-9
438+ channel = self .index_to_channel .get (xl_event .chanIndex )
439+
440+ msg = Message (
441+ timestamp = timestamp + self ._time_offset ,
442+ arbitration_id = msg_id & 0x1FFFFFFF ,
443+ is_extended_id = bool (
444+ msg_id & xldefine .XL_MessageFlagsExtended .XL_CAN_EXT_MSG_ID .value
445+ ),
446+ is_remote_frame = bool (
447+ flags & xldefine .XL_MessageFlags .XL_CAN_MSG_FLAG_REMOTE_FRAME .value
448+ ),
449+ is_error_frame = bool (
450+ flags & xldefine .XL_MessageFlags .XL_CAN_MSG_FLAG_ERROR_FRAME .value
451+ ),
452+ is_rx = not bool (
453+ flags & xldefine .XL_MessageFlags .XL_CAN_MSG_FLAG_TX_COMPLETED .value
454+ ),
455+ is_fd = False ,
456+ dlc = dlc ,
457+ data = xl_event .tagData .msg .data [:dlc ],
458+ channel = channel ,
459+ )
460+ return msg
461+
451462 def handle_can_event (self , event : xlclass .XLevent ) -> None :
452463 """Handle non-message CAN events.
453464
0 commit comments