+ def handle_packet(self):
+ packet = ''
+ for (bit, ss, es) in self.bits:
+ packet += bit
+
+ # Bits[0:7]: SYNC
+ sync = packet[:7 + 1]
+ self.ss, self.es = self.bits[0][1], self.bits[7][2]
+ # The SYNC pattern for low-speed/full-speed is KJKJKJKK (00000001).
+ if sync != '00000001':
+ self.putpb(['SYNC ERROR', sync])
+ self.putb([0, ['SYNC ERROR: %s' % sync]])
+ else:
+ self.putpb(['SYNC', sync])
+ self.putb([0, ['SYNC: %s' % sync]])
+ self.packet.append(sync)
+
+ # Bits[8:15]: PID
+ pid = packet[8:15 + 1]
+ pidname = pids.get(pid, (pid, ''))[0]
+ self.ss, self.es = self.bits[8][1], self.bits[15][2]
+ self.putpb(['PID', pidname])
+ self.putb([0, ['PID: %s' % pidname]])
+ self.packet.append(pid)
+ self.packet_summary += pidname
+
+ if pidname in ('OUT', 'IN', 'SOF', 'SETUP', 'PRE', 'PING'):
+ if pidname == 'SOF':
+ # Bits[16:26]: Framenum
+ framenum = bitstr_to_num(packet[16:26 + 1])
+ self.ss, self.es = self.bits[16][1], self.bits[26][2]
+ self.putpb(['FRAMENUM', framenum])
+ self.putb([0, ['Frame: %d' % framenum]])
+ self.packet.append(framenum)
+ self.packet_summary += ' %d' % framenum
+ else:
+ # Bits[16:22]: Addr
+ addr = bitstr_to_num(packet[16:22 + 1])
+ self.ss, self.es = self.bits[16][1], self.bits[22][2]
+ self.putpb(['ADDR', addr])
+ self.putb([0, ['Addr: %d' % addr]])
+ self.packet.append(addr)
+ self.packet_summary += ' ADDR %d' % addr
+
+ # Bits[23:26]: EP
+ ep = bitstr_to_num(packet[23:26 + 1])
+ self.ss, self.es = self.bits[23][1], self.bits[26][2]
+ self.putpb(['EP', ep])
+ self.putb([0, ['EP: %d' % ep]])
+ self.packet.append(ep)
+ self.packet_summary += ' EP %d' % ep
+
+ # Bits[27:31]: CRC5
+ crc5 = bitstr_to_num(packet[27:31 + 1])
+ self.ss, self.es = self.bits[27][1], self.bits[31][2]
+ self.putpb(['CRC5', crc5])
+ self.putb([0, ['CRC5: 0x%02x' % crc5]])
+ self.packet.append(crc5)
+ elif pidname in ('DATA0', 'DATA1', 'DATA2', 'MDATA'):
+ # Bits[16:packetlen-16]: Data
+ data = packet[16:-16]
+ # TODO: len(data) must be a multiple of 8.
+ databytes = []
+ self.packet_summary += ' ['
+ for i in range(0, len(data), 8):
+ db = bitstr_to_num(data[i:i + 8])
+ self.ss, self.es = self.bits[16 + i][1], self.bits[23 + i][2]
+ self.putpb(['DATABYTE', db])
+ self.putb([0, ['Databyte: %02x' % db]])
+ databytes.append(db)
+ self.packet_summary += ' %02x' % db
+ data = data[8:]
+ self.packet_summary += ' ]'
+
+ # Convenience proto output (no annotation) for all bytes together.
+ self.ss, self.es = self.bits[16][1], self.bits[-16][2]
+ self.putpb(['DATABYTES', databytes])
+ self.packet.append(databytes)
+
+ # Bits[packetlen-16:packetlen]: CRC16
+ crc16 = bitstr_to_num(packet[-16:])
+ self.ss, self.es = self.bits[-16][1], self.bits[-1][2]
+ self.putpb(['CRC16', crc16])
+ self.putb([0, ['CRC16: 0x%04x' % crc16]])
+ self.packet.append(crc16)
+ elif pidname in ('ACK', 'NAK', 'STALL', 'NYET', 'ERR'):
+ pass # Nothing to do, these only have SYNC+PID+EOP fields.
+ else:
+ pass # TODO: Handle 'SPLIT' and possibly 'Reserved' packets.
+
+ # Output a (summary of) the whole packet.
+ pcategory, pname, pinfo = get_category(pidname), pidname, self.packet
+ self.putpp(['PACKET', [pcategory, pname, pinfo]])
+ self.putp([0, ['PACKET: %s' % self.packet_summary]])
+
+ self.packet, self.packet_summary = [], ''
+