21
21
log_tx = log .getChild ("tx" )
22
22
log_rx = log .getChild ("rx" )
23
23
24
- try :
25
- import fcntl
26
- except ImportError :
27
- log .error ("fcntl not available on this platform" )
28
-
29
-
30
24
try :
31
25
from socket import CMSG_SPACE
32
26
44
38
LimitedDurationCyclicSendTaskABC ,
45
39
)
46
40
from can .typechecking import CanFilters
47
- from can .interfaces .socketcan . constants import * # CAN_RAW, CAN_*_FLAG
41
+ from can .interfaces .socketcan import constants
48
42
from can .interfaces .socketcan .utils import pack_filters , find_available_interfaces
49
43
50
44
@@ -177,9 +171,9 @@ def build_can_frame(msg: Message) -> bytes:
177
171
can_id = _compose_arbitration_id (msg )
178
172
flags = 0
179
173
if msg .bitrate_switch :
180
- flags |= CANFD_BRS
174
+ flags |= constants . CANFD_BRS
181
175
if msg .error_state_indicator :
182
- flags |= CANFD_ESI
176
+ flags |= constants . CANFD_ESI
183
177
max_len = 64 if msg .is_fd else 8
184
178
data = bytes (msg .data ).ljust (max_len , b"\x00 " )
185
179
return CAN_FRAME_HEADER_STRUCT .pack (can_id , msg .dlc , flags ) + data
@@ -211,7 +205,7 @@ def build_bcm_header(
211
205
212
206
213
207
def build_bcm_tx_delete_header (can_id : int , flags : int ) -> bytes :
214
- opcode = CAN_BCM_TX_DELETE
208
+ opcode = constants . CAN_BCM_TX_DELETE
215
209
return build_bcm_header (opcode , flags , 0 , 0 , 0 , 0 , 0 , can_id , 1 )
216
210
217
211
@@ -223,13 +217,13 @@ def build_bcm_transmit_header(
223
217
msg_flags : int ,
224
218
nframes : int = 1 ,
225
219
) -> bytes :
226
- opcode = CAN_BCM_TX_SETUP
220
+ opcode = constants . CAN_BCM_TX_SETUP
227
221
228
- flags = msg_flags | SETTIMER | STARTTIMER
222
+ flags = msg_flags | constants . SETTIMER | constants . STARTTIMER
229
223
230
224
if initial_period > 0 :
231
225
# Note `TX_COUNTEVT` creates the message TX_EXPIRED when count expires
232
- flags |= TX_COUNTEVT
226
+ flags |= constants . TX_COUNTEVT
233
227
234
228
def split_time (value : float ) -> Tuple [int , int ]:
235
229
"""Given seconds as a float, return whole seconds and microseconds"""
@@ -254,20 +248,22 @@ def split_time(value: float) -> Tuple[int, int]:
254
248
255
249
256
250
def build_bcm_update_header (can_id : int , msg_flags : int , nframes : int = 1 ) -> bytes :
257
- return build_bcm_header (CAN_BCM_TX_SETUP , msg_flags , 0 , 0 , 0 , 0 , 0 , can_id , nframes )
251
+ return build_bcm_header (
252
+ constants .CAN_BCM_TX_SETUP , msg_flags , 0 , 0 , 0 , 0 , 0 , can_id , nframes
253
+ )
258
254
259
255
260
256
def dissect_can_frame (frame : bytes ) -> Tuple [int , int , int , bytes ]:
261
257
can_id , can_dlc , flags = CAN_FRAME_HEADER_STRUCT .unpack_from (frame )
262
- if len (frame ) != CANFD_MTU :
258
+ if len (frame ) != constants . CANFD_MTU :
263
259
# Flags not valid in non-FD frames
264
260
flags = 0
265
261
return can_id , can_dlc , flags , frame [8 : 8 + can_dlc ]
266
262
267
263
268
264
def create_bcm_socket (channel : str ) -> socket .socket :
269
265
"""create a broadcast manager socket and connect to the given interface"""
270
- s = socket .socket (PF_CAN , socket .SOCK_DGRAM , CAN_BCM )
266
+ s = socket .socket (constants . PF_CAN , socket .SOCK_DGRAM , constants . CAN_BCM )
271
267
s .connect ((channel ,))
272
268
return s
273
269
@@ -297,13 +293,13 @@ def _compose_arbitration_id(message: Message) -> int:
297
293
can_id = message .arbitration_id
298
294
if message .is_extended_id :
299
295
log .debug ("sending an extended id type message" )
300
- can_id |= CAN_EFF_FLAG
296
+ can_id |= constants . CAN_EFF_FLAG
301
297
if message .is_remote_frame :
302
298
log .debug ("requesting a remote frame" )
303
- can_id |= CAN_RTR_FLAG
299
+ can_id |= constants . CAN_RTR_FLAG
304
300
if message .is_error_frame :
305
301
log .debug ("sending error frame" )
306
- can_id |= CAN_ERR_FLAG
302
+ can_id |= constants . CAN_ERR_FLAG
307
303
return can_id
308
304
309
305
@@ -354,7 +350,7 @@ def _tx_setup(
354
350
) -> None :
355
351
# Create a low level packed frame to pass to the kernel
356
352
body = bytearray ()
357
- self .flags = CAN_FD_FRAME if messages [0 ].is_fd else 0
353
+ self .flags = constants . CAN_FD_FRAME if messages [0 ].is_fd else 0
358
354
359
355
if self .duration :
360
356
count = int (self .duration / self .period )
@@ -380,7 +376,7 @@ def _check_bcm_task(self) -> None:
380
376
# Do a TX_READ on a task ID, and check if we get EINVAL. If so,
381
377
# then we are referring to a CAN message with an existing ID
382
378
check_header = build_bcm_header (
383
- opcode = CAN_BCM_TX_READ ,
379
+ opcode = constants . CAN_BCM_TX_READ ,
384
380
flags = 0 ,
385
381
count = 0 ,
386
382
ival1_seconds = 0 ,
@@ -391,7 +387,7 @@ def _check_bcm_task(self) -> None:
391
387
nframes = 0 ,
392
388
)
393
389
log .debug (
394
- f "Reading properties of (cyclic) transmission task id={ self .task_id } " ,
390
+ "Reading properties of (cyclic) transmission task id=%d" , self .task_id
395
391
)
396
392
try :
397
393
self .bcm_socket .send (check_header )
@@ -495,7 +491,7 @@ def create_socket() -> socket.socket:
495
491
"""Creates a raw CAN socket. The socket will
496
492
be returned unbound to any interface.
497
493
"""
498
- sock = socket .socket (PF_CAN , socket .SOCK_RAW , CAN_RAW )
494
+ sock = socket .socket (constants . PF_CAN , socket .SOCK_RAW , constants . CAN_RAW )
499
495
500
496
log .info ("Created a socket" )
501
497
@@ -534,7 +530,7 @@ def capture_message(
534
530
# Fetching the Arb ID, DLC and Data
535
531
try :
536
532
cf , ancillary_data , msg_flags , addr = sock .recvmsg (
537
- CANFD_MTU , RECEIVED_ANCILLARY_BUFFER_SIZE
533
+ constants . CANFD_MTU , RECEIVED_ANCILLARY_BUFFER_SIZE
538
534
)
539
535
if get_channel :
540
536
channel = addr [0 ] if isinstance (addr , tuple ) else addr
@@ -549,7 +545,7 @@ def capture_message(
549
545
assert len (ancillary_data ) == 1 , "only requested a single extra field"
550
546
cmsg_level , cmsg_type , cmsg_data = ancillary_data [0 ]
551
547
assert (
552
- cmsg_level == socket .SOL_SOCKET and cmsg_type == SO_TIMESTAMPNS
548
+ cmsg_level == socket .SOL_SOCKET and cmsg_type == constants . SO_TIMESTAMPNS
553
549
), "received control message type that was not requested"
554
550
# see https://man7.org/linux/man-pages/man3/timespec.3.html -> struct timespec for details
555
551
seconds , nanoseconds = RECEIVED_TIMESTAMP_STRUCT .unpack_from (cmsg_data )
@@ -564,12 +560,12 @@ def capture_message(
564
560
# #define CAN_EFF_FLAG 0x80000000U /* EFF/SFF is set in the MSB */
565
561
# #define CAN_RTR_FLAG 0x40000000U /* remote transmission request */
566
562
# #define CAN_ERR_FLAG 0x20000000U /* error frame */
567
- is_extended_frame_format = bool (can_id & CAN_EFF_FLAG )
568
- is_remote_transmission_request = bool (can_id & CAN_RTR_FLAG )
569
- is_error_frame = bool (can_id & CAN_ERR_FLAG )
570
- is_fd = len (cf ) == CANFD_MTU
571
- bitrate_switch = bool (flags & CANFD_BRS )
572
- error_state_indicator = bool (flags & CANFD_ESI )
563
+ is_extended_frame_format = bool (can_id & constants . CAN_EFF_FLAG )
564
+ is_remote_transmission_request = bool (can_id & constants . CAN_RTR_FLAG )
565
+ is_error_frame = bool (can_id & constants . CAN_ERR_FLAG )
566
+ is_fd = len (cf ) == constants . CANFD_MTU
567
+ bitrate_switch = bool (flags & constants . CANFD_BRS )
568
+ error_state_indicator = bool (flags & constants . CANFD_ESI )
573
569
574
570
# Section 4.7.1: MSG_DONTROUTE: set when the received frame was created on the local host.
575
571
is_rx = not bool (msg_flags & socket .MSG_DONTROUTE )
@@ -625,8 +621,8 @@ def __init__(
625
621
) -> None :
626
622
"""Creates a new socketcan bus.
627
623
628
- If setting some socket options fails, an error will be printed but no exception will be thrown.
629
- This includes enabling:
624
+ If setting some socket options fails, an error will be printed
625
+ but no exception will be thrown. This includes enabling:
630
626
631
627
- that own messages should be received,
632
628
- CAN-FD frames and
@@ -656,7 +652,7 @@ def __init__(
656
652
"""
657
653
self .socket = create_socket ()
658
654
self .channel = channel
659
- self .channel_info = "socketcan channel '%s'" % channel
655
+ self .channel_info = f "socketcan channel '{ channel } '"
660
656
self ._bcm_sockets : Dict [str , socket .socket ] = {}
661
657
self ._is_filtered = False
662
658
self ._task_id = 0
@@ -665,39 +661,47 @@ def __init__(
665
661
# set the local_loopback parameter
666
662
try :
667
663
self .socket .setsockopt (
668
- SOL_CAN_RAW , CAN_RAW_LOOPBACK , 1 if local_loopback else 0
664
+ constants .SOL_CAN_RAW ,
665
+ constants .CAN_RAW_LOOPBACK ,
666
+ 1 if local_loopback else 0 ,
669
667
)
670
668
except OSError as error :
671
669
log .error ("Could not set local loopback flag(%s)" , error )
672
670
673
671
# set the receive_own_messages parameter
674
672
try :
675
673
self .socket .setsockopt (
676
- SOL_CAN_RAW , CAN_RAW_RECV_OWN_MSGS , 1 if receive_own_messages else 0
674
+ constants .SOL_CAN_RAW ,
675
+ constants .CAN_RAW_RECV_OWN_MSGS ,
676
+ 1 if receive_own_messages else 0 ,
677
677
)
678
678
except OSError as error :
679
679
log .error ("Could not receive own messages (%s)" , error )
680
680
681
681
# enable CAN-FD frames if desired
682
682
if fd :
683
683
try :
684
- self .socket .setsockopt (SOL_CAN_RAW , CAN_RAW_FD_FRAMES , 1 )
684
+ self .socket .setsockopt (
685
+ constants .SOL_CAN_RAW , constants .CAN_RAW_FD_FRAMES , 1
686
+ )
685
687
except OSError as error :
686
688
log .error ("Could not enable CAN-FD frames (%s)" , error )
687
689
688
690
if not ignore_rx_error_frames :
689
691
# enable error frames
690
692
try :
691
- self .socket .setsockopt (SOL_CAN_RAW , CAN_RAW_ERR_FILTER , 0x1FFFFFFF )
693
+ self .socket .setsockopt (
694
+ constants .SOL_CAN_RAW , constants .CAN_RAW_ERR_FILTER , 0x1FFFFFFF
695
+ )
692
696
except OSError as error :
693
697
log .error ("Could not enable error frames (%s)" , error )
694
698
695
699
# enable nanosecond resolution timestamping
696
700
# we can always do this since
697
- # 1) is is guaranteed to be at least as precise as without
701
+ # 1) it is guaranteed to be at least as precise as without
698
702
# 2) it is available since Linux 2.6.22, and CAN support was only added afterward
699
703
# so this is always supported by the kernel
700
- self .socket .setsockopt (socket .SOL_SOCKET , SO_TIMESTAMPNS , 1 )
704
+ self .socket .setsockopt (socket .SOL_SOCKET , constants . SO_TIMESTAMPNS , 1 )
701
705
702
706
bind_socket (self .socket , channel )
703
707
kwargs .update (
@@ -830,7 +834,9 @@ def _send_periodic_internal(
830
834
general the message will be sent at the given rate until at
831
835
least *duration* seconds.
832
836
"""
833
- msgs = LimitedDurationCyclicSendTaskABC ._check_and_convert_messages (msgs )
837
+ msgs = LimitedDurationCyclicSendTaskABC ._check_and_convert_messages ( # pylint: disable=protected-access
838
+ msgs
839
+ )
834
840
835
841
msgs_channel = str (msgs [0 ].channel ) if msgs [0 ].channel else None
836
842
bcm_socket = self ._get_bcm_socket (msgs_channel or self .channel )
@@ -850,7 +856,9 @@ def _get_bcm_socket(self, channel: str) -> socket.socket:
850
856
851
857
def _apply_filters (self , filters : Optional [can .typechecking .CanFilters ]) -> None :
852
858
try :
853
- self .socket .setsockopt (SOL_CAN_RAW , CAN_RAW_FILTER , pack_filters (filters ))
859
+ self .socket .setsockopt (
860
+ constants .SOL_CAN_RAW , constants .CAN_RAW_FILTER , pack_filters (filters )
861
+ )
854
862
except OSError as error :
855
863
# fall back to "software filtering" (= not in kernel)
856
864
self ._is_filtered = False
@@ -899,8 +907,6 @@ def sender(event: threading.Event) -> None:
899
907
sender_socket .send (build_can_frame (msg ))
900
908
print ("Sender sent a message." )
901
909
902
- import threading
903
-
904
910
e = threading .Event ()
905
911
threading .Thread (target = receiver , args = (e ,)).start ()
906
912
threading .Thread (target = sender , args = (e ,)).start ()
0 commit comments