Read a packet from the input.

def _read_packet(self):
        """Read a packet from the input."""

        status = STATUS_WAITING
        mode = 0
        checksum = 0
        checksum_calculated = 0
        length = 0
        version = 0
        i = 0
        cnt = 0
        packet = bytearray(0)

        while (status != STATUS_PACKET_DONE):

            read = self._read_ord_byte()
            if (status != STATUS_CTRL_CHECKSUM and status != STATUS_SENSE_CHECKSUM):
                checksum_calculated = self._add_to_checksum(checksum_calculated, read)
            self._debug(PROP_LOGLEVEL_TRACE, "R: " + str(read))
            self._debug(PROP_LOGLEVEL_TRACE, "S: " + str(status))

            if (status == STATUS_WAITING):
                if (read == 2):
                    status = STATUS_PRE_1
                    checksum_calculated = read
                else:
                    status = STATUS_WAITING
            elif (status == STATUS_PRE_1):
                checksum = 0
                if (read == 2):
                    status = STATUS_SENSE_PRE_2
                    checksum_calculated = read
                elif (read == 0):
                    status = STATUS_WAITING
                else:
                    status = STATUS_CTRL_PRE_2
            elif (status == STATUS_SENSE_PRE_2):
                length = read
                status = STATUS_SENSE_PRE_LENGTH
            elif (status == STATUS_SENSE_PRE_LENGTH):
                version = read
                status = STATUS_SENSE_PRE_3
            elif (status == STATUS_SENSE_PRE_3):
                cnt = read
                i = 0
                status = STATUS_SENSE_DATA
            elif (status == STATUS_SENSE_DATA):
                packet.append(read)
                i = i + 1
                if (i == length):
                    status = STATUS_SENSE_CHECKSUM
            elif (status == STATUS_SENSE_CHECKSUM):
                checksum = read
                mode = PROP_PACKET_SENSE
                status = STATUS_PACKET_DONE
            elif (status == STATUS_CTRL_PRE_2):
                version = read
                status = STATUS_CTRL_PRE_3
            elif (status == STATUS_CTRL_PRE_3):
                cnt = read
                i = 0
                length = 16
                status = STATUS_CTRL_DATA
            elif (status == STATUS_CTRL_DATA):
                packet.append(read)
                i = i + 1
                if (i == length):
                    status = STATUS_CTRL_CHECKSUM
            elif (status == STATUS_CTRL_CHECKSUM):
                checksum = read
                mode = PROP_PACKET_CTRL
                status = STATUS_PACKET_DONE
            else:
                status = STATUS_WAITING

        self._debug(PROP_LOGLEVEL_DEBUG, "MODE: " + str(mode) + " Version: " + str(version) + " Checksum: " + str(checksum) + " / " + str(checksum_calculated) + " Count: " + str(cnt) + " Length: " + str(len(packet)))
        self._debug(PROP_LOGLEVEL_TRACE, "Packet: " + str(packet))

        return (mode, version, packet)