10
10
import logging
11
11
import time
12
12
import os
13
- from typing import Tuple , List
13
+ from typing import List , Optional , Tuple
14
14
15
15
try :
16
16
# Try builtin Python 3 Windows API
@@ -333,112 +333,32 @@ def _apply_filters(self, filters):
333
333
except VectorError as exc :
334
334
LOG .warning ("Could not reset filters: %s" , exc )
335
335
336
- def _recv_internal (self , timeout ):
336
+ def _recv_internal (
337
+ self , timeout : Optional [float ]
338
+ ) -> Tuple [Optional [Message ], bool ]:
337
339
end_time = time .time () + timeout if timeout is not None else None
338
340
339
- if self .fd :
340
- event = xlclass .XLcanRxEvent ()
341
- else :
342
- event = xlclass .XLevent ()
343
-
344
341
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 ()
351
345
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 ()
397
347
348
+ except VectorError as exc :
349
+ if exc .error_code != xldefine .XL_Status .XL_ERR_QUEUE_IS_EMPTY .value :
350
+ raise
398
351
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
435
354
355
+ # if no message was received, wait or return on timeout
436
356
if end_time is not None and time .time () > end_time :
437
357
return None , self ._is_filtered
438
358
439
359
if HAS_EVENTS :
440
360
# Wait for receive event to occur
441
- if timeout is None :
361
+ if end_time is None :
442
362
time_left_ms = INFINITE
443
363
else :
444
364
time_left = end_time - time .time ()
@@ -448,6 +368,97 @@ def _recv_internal(self, timeout):
448
368
# Wait a short time until we try again
449
369
time .sleep (self .poll_interval )
450
370
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
+
451
462
def handle_can_event (self , event : xlclass .XLevent ) -> None :
452
463
"""Handle non-message CAN events.
453
464
0 commit comments