10
10
import logging
11
11
import time
12
12
import os
13
+ from typing import Optional , Tuple
13
14
14
15
try :
15
16
# Try builtin Python 3 Windows API
@@ -342,113 +343,32 @@ def _apply_filters(self, filters):
342
343
except VectorError as exc :
343
344
LOG .warning ("Could not reset filters: %s" , exc )
344
345
345
- def _recv_internal (self , timeout ):
346
+ def _recv_internal (
347
+ self , timeout : Optional [float ]
348
+ ) -> Tuple [Optional [Message ], bool ]:
346
349
end_time = time .time () + timeout if timeout is not None else None
347
350
348
- if self .fd :
349
- event = xlclass .XLcanRxEvent ()
350
- else :
351
- event = xlclass .XLevent ()
352
- event_count = ctypes .c_uint ()
353
-
354
351
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 ()
361
355
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 ()
407
357
358
+ except VectorError as exc :
359
+ if exc .error_code != xldefine .XL_Status .XL_ERR_QUEUE_IS_EMPTY .value :
360
+ raise
408
361
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
445
364
365
+ # if no message was received, wait or return on timeout
446
366
if end_time is not None and time .time () > end_time :
447
367
return None , self ._is_filtered
448
368
449
369
if HAS_EVENTS :
450
370
# Wait for receive event to occur
451
- if timeout is None :
371
+ if end_time is None :
452
372
time_left_ms = INFINITE
453
373
else :
454
374
time_left = end_time - time .time ()
@@ -458,6 +378,97 @@ def _recv_internal(self, timeout):
458
378
# Wait a short time until we try again
459
379
time .sleep (self .poll_interval )
460
380
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
+
461
472
def handle_can_event (self , event : xlclass .XLevent ) -> None :
462
473
"""Handle non-message CAN events.
463
474
0 commit comments