'Try to return a decrypted, authenticated, and decompressed packet
out of the buffer.  If there is not enough data, return None.
@rtype: L{str} or L{None}
@return: The decoded packet, if any.'

def getPacket(self):

    bs = self.currentEncryptions.decBlockSize
    ms = self.currentEncryptions.verifyDigestSize
    if (len(self.buf) < bs):
        return
    if (not hasattr(self, 'first')):
        first = self.currentEncryptions.decrypt(self.buf[:bs])
    else:
        first = self.first
        del self.first
    (packetLen, paddingLen) = struct.unpack('!LB', first[:5])
    if (packetLen > 1048576):
        self.sendDisconnect(DISCONNECT_PROTOCOL_ERROR, networkString(('bad    packet    length    %s' % (packetLen,))))
        return
    if (len(self.buf) < ((packetLen + 4) + ms)):
        self.first = first
        return
    if (((packetLen + 4) % bs) != 0):
        self.sendDisconnect(DISCONNECT_PROTOCOL_ERROR, networkString(('bad    packet    mod    (%i%%%i    ==    %i)' % ((packetLen + 4), bs, ((packetLen + 4) % bs)))))
        return
    (encData, self.buf) = (self.buf[:(4 + packetLen)], self.buf[(4 + packetLen):])
    packet = (first + self.currentEncryptions.decrypt(encData[bs:]))
    if (len(packet) != (4 + packetLen)):
        self.sendDisconnect(DISCONNECT_PROTOCOL_ERROR, 'bad    decryption')
        return
    if ms:
        (macData, self.buf) = (self.buf[:ms], self.buf[ms:])
        if (not self.currentEncryptions.verify(self.incomingPacketSequence, packet, macData)):
            self.sendDisconnect(DISCONNECT_MAC_ERROR, 'bad    MAC')
            return
    payload = packet[5:(- paddingLen)]
    if self.incomingCompression:
        try:
            payload = self.incomingCompression.decompress(payload)
        except:
            log.err()
            self.sendDisconnect(DISCONNECT_COMPRESSION_ERROR, 'compression    error')
            return
    self.incomingPacketSequence += 1
    return payload
