Beispiel #1
0
    def _WaitForIBSMessage(self, pgn, fromsa, tosa, muxByte, maxtime=3.0):
        # TODO: Also accept incoming TP session
        # TODO: Can we miss messages because we start listening too late?

        received = False
        data = [RESERVED] * 8  # Dummy data for when nothing is received
        starttime = time.time()
        matchID = IBSID(da=tosa, sa=fromsa, pgn=pgn, prio=6)
        while not (received):
            mesg = self.bus.recv(0.5)
            if mesg is not None:
                receivedID = IBSID.FromCANID(mesg.arbitration_id)
                if (receivedID.pgn == matchID.pgn
                        and receivedID.da == matchID.da
                        and receivedID.sa == matchID.sa
                        and mesg.data[0] == muxByte):
                    received = True
                    data = mesg.data
                    break
            if (time.time() - starttime) > maxtime:
                log.debug('Timeout waiting for CAN ID {canid:08X}'.format(
                    canid=matchID.GetCANID()))
                break

        return received, data
Beispiel #2
0
 def StopPeriodicMessage(self, ibsid):
     # For socketcan_native, bit 32 (MSb) needs to be set for extended ID
     # Is fixed in latest python-can though!
     for periodMsg in self.periodic_tasks:
         if periodMsg.can_id == (ibsid.GetCANID() | (1 << 31)):
             log.debug(
                 'Stopping periodic message ID : 0x{mesgid:08X}'.format(
                     mesgid=ibsid.GetCANID()))
             self.periodic_tasks.remove(periodMsg)
             periodMsg.stop()
             break
Beispiel #3
0
 def AddPeriodicMessage(self, ibsid, contents, period):
     # For socketcan_native, bit 32 (MSb) needs to be set for extended ID
     # Is fixed in latest python-can though!
     log.debug(
         'Adding periodic message ID : 0x{mesgid:08X} period {T}'.format(
             mesgid=ibsid.GetCANID(), T=period))
     msg = can.Message(arbitration_id=(ibsid.GetCANID() | (1 << 31)),
                       data=contents,
                       extended_id=True)
     self.periodic_tasks.append(
         can.send_periodic(can.rc['channel'], msg, period))
Beispiel #4
0
    def on_message_received(self, mesg):
        #TODO: Check 'listening' flag, if listening, store in queue
        #      Change 'WaitForIBSMessage' accordingly, so we don't have to call recv on bus
        #      Then we need a 'Start listening' and 'StopListening' + flushqueue method

        ibsid = IBSID.FromCANID(mesg.arbitration_id)
        log.debug('Rx Mesg PGN {pgn:04X} SA {sa:02X} DA {da:02X}'.format(
            pgn=ibsid.pgn, sa=ibsid.sa, da=ibsid.da))

        #TODO: Smarter filters, SA, DA, PGN, muxbyte?
        for handler in self._rxHandlers:
            if pgn in handler.pgnlist:
                handler.RxMessage(ibsid, mesg.data)
Beispiel #5
0
    def StoreVersion(self, version):
        self._CheckAlive()
        log.debug('Storing version {0}'.format(version))

        self.connection.SendStoreVersioncommand(version, self.da, self.sa)

        # TODO wait for load version response max 3 status messages w/parsing = 0
        [receivedResponse,
         error] = self.connection.WaitStoreVersionResponse(self.da, self.sa)
        if receivedResponse and (error == 0):
            pass
        else:
            raise IBSException(
                "Did not store version, error code: {0}".format(error))
Beispiel #6
0
    def ChangeActiveMask(self, wsid, maskid):
        self._CheckAlive()

        self.connection.SendChangeActiveMask(wsid, maskid, self.sa, self.da)

        [receivedResponse, newMaskID,
         error] = (self.connection.WaitForChangeActiveMaskResponse(
             self.da, self.sa))

        if receivedResponse and (error == 0):
            log.debug("New active mask = 0X{:04X}".format(newMaskID))
            ret = True
        elif receivedResponse:
            raise IBSException(
                "Error change active mask, error code: {0}".format(error))
        else:
            raise IBSException("No response received")
