'''This Protocol subclass handles the lower level of the on-wire format. It decodes the packet length, separates message type and payload, and verifies checksum. It does not decode the Protocol Buffer messages. ''' from twisted.protocols import basic from twisted.python import log class PacketFormat(basic.Int16StringReceiver): '''Handles a simple packet format: (LEN LEN) TYPE PAYLOAD CHECKSUM ''' def getChecksum(self, string): '''Compute a checksum by XORing all bytes in the string. Returns integer. ''' checksum = 0xFF for b in string: checksum ^= ord(b) return checksum def stringReceived(self, string): if len(string) < 2: self.protocolError("packet too short") return if self.getChecksum(string) != 0: self.protocolError("checksum wrong") return msgtype = ord(string[0]) payload = string[1:-1] log.msg("Received: " + repr(msgtype) + " " + repr(payload)) self.messageReceived(msgtype, payload) def messageReceived(self, msgtype, payload): '''Override this to handle received messages.''' raise NotImplementedError def protocolError(self, error): '''Override this to handle protocol errors.''' print error log.err(error) self.transport.loseConnection() def sendMessage(self, msgtype, payload): if hasattr(payload, "SerializeToString"): payload = payload.SerializeToString() message = chr(msgtype) + payload message += chr(self.getChecksum(message)) log.msg("Sending: " + repr(message)) self.sendString(message)