def main(): can_interface = 'can0' bus = Bus(can_interface) data_scoket = s.recv(1024) print(data_scoket) data_can = [0x01] if data_scoket[0] == '0': data_can = [0x00] elif data_scoket[0] == '+': data_can = [0x02] print(data_can) print "send a message..." Message.extended_id = False Message.is_remote_frame = False Message.id_type = 0 Message.is_error_frame = False Message.arbitration_id = 0x65D Message.dlc = 1 Message.data = data_can try: bus.send(Message) except: print "Upss something went wrong"
def __init__(self, interface, verbose = False, listeners = None): self.bus = Bus(interface, bustype = 'socketcan') self.verbose = verbose self.listeners = listeners self.bms = bms.bms() self.ccs = ccs.ccs() self.notifier = can.Notifier(self.bus, [self.on_message_received])
def Can(id): global adc_val can_interface = 'can0' bus = Bus(can_interface) print "send message..." Message.extended_id = False Message.extended_id = False Message.is_remote_frame = False Message.id_type = 1 Message.is_error_frame=False if id==0x22: Message.arbitration_id=id Message.dlc=3 adc_val1=adc_val/ 10 adc_val2=adc_val %10 #message data frame Message.data=[0x00,adc_val1,adc_val2] #exception for error handling try: bus.send(Message); print"data=",Message.data print "id=",id except: print "OOPS somthing went wrong" sleep(3)
def __init__(self, interface, channel): can.rc['interface'] = interface can.rc['channel'] = channel log.info('Opening CAN connection on {0}'.format(can.rc['channel'])) self.bus = Bus(bitrate=250000) self.periodic_tasks = list() self._rxHandlers = list()
def main(): data=0 while(1): can_interface = 'can0' bus = Bus(can_interface) print "send message....." sleep(3) Message.extended_id =False Message.is_remote_frame = False Message.id_type = 1 Message.is_error_frame=False Message.arbitration_id = 0x33 Message.dlc = 1 Message.data=[data] try: bus.send(Message); print Messgae.data except: print "invalid operation!!!!!!" sleep(0.1)
def producer(id): """:param id: Spam the bus with messages including the data id.""" bus = Bus(can_interface) for i in range(16): msg = can.Message(arbitration_id=0x0cf02200, data=[id, i, 0, 1, 3, 1, 4, 1]) bus.send(msg) # TODO Issue #3: Need to keep running to ensure the writing threads stay alive. ? time.sleep(2)
def main(): can_interface = 'can1' bus = Bus(can_interface) try: while True: Message = bus.recv(0.0) if Message: check_rx(Message.arbitration_id, Message.data[0]) except KeyboardInterrupt: bus.shutdown()
def canListener(pipe): data = {} bus = Bus(env.bus) while 1: frame = bus.recv(timeout=0.005) data[hex(frame.arbitration_id)] = frame.data if (pipe.poll(timeout=0)): # flush out the pipe from any flags for writing while pipe.poll(timeout=0): pipe.recv() pipe.send(data) pipe.close() return # execution really should not get here
def __init__(self, can_interface): can.rc['interface'] = 'socketcan_ctypes' if can_interface is None: can_interface = 'can0' self._can_interface = can_interface if not self.status(): raise IOError("CAN Bus not available") self._bus = Bus(self._can_interface) self._bitrate = 500000 if self._bus is None: raise IOError("Can't find CAN bus interface") self._rcv_thread_quit = False self._rcv_thread = None self._rcv_queue = queue.Queue(maxsize=1024)
def __init__(self): can.rc['interface'] = 'socketcan_native' can.rc['channel'] = 'vcan0' can.rc['bitrate'] = 500000 self.bus = Bus() self.buffered_reader = can.BufferedReader() self.notifier = can.Notifier(self.bus, [self.buffered_reader])
def main(): global device_id global encoder_value_send_task if len(sys.argv) != 2: usage() sys.exit(1) device_id = int(sys.argv[1]) if device_id < 0 or device_id >= 63: usage() sys.exit(1) can.rc['interface'] = 'socketcan_ctypes' can.rc['channel'] = 'vcan0' bus = Bus() notifier = can.Notifier(bus, [Listener()]) status_3_msg = can.Message(arbitration_id=(talon_srx.STATUS_3 | device_id), extended_id=True, data=make_status_3_msg()) status_3_task = can.send_periodic(can.rc['channel'], status_3_msg, 0.1) while True: status_3_msg.data = make_status_3_msg() status_3_task.modify_data(status_3_msg) time.sleep(0.05) notifier.stop()
def __init__(self, pdu_type=PDU, *args, **kwargs): logger.debug("Creating a new j1939 bus") #self.rx_can_message_queue = Queue() self.queue = Queue() self.node_queue_list = [(None, self)] ## Start with default logger Queue super(Bus, self).__init__() self._pdu_type = pdu_type self.timeout=1 self._long_message_throttler = threading.Thread(target=self._throttler_function) #self._long_message_throttler.daemon = True self._incomplete_received_pdus = {} self._incomplete_received_pdu_lengths = {} self._incomplete_transmitted_pdus = {} self._long_message_segment_queue = Queue(0) # Convert J1939 filters into Raw Can filters if 'j1939_filters' in kwargs and kwargs['j1939_filters'] is not None: filters = kwargs.pop('j1939_filters') logger.debug("Got filters: {}".format(filters)) can_filters = [] for filt in filters: can_id, can_mask = 0, 0 if 'pgn' in filt: can_id = filt['pgn'] << 8 # The pgn needs to be left shifted by 8 to ignore the CAN_ID's source address # Look at most significant 4 bits to determine destination specific if can_id & 0xF00000 == 0xF00000: logging.info("PDU2 (broadcast message)") can_mask = 0xFFFF00 else: logging.info("PDU1 (p2p)") can_mask = 0xFF0000 if 'source' in filt: # filter by source can_mask |= 0xFF can_id |= filt['source'] logger.info("added source", filt) logger.info("Adding CAN ID filter: {:0x}:{:0x}".format(can_id, can_mask)) can_filters.append({"can_id": can_id, "can_mask": can_mask}) kwargs['can_filters'] = can_filters if 'timeout' in kwargs and kwargs['timeout'] is not None: if isinstance(kwargs['timeout'], (int, float)): self.timeout=kwargs['timeout'] else: raise ValueError("Bad timeout type") logger.debug("Creating a new can bus") self.can_bus = RawCanBus(*args, **kwargs) self.can_notifier = canNotifier(self.can_bus, [self.notification], timeout=self.timeout) ###########self.j1939_notifier = Notifier(self, []) self._long_message_throttler.start()
def main(): can_interface = 'can1' bus = Bus(can_interface) print "Send a message..." Message.extended_id = True Message.is_remote_frame = False Message.id_type = 1 Message.is_error_frame = False Message.arbitration_id = 0x65D Message.dlc = 1 Message.data = [ 0x01] try: bus.send(Message); except: print "Ups something went wrong!"
def response(payloads, quiet_response, channel_in): can.rc['interface'] = 'socketcan_ctypes' can.rc['channel'] = channel_in bus = Bus() send_recv = "receive" # if(payloads != None): # continue consecutive_messages = 1; last_message_id = -1; mod = 1 current = None while 1: if current != None: send_recv == "send" if send_recv == "receive": while 1: current = payloads.get() #print(current) # if current != None: print(current) # break # print(current) # continue elif send_recv == "send": message = can.Message(extended_id = False, is_error_frame = False, arbitration_id = current.arbitration_id, data = [0]) count = 0 while 1: bus.send(message) count += 1 if (count%mod)==0: send_recv = "receive" mod *= 2 current = None break
def __init__(self): super(CanStore, self).__init__() self.frameDictionary = {} # setup worker multiprocessing to listen to the can bus self.parent, self.child = Pipe() self.canWorker = Process(target=canListener, args=(self.child, )) self.canWorker.start() # set up can bus interface self.bus = Bus(self.can_interface)
class can_bus(): def __init__(self): self.bus = Bus('can0', bustype='socketcan_ctypes') self.rx_buff = [] self.tx_buff = [] def transmit(self, data): msg = can.Message(arbitration_id=0x000, data=data, extended_id=False) try: self.bus.send(msg) print("Message sent on {}".format(self.bus.channel_info)) except can.CanError: print("Message NOT sent") def recieve(self, timeout=None): try: msg = self.bus.recv(timeout=1.0) print("Message recieved on {}".format(self.bus.channel_info)) print msg except can.CanError: print("Message NOT received")
def Can(id): can_interface = 'can0' bus = Bus(can_interface) Message.extended_id = False Message.is_remote_frame = False Message.id_type = 1 Message.is_error_frame = False if id==0x22: Message.arbitration_id=id Message.dlc=3 Message.data=[0x22] if id==0x11: Message.arbitration_id=id Message.dlc=3 Message.data=[0x11] try: bus.send(Message); print ("Data=",Message.data) print ("ID=",id) except: print ("Oops!!! Something went wrong!")
def main(): data=0 while(1): can_interface = 'can0' bus = Bus(can_interface) #print "Send a message...a heart beat" Message.extended_id = False Message.is_remote_frame = False Message.id_type = 1 Message.is_error_frame = False Message.arbitration_id = 0x33 Message.dlc = 1 data=data+1 Message.data = [data] try: bus.send(Message); print (Message.data) except: print ("Ups something went wrong!") sleep(0.1)
def __init__(self, pdu_type=PDU, *args, **kwargs): logger.debug("Creating a new j1939 bus") self.rx_can_message_queue = Queue() super(Bus, self).__init__() self._pdu_type = pdu_type self._long_message_throttler = threading.Thread(target=self._throttler_function) #self._long_message_throttler.daemon = True self._incomplete_received_pdus = {} self._incomplete_received_pdu_lengths = {} self._incomplete_transmitted_pdus = {} self._long_message_segment_queue = Queue(0) # Convert J1939 filters into Raw Can filters if 'j1939_filters' in kwargs and kwargs['j1939_filters'] is not None: filters = kwargs.pop('j1939_filters') logger.debug("Got filters: {}".format(filters)) can_filters = [] for filt in filters: can_id, can_mask = 0, 0 if 'pgn' in filt: can_id = filt['pgn'] << 8 # The pgn needs to be left shifted by 8 to ignore the CAN_ID's source address # Look at most significant 4 bits to determine destination specific if can_id & 0xF00000 == 0xF00000: logging.info("PDU2 (broadcast message)") can_mask = 0xFFFF00 else: logging.info("PDU1 (p2p)") can_mask = 0xFF0000 if 'source' in filt: # filter by source can_mask |= 0xFF can_id |= filt['source'] logger.info("added source", filt) logger.info("Adding CAN ID filter: {:0x}:{:0x}".format(can_id, can_mask)) can_filters.append({"can_id": can_id, "can_mask": can_mask}) kwargs['can_filters'] = can_filters logger.debug("Creating a new can bus") self.can_bus = RawCanBus(*args, **kwargs) self.can_notifier = Notifier(self.can_bus, [self.rx_can_message_queue.put]) self.j1939_notifier = Notifier(self, []) self._long_message_throttler.start()
class CanMessageRead(object): bus = Bus(can_interface) def __init__(self): self.id = 0 self.currentDistance = 0 self.prevDistance = 0 def readBus(self): try: msg = self.bus.recv() self.id = msg.data[0] self.prevDistance = self.currentDistance self.currentDistance = msg.data[1] except: print("TODO m: We need to catch this, yo")
class CAN_Main(object): def __init__(self): self.currentSpeed = 0 self.previousSpeed = 0 self.updateSpeed = False self.currentVoltage = 0 self.previousVoltage = 0 self.updateVoltage = False self.leftBlindSpot = False self.leftBottomBlindSpot = False self.centerBottombBlindSpot = False self.rightBottomBlindSpot = False self.rightBlindSpot = False self.overVoltageWarning = False self.underVoltageWarning = False self.overTemperatureWarning = False self.underTemperatureWarning = False self.overCurrentWarning = False self.underCurrentWarning = False def initializeInstances(self): self.bus = Bus(can_interface,can_filters=FILTER_DICTIONARY_LIST) self.can_tools = CAN_Opener.Can_Opener() def pollBus(self): try: msg = self.bus.recv(timeout=10) self.process_CAN_message(msg) except: print("TODO m: We need to catch this, yo") raise def process_CAN_message(self, pCan_frame): self.message_select(pCan_frame) def message_select(self, pCAN_frame): if(pCAN_frame.arbitration_id == 0x100): self.message_one(pCAN_frame.data) elif(pCAN_frame.arbitration_id == 0x200): self.message_two(pCAN_frame.data) elif(pCAN_frame.arbitration_id == 0x300): self.message_three(pCAN_frame.data) elif(pCAN_frame.arbitration_id == 0x400): self.message_four(pCAN_frame.data) else: pass def shiftData(self, pValue, pShiftPlaces): return pValue>>pShiftPlaces def message_one(self, data): #Engine Signals msg_one_bits = self.can_tools.pack_data(data) ''' TODO m: update to EV self.set_engine_coolant_temp(self.shiftData(data[0], 1)) self.set_engine_torque(data[1]) self.set_engine_RPM(data[3]*256 + data[2]) self.set_throttle_percent(self.shiftData(data[4], 1)) ''' def message_two(self, data): #Warnings msg_two_bits = self.can_tools.pack_data(data) ''' TODO m: update to EV self.set_warning_ess_overtemp(self.can_tools.shift_mask(0, 1, msg_two_bits, ONE_BIT_MASK)) self.set_warning_fuel_level_low(self.can_tools.shift_mask(1, 1, msg_two_bits, ONE_BIT_MASK)) self.set_warning_glv_cockpit_brb(self.can_tools.shift_mask(2, 1, msg_two_bits, ONE_BIT_MASK)) self.set_warning_glv_soc_low(self.can_tools.shift_mask(3, 1, msg_two_bits, ONE_BIT_MASK)) self.set_warning_motor_over_temp(self.can_tools.shift_mask(4, 1, msg_two_bits, ONE_BIT_MASK)) self.set_warning_transmission_failure(self.can_tools.shift_mask(5, 1, msg_two_bits, ONE_BIT_MASK)) ''' def message_three(self, data): #Electrical Systems ''' TODO m: update for EV self.set_ess_soc(self.shiftData(data[0], 1)) self.set_ess_voltage(data[1]) ''' def message_four(self, data): #Control msg_four_bits = self.can_tools.pack_data(data) '''
description='Simulates CAN bus messages from CCS') parser.add_argument("--verbose", type=str2bool, nargs='?', const=True, default=False, help="Prints verbose logger messages") args = parser.parse_args() # Add verbose logger if args.verbose: logging.basicConfig() logging.getLogger('apscheduler').setLevel(logging.DEBUG) # Init CAN bus = Bus('can1', bustype='socketcan') # Pose as CCS and send out some messages scheduler = BackgroundScheduler() scheduler.add_job(_send_ccs_rand, 'interval', args=[bus], seconds=1) scheduler.start() # Enter blocking loop to keep daemon alive while True: try: time.sleep(1) except: # Gracefully shutdown scheduler click.echo( click.style('Exception Handled! Killing thread', bg='red',
import sys from signal import * from random import uniform #python3 interframe_spacing_test.py [device_name] [vitrate] [send/receive] [ID] [length] [data] channel_in = sys.argv[1] bitrate = int(sys.argv[2]) send_recv = sys.argv[3] id_in = int(sys.argv[4]) length = int(sys.argv[5]) data = int(sys.argv[6]) can.rc['interface'] = 'socketcan_ctypes' can.rc['channel'] = channel_in bus = Bus() out = [ channel_in, " | ", send_recv, " | ", "bitrate: ", str(bitrate), " | ", "count: ", "" ] def clean(*args): print(''.join(out)) sys.exit(0) if __name__ == '__main__': signal(SIGTERM, clean)
import sys,signal,can from PyQt5 import QtGui, QtCore, QtWidgets from can.interfaces.interface import Bus #200 -> 4,5 == speed 6,7 == ? device = sys.argv[1] can.rc['interface'] = 'socketcan_ctypes' can.rc['channel'] = device bus = Bus() class Main(QtWidgets.QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): self.timer = QtCore.QTimer(self) self.timer.timeout.connect(self.CAN) self.timer.start(1) self.lcd = QtWidgets.QLCDNumber(self) #set widget size self.lcd.setFixedSize(500,200) self.lcd.display(0) self.setGeometry(50,50,500,200) self.setWindowTitle("Speedometer")
class Bus(BusABC): """ A CAN Bus that implements the J1939 Protocol. :param list j1939_filters: a list of dictionaries that specify filters that messages must match to be received by this Bus. Messages can match any of the filters. Options are: * :pgn: An integer PGN to show """ channel_info = "j1939 bus" def __init__(self, pdu_type=PDU, *args, **kwargs): logger.debug("Creating a new j1939 bus") self.rx_can_message_queue = Queue() super(Bus, self).__init__() self._pdu_type = pdu_type self._long_message_throttler = threading.Thread(target=self._throttler_function) #self._long_message_throttler.daemon = True self._incomplete_received_pdus = {} self._incomplete_received_pdu_lengths = {} self._incomplete_transmitted_pdus = {} self._long_message_segment_queue = Queue(0) # Convert J1939 filters into Raw Can filters if 'j1939_filters' in kwargs and kwargs['j1939_filters'] is not None: filters = kwargs.pop('j1939_filters') logger.debug("Got filters: {}".format(filters)) can_filters = [] for filt in filters: can_id, can_mask = 0, 0 if 'pgn' in filt: can_id = filt['pgn'] << 8 # The pgn needs to be left shifted by 8 to ignore the CAN_ID's source address # Look at most significant 4 bits to determine destination specific if can_id & 0xF00000 == 0xF00000: logging.info("PDU2 (broadcast message)") can_mask = 0xFFFF00 else: logging.info("PDU1 (p2p)") can_mask = 0xFF0000 if 'source' in filt: # filter by source can_mask |= 0xFF can_id |= filt['source'] logger.info("added source", filt) logger.info("Adding CAN ID filter: {:0x}:{:0x}".format(can_id, can_mask)) can_filters.append({"can_id": can_id, "can_mask": can_mask}) kwargs['can_filters'] = can_filters logger.debug("Creating a new can bus") self.can_bus = RawCanBus(*args, **kwargs) self.can_notifier = Notifier(self.can_bus, [self.rx_can_message_queue.put]) self.j1939_notifier = Notifier(self, []) self._long_message_throttler.start() def recv(self, timeout=None): logger.debug("Waiting for new message") logger.debug("Timeout is {}".format(timeout)) try: m = self.rx_can_message_queue.get(timeout=timeout) except Empty: return rx_pdu = None if isinstance(m, Message): logger.debug('Got a Message: %s' % m) if m.id_type: # Extended ID # Only J1939 messages (i.e. 29-bit IDs) should go further than this point. # Non-J1939 systems can co-exist with J1939 systems, but J1939 doesn't care # about the content of their messages. logger.info('Message is j1939 msg') rx_pdu = self._process_incoming_message(m) else: logger.info("Received non J1939 message (ignoring)") # TODO: Decide what to do with CAN errors if m.is_error_frame: logger.warning("Appears we got an error frame!") #rx_error = CANError(timestamp=m.timestamp) # if rx_error is not None: # logger.info('Sending error "%s" to registered listeners.' % rx_error) # for listener in self.listeners: # if hasattr(listener, 'on_error_received'): # listener.on_error_received(rx_error) # Return to BusABC where it will get fed to any listeners return rx_pdu def send(self, msg): messages = [] if len(msg.data) > 8: # Making a copy of the PDU so that the original # is not altered by the data padding. pdu = copy.deepcopy(msg) pdu.data = bytearray(pdu.data) pdu_length_lsb, pdu_length_msb = divmod(len(pdu.data), 256) while len(pdu.data) % 7 != 0: pdu.data += b'\xFF' for i, segment in enumerate(pdu.data_segments(segment_length=7)): arbitration_id = copy.deepcopy(pdu.arbitration_id) arbitration_id.pgn.value = constants.PGN_TP_DATA_TRANSFER if pdu.arbitration_id.pgn.is_destination_specific and \ pdu.arbitration_id.destination_address != constants.DESTINATION_ADDRESS_GLOBAL: arbitration_id.pgn.pdu_specific = pdu.arbitration_id.pgn.pdu_specific else: arbitration_id.pgn.pdu_specific = constants.DESTINATION_ADDRESS_GLOBAL message = Message(arbitration_id=arbitration_id.can_id, extended_id=True, dlc=(len(segment) + 1), data=(bytearray([i + 1]) + segment)) messages.append(message) if pdu.arbitration_id.pgn.is_destination_specific and \ pdu.arbitration_id.destination_address != constants.DESTINATION_ADDRESS_GLOBAL: destination_address = pdu.arbitration_id.pgn.pdu_specific if pdu.arbitration_id.source_address in self._incomplete_transmitted_pdus: if destination_address in self._incomplete_transmitted_pdus[pdu.arbitration_id.source_address]: logger.warning("Duplicate transmission of PDU:\n{}".format(pdu)) else: self._incomplete_transmitted_pdus[pdu.arbitration_id.source_address] = {} self._incomplete_transmitted_pdus[pdu.arbitration_id.source_address][destination_address] = messages else: destination_address = constants.DESTINATION_ADDRESS_GLOBAL rts_arbitration_id = ArbitrationID(source_address=pdu.source) rts_arbitration_id.pgn.value = constants.PGN_TP_CONNECTION_MANAGEMENT rts_arbitration_id.pgn.pdu_specific = pdu.arbitration_id.pgn.pdu_specific temp_pgn = copy.deepcopy(pdu.arbitration_id.pgn) if temp_pgn.is_destination_specific: temp_pgn.value -= temp_pgn.pdu_specific pgn_msb = ((temp_pgn.value & 0xFF0000) >> 16) pgn_middle = ((temp_pgn.value & 0x00FF00) >> 8) pgn_lsb = (temp_pgn.value & 0x0000FF) if pdu.arbitration_id.pgn.is_destination_specific and \ pdu.arbitration_id.destination_address != constants.DESTINATION_ADDRESS_GLOBAL: # send request to send rts_msg = Message(extended_id=True, arbitration_id=rts_arbitration_id.can_id, data=[constants.CM_MSG_TYPE_RTS, pdu_length_msb, pdu_length_lsb, len(messages), 0xFF, pgn_lsb, pgn_middle, pgn_msb], dlc=8) self.can_bus.send(rts_msg) else: rts_arbitration_id.pgn.pdu_specific = constants.DESTINATION_ADDRESS_GLOBAL bam_msg = Message(extended_id=True, arbitration_id=rts_arbitration_id.can_id, data=[constants.CM_MSG_TYPE_BAM, pdu_length_msb, pdu_length_lsb, len(messages), 0xFF, pgn_lsb, pgn_middle, pgn_msb], dlc=8) # send BAM self.can_bus.send(bam_msg) for message in messages: # send data messages - no flow control, so no need to wait # for receiving devices to acknowledge self._long_message_segment_queue.put_nowait(message) else: can_message = Message(arbitration_id=msg.arbitration_id.can_id, extended_id=True, dlc=len(msg.data), data=msg.data) self.can_bus.send(can_message) def shutdown(self): self.can_notifier.running.clear() self.can_bus.shutdown() self.j1939_notifier.running.clear() super(Bus, self).shutdown() def _process_incoming_message(self, msg): logger.debug("Processing incoming message") logging.debug(msg) arbitration_id = ArbitrationID() arbitration_id.can_id = msg.arbitration_id if arbitration_id.pgn.is_destination_specific: arbitration_id.pgn.value -= arbitration_id.pgn.pdu_specific pdu = self._pdu_type(timestamp=msg.timestamp, data=msg.data, info_strings=[]) pdu.arbitration_id.can_id = msg.arbitration_id pdu.info_strings = [] if arbitration_id.pgn.value == constants.PGN_TP_CONNECTION_MANAGEMENT: retval = self._connection_management_handler(pdu) elif arbitration_id.pgn.value == constants.PGN_TP_DATA_TRANSFER: retval = self._data_transfer_handler(pdu) else: retval = pdu return retval def _connection_management_handler(self, msg): if len(msg.data) == 0: msg.info_strings.append("Invalid connection management message - no data bytes") return msg cmd = msg.data[0] retval = None if cmd == constants.CM_MSG_TYPE_RTS: retval = self._process_rts(msg) elif cmd == constants.CM_MSG_TYPE_CTS: retval = self._process_cts(msg) elif cmd == constants.CM_MSG_TYPE_EOM_ACK: retval = self._process_eom_ack(msg) elif cmd == constants.CM_MSG_TYPE_BAM: retval = self._process_bam(msg) elif cmd == constants.CM_MSG_TYPE_ABORT: retval = self._process_abort(msg) return retval def _data_transfer_handler(self, msg): msg_source = msg.arbitration_id.source_address pdu_specific = msg.arbitration_id.pgn.pdu_specific if msg_source in self._incomplete_received_pdus: if pdu_specific in self._incomplete_received_pdus[msg_source]: self._incomplete_received_pdus[msg_source][pdu_specific].data.extend(msg.data[1:]) total = self._incomplete_received_pdu_lengths[msg_source][pdu_specific]["total"] if len(self._incomplete_received_pdus[msg_source][pdu_specific].data) >= total: if pdu_specific == constants.DESTINATION_ADDRESS_GLOBAL: # Looks strange but makes sense - in the absence of explicit flow control, # the last CAN packet in a long message *is* the end of message acknowledgement return self._process_eom_ack(msg) # Find a Node object so we can search its list of known node addresses for this node # so we can find if we are responsible for sending the EOM ACK message send_ack = any(True for l in self.j1939_notifier.listeners if isinstance(l, Node) and (l.address == pdu_specific or pdu_specific in l.address_list)) if send_ack: arbitration_id = ArbitrationID() arbitration_id.pgn.value = constants.PGN_TP_CONNECTION_MANAGEMENT arbitration_id.pgn.pdu_specific = msg_source arbitration_id.source_address = pdu_specific total_length = self._incomplete_received_pdu_lengths[msg_source][pdu_specific]["total"] _num_packages = self._incomplete_received_pdu_lengths[msg_source][pdu_specific]["num_packages"] pgn = self._incomplete_received_pdus[msg_source][pdu_specific].arbitration_id.pgn pgn_msb = ((pgn.value & 0xFF0000) >> 16) _pgn_middle = ((pgn.value & 0x00FF00) >> 8) _pgn_lsb = 0 div, mod = divmod(total_length, 256) can_message = Message(arbitration_id=arbitration_id.can_id, extended_id=True, dlc=8, data=[constants.CM_MSG_TYPE_EOM_ACK, mod, #total_length % 256, div, #total_length / 256, _num_packages, 0xFF, _pgn_lsb, _pgn_middle, pgn_msb]) self.can_bus.send(can_message) return self._process_eom_ack(msg) def _process_rts(self, msg): if msg.arbitration_id.source_address not in self._incomplete_received_pdus: self._incomplete_received_pdus[msg.arbitration_id.source_address] = {} self._incomplete_received_pdu_lengths[msg.arbitration_id.source_address] = {} # Delete any previous messages that were not finished correctly if msg.arbitration_id.pgn.pdu_specific in self._incomplete_received_pdus[msg.arbitration_id.source_address]: del self._incomplete_received_pdus[msg.arbitration_id.source_address][msg.arbitration_id.pgn.pdu_specific] del self._incomplete_received_pdu_lengths[msg.arbitration_id.source_address][ msg.arbitration_id.pgn.pdu_specific] if msg.data[0] == constants.CM_MSG_TYPE_BAM: self._incomplete_received_pdus[msg.arbitration_id.source_address][0xFF] = self._pdu_type() self._incomplete_received_pdus[msg.arbitration_id.source_address][0xFF].arbitration_id.pgn.value = int( ("%.2X%.2X%.2X" % (msg.data[7], msg.data[6], msg.data[5])), 16) if self._incomplete_received_pdus[msg.arbitration_id.source_address][ 0xFF].arbitration_id.pgn.is_destination_specific: self._incomplete_received_pdus[msg.arbitration_id.source_address][ 0xFF].arbitration_id.pgn.pdu_specific = msg.arbitration_id.pgn.pdu_specific self._incomplete_received_pdus[msg.arbitration_id.source_address][ 0xFF].arbitration_id.source_address = msg.arbitration_id.source_address self._incomplete_received_pdus[msg.arbitration_id.source_address][0xFF].data = [] _message_size = int("%.2X%.2X" % (msg.data[2], msg.data[1]), 16) self._incomplete_received_pdu_lengths[msg.arbitration_id.source_address][0xFF] = {"total": _message_size, "chunk": 255, "num_packages": msg.data[ 3], } else: self._incomplete_received_pdus[msg.arbitration_id.source_address][ msg.arbitration_id.pgn.pdu_specific] = self._pdu_type() self._incomplete_received_pdus[msg.arbitration_id.source_address][ msg.arbitration_id.pgn.pdu_specific].arbitration_id.pgn.value = int( ("%.2X%.2X%.2X" % (msg.data[7], msg.data[6], msg.data[5])), 16) if self._incomplete_received_pdus[msg.arbitration_id.source_address][ msg.arbitration_id.pgn.pdu_specific].arbitration_id.pgn.is_destination_specific: self._incomplete_received_pdus[msg.arbitration_id.source_address][ msg.arbitration_id.pgn.pdu_specific].arbitration_id.pgn.pdu_specific = msg.arbitration_id.pgn.pdu_specific self._incomplete_received_pdus[msg.arbitration_id.source_address][ msg.arbitration_id.pgn.pdu_specific].arbitration_id.source_address = msg.arbitration_id.source_address self._incomplete_received_pdus[msg.arbitration_id.source_address][ msg.arbitration_id.pgn.pdu_specific].data = [] _message_size = int("%.2X%.2X" % (msg.data[2], msg.data[1]), 16) self._incomplete_received_pdu_lengths[msg.arbitration_id.source_address][ msg.arbitration_id.pgn.pdu_specific] = {"total": _message_size, "chunk": 255, "num_packages": msg.data[3], } if msg.data[0] != constants.CM_MSG_TYPE_BAM: for _listener in self.j1939_notifier.listeners: if isinstance(_listener, Node): # find a Node object so we can search its list of known node addresses # for this node - if we find it we are responsible for sending the CTS message if _listener.address == msg.arbitration_id.pgn.pdu_specific or msg.arbitration_id.pgn.pdu_specific in _listener.address_list: _cts_arbitration_id = ArbitrationID(source_address=msg.arbitration_id.pgn.pdu_specific) _cts_arbitration_id.pgn.value = constants.PGN_TP_CONNECTION_MANAGEMENT _cts_arbitration_id.pgn.pdu_specific = msg.arbitration_id.source_address _data = [0x11, msg.data[4], 0x01, 0xFF, 0xFF] _data.extend(msg.data[5:]) cts_msg = Message(extended_id=True, arbitration_id=_cts_arbitration_id.can_id, data=_data, dlc=8) # send clear to send self.can_bus.send(cts_msg) return def _process_cts(self, msg): if msg.arbitration_id.pgn.pdu_specific in self._incomplete_transmitted_pdus: if msg.arbitration_id.source_address in self._incomplete_transmitted_pdus[ msg.arbitration_id.pgn.pdu_specific]: # Next packet number in CTS message (Packet numbers start at 1 not 0) start_index = msg.data[2] - 1 # Using total number of packets in CTS message end_index = start_index + msg.data[1] for _msg in self._incomplete_transmitted_pdus[msg.arbitration_id.pgn.pdu_specific][ msg.arbitration_id.source_address][start_index:end_index]: self.can_bus.send(_msg) def _process_eom_ack(self, msg): if (msg.arbitration_id.pgn.value - msg.arbitration_id.pgn.pdu_specific) == constants.PGN_TP_DATA_TRANSFER: self._incomplete_received_pdus[msg.arbitration_id.source_address][ msg.arbitration_id.pgn.pdu_specific].timestamp = msg.timestamp retval = copy.deepcopy( self._incomplete_received_pdus[msg.arbitration_id.source_address][msg.arbitration_id.pgn.pdu_specific]) retval.data = retval.data[:self._incomplete_received_pdu_lengths[msg.arbitration_id.source_address][ msg.arbitration_id.pgn.pdu_specific]["total"]] del self._incomplete_received_pdus[msg.arbitration_id.source_address][msg.arbitration_id.pgn.pdu_specific] del self._incomplete_received_pdu_lengths[msg.arbitration_id.source_address][ msg.arbitration_id.pgn.pdu_specific] else: if msg.arbitration_id.pgn.pdu_specific in self._incomplete_received_pdus: if msg.arbitration_id.source_address in self._incomplete_received_pdus[ msg.arbitration_id.pgn.pdu_specific]: self._incomplete_received_pdus[msg.arbitration_id.pgn.pdu_specific][ msg.arbitration_id.source_address].timestamp = msg.timestamp retval = copy.deepcopy(self._incomplete_received_pdus[msg.arbitration_id.pgn.pdu_specific][ msg.arbitration_id.source_address]) retval.data = retval.data[: self._incomplete_received_pdu_lengths[msg.arbitration_id.pgn.pdu_specific][ msg.arbitration_id.source_address]["total"]] del self._incomplete_received_pdus[msg.arbitration_id.pgn.pdu_specific][ msg.arbitration_id.source_address] del self._incomplete_received_pdu_lengths[msg.arbitration_id.pgn.pdu_specific][ msg.arbitration_id.source_address] else: retval = None else: retval = None if msg.arbitration_id.pgn.pdu_specific in self._incomplete_transmitted_pdus: if msg.arbitration_id.source_address in self._incomplete_transmitted_pdus[ msg.arbitration_id.pgn.pdu_specific]: del self._incomplete_transmitted_pdus[msg.arbitration_id.pgn.pdu_specific][ msg.arbitration_id.source_address] return retval def _process_bam(self, msg): self._process_rts(msg) def _process_abort(self, msg): if msg.arbitration_id.pgn.pdu_specific in self._incomplete_received_pdus: if msg.source in self._incomplete_received_pdus[msg.arbitration_id.pgn.pdu_specific]: del self._incomplete_received_pdus[msg.arbitration_id.pgn.pdu_specific][ msg.arbitration_id.source_address] def _throttler_function(self): while self.can_notifier.running.is_set(): _msg = None try: _msg = self._long_message_segment_queue.get(timeout=0.1) except Empty: pass if _msg is not None: self.can_bus.send(_msg) @property def transmissions_in_progress(self): retval = 0 for _tx_address in self._incomplete_transmitted_pdus: retval += len(self._incomplete_transmitted_pdus[_tx_address]) for _rx_address in self._incomplete_received_pdus: retval += len(self._incomplete_received_pdus[_rx_address]) return retval
import time import can import sys from can.interfaces.interface import Bus can_interface = 'can0' # # TODO: keep sending 700/02 3e 80 # # bus = Bus(can_interface) receivers = [] def hexdump(x): return ' '.join("%02x" % y for y in bytearray(x)) class IsoTp: PAD = bytes([0x55]) def __init__(self, bus, id_source, id_target, add_address_info = None): global receivers self.id_source = id_source self.id_target = id_target self.add_address_info = add_address_info self.bus = bus receivers.append(self) self.rx_pdu = None self.rx_dl = None self.rx_exp_sn = None self.debug = True
def initializeInstances(self): self.bus = Bus(can_interface,can_filters=FILTER_DICTIONARY_LIST) self.can_tools = CAN_Opener.Can_Opener()
import log_utils from timeit import default_timer import sys import can from can.interfaces.interface import Bus #python3 send_from_log.py [device name] [logfile] can.rc['interface'] = 'socketcan_ctypes' can.rc['channel'] = 'can0' bus = Bus() chan_in = sys.argv[1] LOGFILE = sys.argv[2] #ID = int(sys.argv[2]) can.rc['interface'] = 'socketcan_ctypes' can.rc['channel'] = chan_in bus = Bus() def send_message(message): soc_message = can.Message(extended_id=False, is_error_frame=False, arbitration_id=message.can_id, data=message.data) bus.send(soc_message) def message_alter(message, altered_bytes): for i in range(len(message.data)):
def initializeInstances(self): self.bus = Bus(can_interface, can_filters=FILTER_DICTIONARY_LIST) self.can_tools = CAN_Opener.Can_Opener()
class Bus(BusABC): """ A CAN Bus that implements the J1939 Protocol. :param list j1939_filters: a list of dictionaries that specify filters that messages must match to be received by this Bus. Messages can match any of the filters. Options are: * :pgn: An integer PGN to show """ channel_info = "j1939 bus" def __init__(self, pdu_type=PDU, *args, **kwargs): logger.debug("Creating a new j1939 bus") self.rx_can_message_queue = Queue() super(Bus, self).__init__() self._pdu_type = pdu_type self._long_message_throttler = threading.Thread( target=self._throttler_function) #self._long_message_throttler.daemon = True self._incomplete_received_pdus = {} self._incomplete_received_pdu_lengths = {} self._incomplete_transmitted_pdus = {} self._long_message_segment_queue = Queue(0) # Convert J1939 filters into Raw Can filters if 'j1939_filters' in kwargs and kwargs['j1939_filters'] is not None: filters = kwargs.pop('j1939_filters') logger.debug("Got filters: {}".format(filters)) can_filters = [] for filt in filters: can_id, can_mask = 0, 0 if 'pgn' in filt: can_id = filt['pgn'] << 8 # The pgn needs to be left shifted by 8 to ignore the CAN_ID's source address # Look at most significant 4 bits to determine destination specific if can_id & 0xF00000 == 0xF00000: logging.info("PDU2 (broadcast message)") can_mask = 0xFFFF00 else: logging.info("PDU1 (p2p)") can_mask = 0xFF0000 if 'source' in filt: # filter by source can_mask |= 0xFF can_id |= filt['source'] logger.info("added source", filt) logger.info("Adding CAN ID filter: {:0x}:{:0x}".format( can_id, can_mask)) can_filters.append({"can_id": can_id, "can_mask": can_mask}) kwargs['can_filters'] = can_filters logger.debug("Creating a new can bus") self.can_bus = RawCanBus(*args, **kwargs) self.can_notifier = Notifier(self.can_bus, [self.rx_can_message_queue.put]) self.j1939_notifier = Notifier(self, []) self._long_message_throttler.start() def recv(self, timeout=None): logger.debug("Waiting for new message") logger.debug("Timeout is {}".format(timeout)) try: m = self.rx_can_message_queue.get(timeout=timeout) except Empty: return rx_pdu = None if isinstance(m, Message): logger.debug('Got a Message: %s' % m) if m.id_type: # Extended ID # Only J1939 messages (i.e. 29-bit IDs) should go further than this point. # Non-J1939 systems can co-exist with J1939 systems, but J1939 doesn't care # about the content of their messages. logger.info('Message is j1939 msg') rx_pdu = self._process_incoming_message(m) else: logger.info("Received non J1939 message (ignoring)") # TODO: Decide what to do with CAN errors if m.is_error_frame: logger.warning("Appears we got an error frame!") #rx_error = CANError(timestamp=m.timestamp) # if rx_error is not None: # logger.info('Sending error "%s" to registered listeners.' % rx_error) # for listener in self.listeners: # if hasattr(listener, 'on_error_received'): # listener.on_error_received(rx_error) # Return to BusABC where it will get fed to any listeners return rx_pdu def send(self, msg): messages = [] if len(msg.data) > 8: # Making a copy of the PDU so that the original # is not altered by the data padding. pdu = copy.deepcopy(msg) pdu.data = bytearray(pdu.data) pdu_length_lsb, pdu_length_msb = divmod(len(pdu.data), 256) while len(pdu.data) % 7 != 0: pdu.data += b'\xFF' for i, segment in enumerate(pdu.data_segments(segment_length=7)): arbitration_id = copy.deepcopy(pdu.arbitration_id) arbitration_id.pgn.value = constants.PGN_TP_DATA_TRANSFER if pdu.arbitration_id.pgn.is_destination_specific and \ pdu.arbitration_id.destination_address != constants.DESTINATION_ADDRESS_GLOBAL: arbitration_id.pgn.pdu_specific = pdu.arbitration_id.pgn.pdu_specific else: arbitration_id.pgn.pdu_specific = constants.DESTINATION_ADDRESS_GLOBAL message = Message(arbitration_id=arbitration_id.can_id, extended_id=True, dlc=(len(segment) + 1), data=(bytearray([i + 1]) + segment)) messages.append(message) if pdu.arbitration_id.pgn.is_destination_specific and \ pdu.arbitration_id.destination_address != constants.DESTINATION_ADDRESS_GLOBAL: destination_address = pdu.arbitration_id.pgn.pdu_specific if pdu.arbitration_id.source_address in self._incomplete_transmitted_pdus: if destination_address in self._incomplete_transmitted_pdus[ pdu.arbitration_id.source_address]: logger.warning( "Duplicate transmission of PDU:\n{}".format(pdu)) else: self._incomplete_transmitted_pdus[ pdu.arbitration_id.source_address] = {} self._incomplete_transmitted_pdus[ pdu.arbitration_id. source_address][destination_address] = messages else: destination_address = constants.DESTINATION_ADDRESS_GLOBAL rts_arbitration_id = ArbitrationID(source_address=pdu.source) rts_arbitration_id.pgn.value = constants.PGN_TP_CONNECTION_MANAGEMENT rts_arbitration_id.pgn.pdu_specific = pdu.arbitration_id.pgn.pdu_specific temp_pgn = copy.deepcopy(pdu.arbitration_id.pgn) if temp_pgn.is_destination_specific: temp_pgn.value -= temp_pgn.pdu_specific pgn_msb = ((temp_pgn.value & 0xFF0000) >> 16) pgn_middle = ((temp_pgn.value & 0x00FF00) >> 8) pgn_lsb = (temp_pgn.value & 0x0000FF) if pdu.arbitration_id.pgn.is_destination_specific and \ pdu.arbitration_id.destination_address != constants.DESTINATION_ADDRESS_GLOBAL: # send request to send rts_msg = Message(extended_id=True, arbitration_id=rts_arbitration_id.can_id, data=[ constants.CM_MSG_TYPE_RTS, pdu_length_msb, pdu_length_lsb, len(messages), 0xFF, pgn_lsb, pgn_middle, pgn_msb ], dlc=8) self.can_bus.send(rts_msg) else: rts_arbitration_id.pgn.pdu_specific = constants.DESTINATION_ADDRESS_GLOBAL bam_msg = Message(extended_id=True, arbitration_id=rts_arbitration_id.can_id, data=[ constants.CM_MSG_TYPE_BAM, pdu_length_msb, pdu_length_lsb, len(messages), 0xFF, pgn_lsb, pgn_middle, pgn_msb ], dlc=8) # send BAM self.can_bus.send(bam_msg) for message in messages: # send data messages - no flow control, so no need to wait # for receiving devices to acknowledge self._long_message_segment_queue.put_nowait(message) else: can_message = Message(arbitration_id=msg.arbitration_id.can_id, extended_id=True, dlc=len(msg.data), data=msg.data) self.can_bus.send(can_message) def shutdown(self): self.can_notifier.running.clear() self.can_bus.shutdown() self.j1939_notifier.running.clear() super(Bus, self).shutdown() def _process_incoming_message(self, msg): logger.debug("Processing incoming message") logging.debug(msg) arbitration_id = ArbitrationID() arbitration_id.can_id = msg.arbitration_id if arbitration_id.pgn.is_destination_specific: arbitration_id.pgn.value -= arbitration_id.pgn.pdu_specific pdu = self._pdu_type(timestamp=msg.timestamp, data=msg.data, info_strings=[]) pdu.arbitration_id.can_id = msg.arbitration_id pdu.info_strings = [] if arbitration_id.pgn.value == constants.PGN_TP_CONNECTION_MANAGEMENT: retval = self._connection_management_handler(pdu) elif arbitration_id.pgn.value == constants.PGN_TP_DATA_TRANSFER: retval = self._data_transfer_handler(pdu) else: retval = pdu logging.debug(retval) return retval def _connection_management_handler(self, msg): if len(msg.data) == 0: msg.info_strings.append( "Invalid connection management message - no data bytes") return msg cmd = msg.data[0] retval = None if cmd == constants.CM_MSG_TYPE_RTS: retval = self._process_rts(msg) elif cmd == constants.CM_MSG_TYPE_CTS: retval = self._process_cts(msg) elif cmd == constants.CM_MSG_TYPE_EOM_ACK: retval = self._process_eom_ack(msg) elif cmd == constants.CM_MSG_TYPE_BAM: retval = self._process_bam(msg) elif cmd == constants.CM_MSG_TYPE_ABORT: retval = self._process_abort(msg) return retval def _data_transfer_handler(self, msg): msg_source = msg.arbitration_id.source_address pdu_specific = msg.arbitration_id.pgn.pdu_specific if msg_source in self._incomplete_received_pdus: if pdu_specific in self._incomplete_received_pdus[msg_source]: self._incomplete_received_pdus[msg_source][ pdu_specific].data.extend(msg.data[1:]) total = self._incomplete_received_pdu_lengths[msg_source][ pdu_specific]["total"] if len(self._incomplete_received_pdus[msg_source] [pdu_specific].data) >= total: if pdu_specific == constants.DESTINATION_ADDRESS_GLOBAL: # Looks strange but makes sense - in the absence of explicit flow control, # the last CAN packet in a long message *is* the end of message acknowledgement return self._process_eom_ack(msg) # Find a Node object so we can search its list of known node addresses for this node # so we can find if we are responsible for sending the EOM ACK message send_ack = any(True for l in self.j1939_notifier.listeners if isinstance(l, Node) and ( l.address == pdu_specific or pdu_specific in l.address_list)) if send_ack: arbitration_id = ArbitrationID() arbitration_id.pgn.value = constants.PGN_TP_CONNECTION_MANAGEMENT arbitration_id.pgn.pdu_specific = msg_source arbitration_id.source_address = pdu_specific total_length = self._incomplete_received_pdu_lengths[ msg_source][pdu_specific]["total"] _num_packages = self._incomplete_received_pdu_lengths[ msg_source][pdu_specific]["num_packages"] pgn = self._incomplete_received_pdus[msg_source][ pdu_specific].arbitration_id.pgn pgn_msb = ((pgn.value & 0xFF0000) >> 16) _pgn_middle = ((pgn.value & 0x00FF00) >> 8) _pgn_lsb = 0 div, mod = divmod(total_length, 256) can_message = Message( arbitration_id=arbitration_id.can_id, extended_id=True, dlc=8, data=[ constants.CM_MSG_TYPE_EOM_ACK, mod, # total_length % 256, div, # total_length / 256, _num_packages, 0xFF, _pgn_lsb, _pgn_middle, pgn_msb ]) self.can_bus.send(can_message) return self._process_eom_ack(msg) def _process_rts(self, msg): if msg.arbitration_id.source_address not in self._incomplete_received_pdus: self._incomplete_received_pdus[ msg.arbitration_id.source_address] = {} self._incomplete_received_pdu_lengths[ msg.arbitration_id.source_address] = {} # Delete any previous messages that were not finished correctly if msg.arbitration_id.pgn.pdu_specific in self._incomplete_received_pdus[ msg.arbitration_id.source_address]: del self._incomplete_received_pdus[ msg.arbitration_id.source_address][ msg.arbitration_id.pgn.pdu_specific] del self._incomplete_received_pdu_lengths[ msg.arbitration_id.source_address][ msg.arbitration_id.pgn.pdu_specific] if msg.data[0] == constants.CM_MSG_TYPE_BAM: self._incomplete_received_pdus[ msg.arbitration_id.source_address][0xFF] = self._pdu_type() self._incomplete_received_pdus[msg.arbitration_id.source_address][ 0xFF].arbitration_id.pgn.value = int( ("%.2X%.2X%.2X" % (msg.data[7], msg.data[6], msg.data[5])), 16) if self._incomplete_received_pdus[ msg.arbitration_id.source_address][ 0xFF].arbitration_id.pgn.is_destination_specific: self._incomplete_received_pdus[msg.arbitration_id.source_address][ 0xFF].arbitration_id.pgn.pdu_specific = msg.arbitration_id.pgn.pdu_specific self._incomplete_received_pdus[msg.arbitration_id.source_address][ 0xFF].arbitration_id.source_address = msg.arbitration_id.source_address self._incomplete_received_pdus[ msg.arbitration_id.source_address][0xFF].data = [] _message_size = int("%.2X%.2X" % (msg.data[2], msg.data[1]), 16) self._incomplete_received_pdu_lengths[ msg.arbitration_id.source_address][0xFF] = { "total": _message_size, "chunk": 255, "num_packages": msg.data[3], } else: self._incomplete_received_pdus[msg.arbitration_id.source_address][ msg.arbitration_id.pgn.pdu_specific] = self._pdu_type() self._incomplete_received_pdus[msg.arbitration_id.source_address][ msg.arbitration_id.pgn. pdu_specific].arbitration_id.pgn.value = int( ("%.2X%.2X%.2X" % (msg.data[7], msg.data[6], msg.data[5])), 16) if self._incomplete_received_pdus[msg.arbitration_id.source_address][ msg.arbitration_id.pgn. pdu_specific].arbitration_id.pgn.is_destination_specific: self._incomplete_received_pdus[msg.arbitration_id.source_address][ msg.arbitration_id.pgn. pdu_specific].arbitration_id.pgn.pdu_specific = msg.arbitration_id.pgn.pdu_specific self._incomplete_received_pdus[msg.arbitration_id.source_address][ msg.arbitration_id.pgn. pdu_specific].arbitration_id.source_address = msg.arbitration_id.source_address self._incomplete_received_pdus[msg.arbitration_id.source_address][ msg.arbitration_id.pgn.pdu_specific].data = [] _message_size = int("%.2X%.2X" % (msg.data[2], msg.data[1]), 16) self._incomplete_received_pdu_lengths[ msg.arbitration_id.source_address][ msg.arbitration_id.pgn.pdu_specific] = { "total": _message_size, "chunk": 255, "num_packages": msg.data[3], } if msg.data[0] != constants.CM_MSG_TYPE_BAM: for _listener in self.j1939_notifier.listeners: if isinstance(_listener, Node): # find a Node object so we can search its list of known node addresses # for this node - if we find it we are responsible for sending the CTS message if _listener.address == msg.arbitration_id.pgn.pdu_specific or msg.arbitration_id.pgn.pdu_specific in _listener.address_list: _cts_arbitration_id = ArbitrationID( source_address=msg.arbitration_id.pgn.pdu_specific) _cts_arbitration_id.pgn.value = constants.PGN_TP_CONNECTION_MANAGEMENT _cts_arbitration_id.pgn.pdu_specific = msg.arbitration_id.source_address _data = [0x11, msg.data[4], 0x01, 0xFF, 0xFF] _data.extend(msg.data[5:]) cts_msg = Message( extended_id=True, arbitration_id=_cts_arbitration_id.can_id, data=_data, dlc=8) # send clear to send self.can_bus.send(cts_msg) return def _process_cts(self, msg): if msg.arbitration_id.pgn.pdu_specific in self._incomplete_transmitted_pdus: if msg.arbitration_id.source_address in self._incomplete_transmitted_pdus[ msg.arbitration_id.pgn.pdu_specific]: # Next packet number in CTS message (Packet numbers start at 1 not 0) start_index = msg.data[2] - 1 # Using total number of packets in CTS message end_index = start_index + msg.data[1] for _msg in self._incomplete_transmitted_pdus[ msg.arbitration_id.pgn.pdu_specific][ msg.arbitration_id. source_address][start_index:end_index]: self.can_bus.send(_msg) def _process_eom_ack(self, msg): if (msg.arbitration_id.pgn.value - msg.arbitration_id.pgn.pdu_specific ) == constants.PGN_TP_DATA_TRANSFER: self._incomplete_received_pdus[msg.arbitration_id.source_address][ msg.arbitration_id.pgn.pdu_specific].timestamp = msg.timestamp retval = copy.deepcopy(self._incomplete_received_pdus[ msg.arbitration_id.source_address][ msg.arbitration_id.pgn.pdu_specific]) retval.data = retval.data[:self._incomplete_received_pdu_lengths[ msg.arbitration_id.source_address][msg.arbitration_id.pgn. pdu_specific]["total"]] del self._incomplete_received_pdus[ msg.arbitration_id.source_address][ msg.arbitration_id.pgn.pdu_specific] del self._incomplete_received_pdu_lengths[ msg.arbitration_id.source_address][ msg.arbitration_id.pgn.pdu_specific] else: if msg.arbitration_id.pgn.pdu_specific in self._incomplete_received_pdus: if msg.arbitration_id.source_address in self._incomplete_received_pdus[ msg.arbitration_id.pgn.pdu_specific]: self._incomplete_received_pdus[ msg.arbitration_id.pgn.pdu_specific][ msg.arbitration_id. source_address].timestamp = msg.timestamp retval = copy.deepcopy(self._incomplete_received_pdus[ msg.arbitration_id.pgn.pdu_specific][ msg.arbitration_id.source_address]) retval.data = retval.data[:self. _incomplete_received_pdu_lengths[ msg.arbitration_id.pgn. pdu_specific][ msg.arbitration_id. source_address]["total"]] del self._incomplete_received_pdus[ msg.arbitration_id.pgn.pdu_specific][ msg.arbitration_id.source_address] del self._incomplete_received_pdu_lengths[ msg.arbitration_id.pgn.pdu_specific][ msg.arbitration_id.source_address] else: retval = None else: retval = None if msg.arbitration_id.pgn.pdu_specific in self._incomplete_transmitted_pdus: if msg.arbitration_id.source_address in self._incomplete_transmitted_pdus[ msg.arbitration_id.pgn.pdu_specific]: del self._incomplete_transmitted_pdus[ msg.arbitration_id.pgn.pdu_specific][ msg.arbitration_id.source_address] return retval def _process_bam(self, msg): self._process_rts(msg) def _process_abort(self, msg): if msg.arbitration_id.pgn.pdu_specific in self._incomplete_received_pdus: if msg.source in self._incomplete_received_pdus[ msg.arbitration_id.pgn.pdu_specific]: del self._incomplete_received_pdus[ msg.arbitration_id.pgn.pdu_specific][ msg.arbitration_id.source_address] def _throttler_function(self): while self.can_notifier.running.is_set(): _msg = None try: _msg = self._long_message_segment_queue.get(timeout=0.1) except Empty: pass if _msg is not None: self.can_bus.send(_msg) @property def transmissions_in_progress(self): retval = 0 for _tx_address in self._incomplete_transmitted_pdus: retval += len(self._incomplete_transmitted_pdus[_tx_address]) for _rx_address in self._incomplete_received_pdus: retval += len(self._incomplete_received_pdus[_rx_address]) return retval
def dumpcan(): global var windowid = 0 for message in Bus(can_interface): if var == 1: msg = unicode(message).encode('utf-8') canid = msg[26:29] msg = msg[48:99] if canid == ("464"): if msg == ("20 02 02 00"): #Button Up - KODI Up xbmc.executeJSONRPC( '{"jsonrpc":"2.0","method":"Input.Up","id":1}') if msg == ("20 02 20 00"): #Button Down - KODI Down xbmc.executeJSONRPC( '{"jsonrpc":"2.0","method":"Input.Down","id":1}') if msg == ("20 02 01 00"): #Button Left - KODI Left xbmc.executeJSONRPC( '{"jsonrpc":"2.0","method":"Input.Left","id":1}') if msg == ("20 02 03 00"): #Button Right - KODI Right xbmc.executeJSONRPC( '{"jsonrpc":"2.0","method":"Input.Right","id":1}') if msg == ("20 02 04 00"): #Button AS - KODI OK xbmc.executeJSONRPC( '{"jsonrpc":"2.0","method":"Input.Select","id":1}') if msg == ("20 02 00 50"): #Button Return - KODI Back xbmc.executeJSONRPC( '{"jsonrpc":"2.0","method":"Input.Back","id":1}') if msg == ("20 02 00 05"): #Encoder Button Pressed - KODI OK xbmc.executeJSONRPC( '{"jsonrpc":"2.0","method":"Input.Select","id":1}') if msg == ("20 01 00 ff" ): #Right Encoder Rotation to Left - KODI UP xbmc.executeJSONRPC( '{"jsonrpc":"2.0","method":"Input.Up","id":1}') if msg == ("20 01 01 ff" ): #Right Encoder Rotation to Left - KODI Down xbmc.executeJSONRPC( '{"jsonrpc":"2.0","method":"Input.Down","id":1}') if msg == ("20 02 00 20"): #Button - Kodi Up windowid = xbmcgui.getCurrentWindowId() if (windowid == 12006): # MusicVisualisation.xml xbmc.executeJSONRPC( '{"jsonrpc":"2.0","method":"Player.Seek","params":{"playerid":0,"value":"bigforward"},"id":1}' ) elif (windowid == 12005): # VideoFullScreen.xml xbmc.executeJSONRPC( '{"jsonrpc":"2.0","method":"Player.Seek","params":{"playerid":1,"value":"bigforward"},"id":1}' ) else: xbmc.executeJSONRPC( '{"jsonrpc":"2.0","method":"Input.Up","id":1}') if msg == ("20 02 00 01"): #Button + KODI - windowid = xbmcgui.getCurrentWindowId() if (windowid == 12006): # MusicVisualisation.xml xbmc.executeJSONRPC( '{"jsonrpc":"2.0","method":"Player.Seek","params":{"playerid":0,"value":"bigbackward"},"id":1}' ) elif (windowid == 12005): # VideoFullScreen.xml xbmc.executeJSONRPC( '{"jsonrpc":"2.0","method":"Player.Seek","params":{"playerid":1,"value":"bigbackward"},"id":1}' ) else: xbmc.executeJSONRPC( '{"jsonrpc":"2.0","method":"Input.Down","id":1}') if msg == ("20 02 00 03"): #Button Mode - KODI Context menu windowid = xbmcgui.getCurrentWindowId() if (windowid == 12006): # MusicVisualisation.xml xbmc.executeJSONRPC( '{"jsonrpc":"2.0","method":"Input.ShowOSD","id":1}' ) elif (windowid == 12005): # VideoFullScreen.xml xbmc.executeJSONRPC( '{"jsonrpc":"2.0","method":"Input.ShowOSD","id":1}' ) else: xbmc.executeJSONRPC( '{"jsonrpc":"2.0","method":"Input.ContextMenu","id":1}' ) if msg == ("00 02"): #Stop Player if power OFF xbmc.executeJSONRPC( '{"jsonrpc":"2.0","method":"Player.Stop","params":{"playerid":1},"id":1}' ) if canid == ("218"): if msg == ("01 02"): #Stop Player if key disable xbmc.executeJSONRPC( '{"jsonrpc":"2.0","method":"Player.Stop","params":{"playerid":1},"id":1}' )
def __init__(self): self.bus = Bus('can0', bustype='socketcan_ctypes') self.rx_buff = [] self.tx_buff = []
def pushCan(canId, data): bus = Bus(channel=can_interface) msg = can.Message(arbitration_id=canId, data=(data).to_bytes(4, byteorder='little'), extended_id=True) bus.send(msg)
class driver: """ Driver construcotr @param interface Name of the CAN interface to listen on @param verbose On true, print extra verbose debugging info @param listeners Additional listeners for CAN notifier """ def __init__(self, interface, verbose = False, listeners = None): self.bus = Bus(interface, bustype = 'socketcan') self.verbose = verbose self.listeners = listeners self.bms = bms.bms() self.ccs = ccs.ccs() self.notifier = can.Notifier(self.bus, [self.on_message_received]) """ Starts a loop to keep notifier alive. Do not use if you already have an event loop. @exception on any thrown event, shuts down bus and stops notifier """ def listen(self): try: while True: time.sleep(1) except KeyboardInterrupt: print("Exception Handled!") self.bus.shutdown() self.notifier.stop() """ TODO DOC """ def notify_listeners(self, hypercan_message): for listener in self.listeners: listener(hypercan_message, self) """ Function is called whenever the notifier receives a message. @param message Python-CAN message object @return hypermessage Hyperloop level message dictionary """ def on_message_received(self, message): # Verbose output if self.verbose: print("Message Receieved") canFrameVars = vars(message) for var in canFrameVars: print(var+": "+str(canFrameVars[var])) # Properly handle messages if message.arbitration_id == 0x18FF50E5: self.notify_listeners(self.ccs.handle_message(message)) elif message.arbitration_id >= 0x620 and message.arbitration_id <= 0x628: self.notify_listeners(self.bms.handle_message(message)) elif self.verbose: # Eventually I need to add an exception class here....and add the motor controller # It is also noteworthy that this block may be deleted completely, there are many # arbitration IDs that we can safely ignore transmitted over the bus print('Unknown arbitration ID '+hex(message.arbitration_id)) #raise Exception('Unknown arbitration ID '+str(message.arbitration_id)) """ Attempts to send message over CAN bus @param Message CAN message object to TX @throws on CAN error """ def send_message(self, Message): try: self.bus.send(Message); except: print("Some error was handled")
if GPS_logging: # Arguments are the log filename and if debugging is on or off os.system('gpsd /dev/ttyO5 -F /var/run/gpsd.sock') time.sleep(0.5) gps_thread = GPSPoller('./logs/gps.csv', False) gps_thread.start() if CAN_logging: """ Sleep a bit to allow the system to enable CAN interfaces """ time.sleep(5) # can.rc['interface'] = 'socketcan_ctypes' can_interface = 'can0' bus = Bus(can_interface) # Arguments are the bus we're listening on and the function called on a # detected event. notifier = can.Notifier(bus, [ParseAndStore()]) if MPU_logging: i2c_bus = 1 device_address = 0x68 # The offsets are different for each device and should be changed to # sutiable figures using a calibration procedure x_accel_offset = -5489 y_accel_offset = -1441 z_accel_offset = 1305 x_gyro_offset = -2 y_gyro_offset = -72 z_gyro_offset = -5