Beispiel #7
0
    def _SendTPMessage(self, pgn, da, sa, data):
        log.debug('(TP) Request starting TP for {n} bytes'.format(n=len(data)))
        tpcm_id = IBSID(da, sa, pgn=PGN_TP_CM, prio=6)
        tpdt_id = IBSID(da, sa, pgn=PGN_TP_DT, prio=7)

        # Send RTS
        rts_control = 0x10
        nr_of_packets = int(math.ceil(len(data) / 7.0))
        rts_data = ([rts_control] + NumericValue(len(data)).AsLEBytes(2) +
                    [nr_of_packets, RESERVED] + NumericValue(pgn).AsLEBytes(3))

        log.debug(
            '(TP) Sending RTS for PGN {0} : {1} bytes in {2} packets'.format(
                pgn, len(data), nr_of_packets))
        self._SendCANMessage(tpcm_id.GetCANID(), rts_data)

        # Check the CTS
        #FIXME: Only send min(nrOfPackets,maxPackets), what to do if less?
        [received, ctsdata] = self._WaitForIBSMessage(0xEC00, da, sa, 0x11)
        if received:
            log.debug('(TP) Received CTS for max {0} packets, next packet {1}'.
                      format(ctsdata[1], ctsdata[2]))

        else:
            return False

        # Pack with 0xFF
        if len(data) % 7 > 0:
            data = data + list([RESERVED] * (7 - (len(data) % 7)))

        # Send bytes
        for seqN in range(nr_of_packets):
            log.debug('(TP) Send package {n}'.format(n=seqN + 1))
            startByte = seqN * 7
            self._SendCANMessage(tpdt_id.GetCANID(),
                                 [seqN + 1] + data[startByte:startByte + 7])
            # sleep 1 msec, otherwise hardware buffer gets full!
            time.sleep(0.001)
Beispiel #8
0
 def SendAddressClaim(self, ibsName, sa):
     log.debug('Sending Address claim for name {:016X}'.format(ibsName))
     candata = NumericValue(ibsName).AsLEBytes(8)
     self._SendIBSMessage(PGN_ADDRCLAIM, SA_GLOBAL, sa, candata)
Beispiel #9
0
 def SendRequestAddressClaim(self, sa):
     log.debug('Sending Request Address Claim')
     self.SendRequest(sa, da=SA_GLOBAL, reqPGN=PGN_ADDRCLAIM)
Beispiel #10
0
    def _SendETPMessage(self, pgn, da, sa, data):
        log.debug(
            '(ETP) Request starting ETP for {n} bytes'.format(n=len(data)))
        etpcm_id = IBSID(da, sa, PGN_ETP_CM, prio=6)
        etpdt_id = IBSID(da, sa, PGN_ETP_DT, prio=7)

        mesg_size = len(data)

        # Send RTS
        rts_control = 0x14
        totalPackets = int(math.ceil(len(data) / 7.0))

        log.debug("(ETP) Sending {0} bytes in {1} packets".format(
            len(data), totalPackets))

        rts_data = ([rts_control] + NumericValue(mesg_size).AsLEBytes(4) +
                    NumericValue(pgn).AsLEBytes(3))
        self._SendCANMessage(etpcm_id.GetCANID(), rts_data)

        # Pack data with 0xFF to multiple of 7
        if len(data) % 7 > 0:
            data = data + list([RESERVED] * (7 - (len(data) % 7)))

        # Setup for the data transfer
        nextPacket = 1
        maxSentPackets = 0
        done = False

        while not (done):
            # TODO: What is the time out for this one?
            [received, ctsdata] = self._WaitForIBSMessage(0xC800, da, sa, 0x15)
            if received:
                nextPacket = NumericValue.FromLEBytes(ctsdata[2:5]).Value()
                maxSentPackets = ctsdata[1]
                log.debug(
                    "(ETP) Received CTS for max {0} packets, next packet {1}".
                    format(maxSentPackets, nextPacket))
            else:
                log.warning('(ETP) Wait for CTS timed out')
                break

            packetOffset = nextPacket - 1

            nPackets = min(maxSentPackets, totalPackets - packetOffset)

            log.debug(
                '(ETP) Sending {0} packets with packet offset {1}'.format(
                    nPackets, packetOffset))
            log.debug('(ETP) bytes[{0} - {1}]'.format(
                packetOffset * 7, packetOffset * 7 + nPackets * 7 - 1))

            dpoData = ([0x16] + [nPackets] +
                       NumericValue(packetOffset).AsLEBytes(3) +
                       NumericValue(pgn).AsLEBytes(3))
            self._SendCANMessage(etpcm_id.GetCANID(), dpoData)

            for n in range(nPackets):
                startByte = (n * 7) + (packetOffset * 7)
                # Send send data[n * 7 + dataoffset: n* 7 +7 + dataoffset]
                self._SendCANMessage(etpdt_id.GetCANID(),
                                     [n + 1] + data[startByte:startByte + 7])

                # If it is the last packet, quit the loop
                if (n + nextPacket) >= totalPackets:
                    done = True
                    break

                time.sleep(0.001)
Beispiel #11
0
 def SendIdentifyVT(self, sa):
     log.debug('Sending identify VT')
     self._SendIBSMessage(PGN_ECU2VT, 0xFF, sa, [0xBB] + (7 * [0xFF]))