3434 RestartableCyclicTaskABC ,
3535 LimitedDurationCyclicSendTaskABC ,
3636)
37+ from can .typechecking import CanFilters
3738from can .interfaces .socketcan .constants import * # CAN_RAW, CAN_*_FLAG
3839from can .interfaces .socketcan .utils import pack_filters , find_available_interfaces
3940
@@ -593,20 +594,28 @@ def __init__(
593594 channel : str = "" ,
594595 receive_own_messages : bool = False ,
595596 fd : bool = False ,
597+ can_filters : Optional [CanFilters ] = None ,
596598 ** kwargs ,
597599 ) -> None :
598- """
600+ """Creates a new socketcan bus.
601+
602+ If setting some socket options fails, an error will be printed but no exception will be thrown.
603+ This includes enabling:
604+ - that own messages should be received,
605+ - CAN-FD frames and
606+ - error frames.
607+
599608 :param channel:
600- The can interface name with which to create this bus. An example channel
601- would be 'vcan0' or 'can0'.
609+ The can interface name with which to create this bus.
610+ An example channel would be 'vcan0' or 'can0'.
602611 An empty string '' will receive messages from all channels.
603612 In that case any sent messages must be explicitly addressed to a
604613 channel using :attr:`can.Message.channel`.
605614 :param receive_own_messages:
606615 If transmitted messages should also be received by this bus.
607616 :param fd:
608617 If CAN-FD frames should be supported.
609- :param list can_filters:
618+ :param can_filters:
610619 See :meth:`can.BusABC.set_filters`.
611620 """
612621 self .socket = create_socket ()
@@ -622,53 +631,56 @@ def __init__(
622631 self .socket .setsockopt (
623632 SOL_CAN_RAW , CAN_RAW_RECV_OWN_MSGS , 1 if receive_own_messages else 0
624633 )
625- except socket .error as e :
626- log .error ("Could not receive own messages (%s)" , e )
634+ except socket .error as error :
635+ log .error ("Could not receive own messages (%s)" , error )
627636
637+ # enable CAN-FD frames
628638 if fd :
629- # TODO handle errors
630- self .socket .setsockopt (SOL_CAN_RAW , CAN_RAW_FD_FRAMES , 1 )
639+ try :
640+ self .socket .setsockopt (SOL_CAN_RAW , CAN_RAW_FD_FRAMES , 1 )
641+ except socket .error as error :
642+ log .error ("Could not enable CAN-FD frames (%s)" , error )
631643
632- # Enable error frames
633- self .socket .setsockopt (SOL_CAN_RAW , CAN_RAW_ERR_FILTER , 0x1FFFFFFF )
644+ # enable error frames
645+ try :
646+ self .socket .setsockopt (SOL_CAN_RAW , CAN_RAW_ERR_FILTER , 0x1FFFFFFF )
647+ except socket .error as error :
648+ log .error ("Could not enable error frames (%s)" , error )
634649
635650 bind_socket (self .socket , channel )
636651 kwargs .update ({"receive_own_messages" : receive_own_messages , "fd" : fd })
637- super ().__init__ (channel = channel , ** kwargs )
652+ super ().__init__ (channel = channel , can_filters = can_filters , ** kwargs )
638653
639654 def shutdown (self ) -> None :
640655 """Stops all active periodic tasks and closes the socket."""
641656 self .stop_all_periodic_tasks ()
642- for channel in self ._bcm_sockets :
643- log .debug ("Closing bcm socket for channel {}" .format (channel ))
644- bcm_socket = self ._bcm_sockets [channel ]
657+ for channel , bcm_socket in self ._bcm_sockets .items ():
658+ log .debug ("Closing bcm socket for channel %s" , channel )
645659 bcm_socket .close ()
646660 log .debug ("Closing raw can socket" )
647661 self .socket .close ()
648662
649663 def _recv_internal (
650664 self , timeout : Optional [float ]
651665 ) -> Tuple [Optional [Message ], bool ]:
652- # get all sockets that are ready (can be a list with a single value
653- # being self.socket or an empty list if self.socket is not ready)
654666 try :
655667 # get all sockets that are ready (can be a list with a single value
656668 # being self.socket or an empty list if self.socket is not ready)
657669 ready_receive_sockets , _ , _ = select .select ([self .socket ], [], [], timeout )
658670 except socket .error as exc :
659671 # something bad happened (e.g. the interface went down)
660- raise can .CanError ("Failed to receive: %s" % exc )
672+ raise can .CanError (f "Failed to receive: { exc } " )
661673
662- if ready_receive_sockets : # not empty or True
674+ if ready_receive_sockets : # not empty
663675 get_channel = self .channel == ""
664676 msg = capture_message (self .socket , get_channel )
665677 if msg and not msg .channel and self .channel :
666678 # Default to our own channel
667679 msg .channel = self .channel
668680 return msg , self ._is_filtered
669- else :
670- # socket wasn't readable or timeout occurred
671- return None , self ._is_filtered
681+
682+ # socket wasn't readable or timeout occurred
683+ return None , self ._is_filtered
672684
673685 def send (self , msg : Message , timeout : Optional [float ] = None ) -> None :
674686 """Transmit a message to the CAN bus.
@@ -777,13 +789,12 @@ def _get_bcm_socket(self, channel: str) -> socket.socket:
777789 def _apply_filters (self , filters : Optional [can .typechecking .CanFilters ]) -> None :
778790 try :
779791 self .socket .setsockopt (SOL_CAN_RAW , CAN_RAW_FILTER , pack_filters (filters ))
780- except socket .error as err :
792+ except socket .error as error :
781793 # fall back to "software filtering" (= not in kernel)
782794 self ._is_filtered = False
783- # TODO Is this serious enough to raise a CanError exception?
784795 log .error (
785796 "Setting filters failed; falling back to software filtering (not in kernel): %s" ,
786- err ,
797+ error ,
787798 )
788799 else :
789800 self ._is_filtered = True
0 commit comments