def _processIncomingPacket(self, packet): ''' Takes a raw packet, checks it and returns the correct packet class ''' # Check for special bytes n packet that shouldn't be there if protocol.START_BYTE in packet or protocol.END_BYTE in packet: raise ParsingException, 'Unescaped bytes found in packet: %s' % protocols.toHex(packet) # Process escapes processed = 0 while protocol.ESCAPE_BYTE in packet[processed:]: i = packet.index(protocol.ESCAPE_BYTE, processed) processed = i+1 # Convert escaped byte to an integer to XOR, and then convert back to a string unescaped = chr(ord(packet[i+1]) ^ 0xFF) if unescaped in protocol.SPECIAL_BYTES: packet = packet[:i] + unescaped + packet[i+2:] else: raise ParsingException, 'Wrongly escaped byte found in packet (%s): %s' % (hex(ord(unescaped)), protocols.toHex(packet)) if not len(packet): raise IgnorableParsingException, 'Packet is empty' if len(packet) < 4: raise ParsingException, 'Packet does not contain required information. Packet content: %s' % protocols.toHex(packet) # Split up packet contents = { 'flags': packet[0], 'payload_id': protocols.shortFrom8bit(packet[1:3]), 'payload': packet[3:-1], 'checksum': packet[-1] } # Check checksum gen_checksum = packetlib.getChecksum(packet[:-1]) if contents['checksum'] != gen_checksum: raise ParsingException, 'Checksum is incorrect! Provided: %d, generated: %d, packet: [%s]' % (ord(contents['checksum']), ord(gen_checksum), protocols.toHex(packet)) # Create response packet object response = responses.getPacket(contents['payload_id']) # Populate data response.parseHeaderFlags(contents['flags']) response.setPayloadId(contents['payload_id']) response.parsePayload(contents['payload']) response.validate() return response
def _processBuffer(self): ''' Check for any incoming packets and return if found - Removing anything before first START_BYTE - Check for END_BYTE - Loop though buffer copy - If complete packet found, remove length from buffer - If incomplete packet, leave buffer and try again later ''' try: index = -1 # Remove any buffer before the first start byte if self._cache[0] != protocol.START_BYTE: index = self._cache.find(protocol.START_BYTE, 1) if index >= 0: if self._cache[:index] == protocol.END_BYTE: raise IgnorableParsingException, 'Ignorable packet found in buffer before start byte %s' % protocols.toHex(self._cache[:index]) else: raise ParsingException, 'Bad/incomplete packet found in buffer before start byte %s' % protocols.toHex(self._cache[:index]) except ParsingException: # Catch parsing eceptions and tidy up the buffer if index >= 0: self._cache = self._cache[index:] else: self._cache = '' raise # If another start byte in buffer before next end byte s = self._cache.find(protocol.START_BYTE, 1) if s >= 0: # Find end byte before second start byte e = self._cache.find(protocol.END_BYTE, 1, s) # If no end byte before second byte, incomplete packet if e == -1: # Remove from buffer # Nasty try/raise/except/raise construct here so we can wipe the cache try: if self._cache[:s] == protocol.START_BYTE: raise IgnorableParsingException, 'Ignorable packet found in buffer missing end byte %s' % protocols.toHex(self._cache[:s]) else: raise ParsingException, 'Bad/incomplete packet found in buffer missing end byte %s' % protocols.toHex(self._cache[:s]) except ParsingException: # Tidy up buffer self._cache = self._cache[s:] raise # If no end byte in buffer, return as it must not contain a complete packet if protocol.END_BYTE not in self._cache: return # Grab packet from buffer (minus start and end bytes) end = self._cache.index(protocol.END_BYTE) packet = self._cache[1:end] # Clear processed buffer self._cache = self._cache[end+1:] # Process packet return self._processIncomingPacket(packet)
def getHex(self): ''' Return a packet as hex strings ''' packet = self._buildPacket() return protocols.toHex(packet)