@@ -214,6 +214,7 @@ def send_bcm(bcm_socket, data):
214214 else :
215215 raise e
216216
217+
217218def _add_flags_to_can_id (message ):
218219 can_id = message .arbitration_id
219220 if message .is_extended_id :
@@ -240,21 +241,21 @@ class CyclicSendTask(LimitedDurationCyclicSendTaskABC,
240241
241242 """
242243
243- def __init__ (self , channel , message , period , duration = None ):
244+ def __init__ (self , bcm_socket , message , period , duration = None ):
244245 """
245- :param str channel: The name of the CAN channel to connect to .
246+ :param bcm_socket: An open bcm socket on the desired CAN channel .
246247 :param can.Message message: The message to be sent periodically.
247248 :param float period: The rate in seconds at which to send the message.
248249 :param float duration: Approximate duration in seconds to send the message.
249250 """
250251 super (CyclicSendTask , self ).__init__ (message , period , duration )
251- self .channel = channel
252+ self .bcm_socket = bcm_socket
252253 self .duration = duration
253254 self ._tx_setup (message )
254255 self .message = message
255256
256257 def _tx_setup (self , message ):
257- self . bcm_socket = create_bcm_socket ( self . channel )
258+
258259 # Create a low level packed frame to pass to the kernel
259260 self .can_id_with_flags = _add_flags_to_can_id (message )
260261 self .flags = CAN_FD_FRAME if message .is_fd else 0
@@ -283,7 +284,6 @@ def stop(self):
283284
284285 stopframe = build_bcm_tx_delete_header (self .can_id_with_flags , self .flags )
285286 send_bcm (self .bcm_socket , stopframe )
286- self .bcm_socket .close ()
287287
288288 def modify_data (self , message ):
289289 """Update the contents of this periodically sent message.
@@ -460,8 +460,9 @@ def __init__(self, channel="", receive_own_messages=False, fd=False, **kwargs):
460460 self .socket = create_socket ()
461461 self .channel = channel
462462 self .channel_info = "socketcan channel '%s'" % channel
463+ self ._bcm_sockets = {}
463464
464- # set the receive_own_messages paramater
465+ # set the receive_own_messages parameter
465466 try :
466467 self .socket .setsockopt (SOL_CAN_RAW ,
467468 CAN_RAW_RECV_OWN_MSGS ,
@@ -481,12 +482,17 @@ def __init__(self, channel="", receive_own_messages=False, fd=False, **kwargs):
481482 0x1FFFFFFF )
482483
483484 bind_socket (self .socket , channel )
484-
485485 kwargs .update ({'receive_own_messages' : receive_own_messages , 'fd' : fd })
486486 super (SocketcanBus , self ).__init__ (channel = channel , ** kwargs )
487487
488488 def shutdown (self ):
489- """Closes the socket."""
489+ """Stops all active periodic tasks and closes the socket."""
490+ self .stop_all_periodic_tasks ()
491+ for channel in self ._bcm_sockets :
492+ log .debug ("Closing bcm socket for channel {}" .format (channel ))
493+ bcm_socket = self ._bcm_sockets [channel ]
494+ bcm_socket .close ()
495+ log .debug ("Closing raw can socket" )
490496 self .socket .close ()
491497
492498 def _recv_internal (self , timeout ):
@@ -578,7 +584,9 @@ def send_periodic(self, msg, period, duration=None):
578584 The duration to keep sending this message at given rate. If
579585 no duration is provided, the task will continue indefinitely.
580586
581- :return: A started task instance
587+ :return:
588+ A started task instance. This can be used to modify the data,
589+ pause/resume the transmission and to stop the transmission.
582590 :rtype: can.interfaces.socketcan.CyclicSendTask
583591
584592 .. note::
@@ -589,7 +597,15 @@ def send_periodic(self, msg, period, duration=None):
589597 least *duration* seconds.
590598
591599 """
592- return CyclicSendTask (msg .channel or self .channel , msg , period , duration )
600+ bcm_socket = self ._get_bcm_socket (msg .channel or self .channel )
601+ task = CyclicSendTask (bcm_socket , msg , period , duration )
602+ self ._periodic_tasks .append (task )
603+ return task
604+
605+ def _get_bcm_socket (self , channel ):
606+ if channel not in self ._bcm_sockets :
607+ self ._bcm_sockets [channel ] = create_bcm_socket (self .channel )
608+ return self ._bcm_sockets [channel ]
593609
594610 def _apply_filters (self , filters ):
595611 try :
0 commit comments