6464 fileHandler .setLevel (lLevel )
6565 logger .addHandler (fileHandler )
6666
67- can_set_logging_level ('debug' )
67+ # can_set_logging_level('debug')
6868
6969class j1939Listner (canListener ):
7070
@@ -82,6 +82,13 @@ class Bus(BusABC):
8282 """
8383 A CAN Bus that implements the J1939 Protocol.
8484
85+ :param bool strict:
86+
87+ indicates whether to operate on strictly J1939 message (True)
88+ or also handle 11-bit CAN messages. If False, then any specfified
89+ `can_filters` will be honored; incoming 11-bit messages will be
90+ accepted; and outgoing 11-bit messages will be sent.
91+
8592 :param list j1939_filters:
8693 a list of dictionaries that specify filters that messages must
8794 match to be received by this Bus. Messages can match any of the
@@ -94,7 +101,7 @@ class Bus(BusABC):
94101
95102 channel_info = "j1939 bus"
96103
97- def __init__ (self , pdu_type = PDU , broadcast = True , * args , ** kwargs ):
104+ def __init__ (self , pdu_type = PDU , broadcast = True , strict = True , * args , ** kwargs ):
98105 logger .debug ("Creating a new j1939 bus" )
99106
100107 #self.rx_can_message_queue = Queue()
@@ -104,6 +111,7 @@ def __init__(self, pdu_type=PDU, broadcast=True, *args, **kwargs):
104111
105112 super (Bus , self ).__init__ (kwargs .get ('channel' ), kwargs .get ('can_filters' ))
106113 self ._pdu_type = pdu_type
114+ self ._strict = strict
107115 self .timeout = 1
108116 self ._long_message_throttler = threading .Thread (target = self ._throttler_function )
109117 self ._long_message_throttler .daemon = True
@@ -129,7 +137,7 @@ def __init__(self, pdu_type=PDU, broadcast=True, *args, **kwargs):
129137 if 'j1939_filters' in kwargs and kwargs ['j1939_filters' ] is not None :
130138 filters = kwargs .pop ('j1939_filters' )
131139 logger .debug ("Got filters: {}" .format (filters ))
132- can_filters = []
140+ can_filters = [] if self . _strict else kwargs . get ( 'can_filters' , [])
133141 for filt in filters :
134142 can_id , can_mask = 0 , 0
135143 if 'pgn' in filt :
@@ -159,13 +167,15 @@ def __init__(self, pdu_type=PDU, broadcast=True, *args, **kwargs):
159167 raise ValueError ("Bad timeout type" )
160168
161169 logger .debug ("Creating a new can bus" )
162- self .can_bus = RawCanBus (* args , ** kwargs )
170+ self .can_bus = self . _make_can_bus (* args , ** kwargs )
163171
164172 canListener = j1939Listner (self .notification )
165173 self .can_notifier = canNotifier (self .can_bus , [canListener ], timeout = self .timeout )
166174
167175 self ._long_message_throttler .start ()
168176
177+ def _make_can_bus (self , * args , ** kwargs ):
178+ return RawCanBus (* args , ** kwargs )
169179
170180 def notification (self , inboundMessage ):
171181 #self.rx_can_message_queue.put(inboundMessage)
@@ -176,55 +186,64 @@ def notification(self, inboundMessage):
176186 if isinstance (inboundMessage , Message ):
177187 logger .info ('\n \n {}: Got a Message from CAN: {}' .format (inspect .stack ()[0 ][3 ],inboundMessage ))
178188 if inboundMessage .id_type :
179- # Extended ID
180- # Only J1939 messages (i.e. 29-bit IDs) should go further than this point.
181- # Non-J1939 systems can co-exist with J1939 systems, but J1939 doesn't care
182- # about the content of their messages.
183- logger .info ('{}: Message is j1939 msg' .format (inspect .stack ()[0 ][3 ]))
184-
185- #
186- # Need to determine if it's a broadcast message or
187- # limit to listening nodes only
188- #
189- arbitration_id = ArbitrationID ()
190- arbitration_id .can_id = inboundMessage .arbitration_id
191- logger .info ("{}: ArbitrationID = {}, inboundMessage.arbitration_id: 0x{:08x}" .format (inspect .stack ()[0 ][3 ],arbitration_id , inboundMessage .arbitration_id ))
192-
193- for (node , l_notifier ) in self .node_queue_list :
194- logger .debug ("notification: node=%s" % (node ))
195- logger .debug (" notifier=%s" % (l_notifier ))
196- logger .debug (" arbitration_id.pgn=%s" % (arbitration_id .pgn ))
197- logger .debug (" destination_address=%s" % (arbitration_id .destination_address ))
198-
199- # redirect the AC stuff to the node processors. the rest can go
200- # to the main queue.
201- if node and (arbitration_id .pgn in [PGN_AC_ADDRESS_CLAIMED , PGN_AC_COMMANDED_ADDRESS , PGN_REQUEST_FOR_PGN ]):
202- logger .info ("{}: sending to notifier queue" .format (inspect .stack ()[0 ][3 ]))
203- # send the PDU to the node processor.
204- l_notifier .queue .put (inboundMessage )
205-
206- # if node has the destination address, do something with the PDU
207- elif node and (arbitration_id .destination_address in node .address_list ):
208- logger .info ("{}: sending to process_incoming_message" .format (inspect .stack ()[0 ][3 ]))
209- rx_pdu = self ._process_incoming_message (inboundMessage )
210- if rx_pdu :
211- logger .info ("WP02: notification: sent to general queue: %s QQ=%s" % (rx_pdu , self .queue ))
212- self .queue .put (rx_pdu )
213- elif node and (arbitration_id .destination_address is None ):
214- logger .info ("{}: sending broadcast to general queue" .format (inspect .stack ()[0 ][3 ]))
215- rx_pdu = self ._process_incoming_message (inboundMessage )
216- logger .info ("WP01: notification: sent broadcast to general queue: %s QQ=%s" % (rx_pdu , self .queue ))
217- self .queue .put (rx_pdu )
218- elif node is None :
219- # always send the message to the logging queue
220- logger .info ("{}: sending to general queue" .format (inspect .stack ()[0 ][3 ]))
221- rx_pdu = self ._process_incoming_message (inboundMessage )
222- logger .info ("WP03: notification: sent pdu [%s] to general queue" % rx_pdu )
223- self .queue .put (rx_pdu )
224- else :
225- logger .info ("WP04: notification: pdu dropped: %s\n \n " % inboundMessage )
189+ self ._handle_pdu_msg (inboundMessage )
190+ else :
191+ self ._handle_non_pdu_msg (inboundMessage )
192+
193+ def _handle_pdu_msg (self , inboundMessage ):
194+ # Extended ID
195+ # Only J1939 messages (i.e. 29-bit IDs) should go further than this point.
196+ # Non-J1939 systems can co-exist with J1939 systems, but J1939 doesn't care
197+ # about the content of their messages.
198+ logger .info ('{}: Message is j1939 msg' .format (inspect .stack ()[0 ][3 ]))
199+
200+ #
201+ # Need to determine if it's a broadcast message or
202+ # limit to listening nodes only
203+ #
204+ arbitration_id = ArbitrationID ()
205+ arbitration_id .can_id = inboundMessage .arbitration_id
206+ logger .info ("{}: ArbitrationID = {}, inboundMessage.arbitration_id: 0x{:08x}" .format (inspect .stack ()[0 ][3 ],arbitration_id , inboundMessage .arbitration_id ))
207+
208+ for (node , l_notifier ) in self .node_queue_list :
209+ logger .debug ("notification: node=%s" % (node ))
210+ logger .debug (" notifier=%s" % (l_notifier ))
211+ logger .debug (" arbitration_id.pgn=%s" % (arbitration_id .pgn ))
212+ logger .debug (" destination_address=%s" % (arbitration_id .destination_address ))
213+
214+ # redirect the AC stuff to the node processors. the rest can go
215+ # to the main queue.
216+ if node and (arbitration_id .pgn in [PGN_AC_ADDRESS_CLAIMED , PGN_AC_COMMANDED_ADDRESS , PGN_REQUEST_FOR_PGN ]):
217+ logger .info ("{}: sending to notifier queue" .format (inspect .stack ()[0 ][3 ]))
218+ # send the PDU to the node processor.
219+ l_notifier .queue .put (inboundMessage )
220+
221+ # if node has the destination address, do something with the PDU
222+ elif node and (arbitration_id .destination_address in node .address_list ):
223+ logger .info ("{}: sending to process_incoming_message" .format (inspect .stack ()[0 ][3 ]))
224+ rx_pdu = self ._process_incoming_message (inboundMessage )
225+ if rx_pdu :
226+ logger .info ("WP02: notification: sent to general queue: %s QQ=%s" % (rx_pdu , self .queue ))
227+ self .queue .put (rx_pdu )
228+ elif node and (arbitration_id .destination_address is None ):
229+ logger .info ("{}: sending broadcast to general queue" .format (inspect .stack ()[0 ][3 ]))
230+ rx_pdu = self ._process_incoming_message (inboundMessage )
231+ logger .info ("WP01: notification: sent broadcast to general queue: %s QQ=%s" % (rx_pdu , self .queue ))
232+ self .queue .put (rx_pdu )
233+ elif node is None :
234+ # always send the message to the logging queue
235+ logger .info ("{}: sending to general queue" .format (inspect .stack ()[0 ][3 ]))
236+ rx_pdu = self ._process_incoming_message (inboundMessage )
237+ logger .info ("WP03: notification: sent pdu [%s] to general queue" % rx_pdu )
238+ self .queue .put (rx_pdu )
226239 else :
227- logger .info ("Received non J1939 message (ignoring)" )
240+ logger .info ("WP04: notification: pdu dropped: %s\n \n " % inboundMessage )
241+
242+ def _handle_non_pdu_msg (self , inboundMessage ):
243+ if self ._strict :
244+ logger .info ("Received non J1939 message (ignoring)" )
245+ else :
246+ self .queue .put (inboundMessage )
228247
229248 def connect (self , node ):
230249 """
@@ -263,7 +282,13 @@ def recv(self, timeout=None):
263282 # listener.on_error_received(rx_error)
264283
265284 def send (self , msg , timeout = None ):
266- logger .info ("j1939.send: msg={}" .format (msg ))
285+ logger .info ("j1939.send: msg=%s" , msg )
286+ if isinstance (msg , self ._pdu_type ):
287+ self ._send_pdu (msg )
288+ elif not self ._strict :
289+ self ._send (msg )
290+
291+ def _send_pdu (self , msg ):
267292 messages = []
268293 if len (msg .data ) > 8 :
269294 logger .info ("j1939.send: message is > than 8 bytes" )
@@ -403,13 +428,16 @@ def send(self, msg, timeout=None):
403428 dlc = len (msg .data ),
404429 data = msg .data )
405430
406- logger .debug ("j1939.send: calling can_bus_send: can-msg: {}" .format (can_message ))
407- try :
408- self .can_bus .send (can_message )
409- except CanError :
410- if self ._ignore_can_send_error :
411- pass
412- raise
431+ self ._send (can_message )
432+
433+ def _send (self , can_message ):
434+ logger .debug ("j1939.send: calling can_bus_send: can-msg: %s" , can_message )
435+ try :
436+ self .can_bus .send (can_message )
437+ except CanError :
438+ if self ._ignore_can_send_error :
439+ pass
440+ raise
413441
414442 def shutdown (self ):
415443 self .can_notifier ._running = False
0 commit comments