def parse_msg(buf): ''' Parses message from buffer. returns: - PARSE_RESULT - remaining buffer - Packet -object (if message was valid, else None) ''' # If the buffer doesn't contain 0x55 (start char) # the message isn't needed -> ignore if 0x55 not in buf: return PARSE_RESULT.INCOMPLETE, [], None # Valid buffer starts from 0x55 # Convert to list, as index -method isn't defined for bytearray buf = buf[list(buf).index(0x55):] try: data_len = (buf[1] << 8) | buf[2] opt_len = buf[3] except IndexError: # If the fields don't exist, message is incomplete return PARSE_RESULT.INCOMPLETE, buf, None # Header: 6 bytes, data, optional data and data checksum msg_len = 6 + data_len + opt_len + 1 if len(buf) < msg_len: # If buffer isn't long enough, the message is incomplete return PARSE_RESULT.INCOMPLETE, buf, None msg = buf[0:msg_len] buf = buf[msg_len:] packet_type = msg[4] data = msg[6:6 + data_len] opt_data = msg[6 + data_len:6 + data_len + opt_len] # Check CRCs for header and data if msg[5] != crc8.calc(msg[1:5]): # Fail if doesn't match message logger.error('Header CRC error!') # Return CRC_MISMATCH return PARSE_RESULT.CRC_MISMATCH, buf, None if msg[6 + data_len + opt_len] != crc8.calc(msg[6:6 + data_len + opt_len]): # Fail if doesn't match message logger.error('Data CRC error!') # Return CRC_MISMATCH return PARSE_RESULT.CRC_MISMATCH, buf, None # If we got this far, everything went ok (?) if packet_type == PACKET.RADIO: p = RadioPacket(packet_type, data, opt_data) elif packet_type == PACKET.RESPONSE: p = ResponsePacket(packet_type, data, opt_data) else: p = Packet(packet_type, data, opt_data) return PARSE_RESULT.OK, buf, p
def build(self): ''' Build Packet for sending to EnOcean controller ''' data_length = len(self.data) ords = [0x55, (data_length >> 8) & 0xFF, data_length & 0xFF, len(self.optional), int(self.type)] ords.append(crc8.calc(ords[1:5])) ords.extend(self.data) ords.extend(self.optional) ords.append(crc8.calc(ords[6:])) return ords
def build(self): ''' Build Packet for sending to EnOcean controller ''' data_length = len(self.data) ords = [0x55, (data_length >> 8) & 0xFF, data_length & 0xFF, len(self.optional), int(self.packet_type)] ords.append(crc8.calc(ords[1:5])) ords.extend(self.data) ords.extend(self.optional) ords.append(crc8.calc(ords[6:])) return ords
def parse_msg(buf, communicator=None): ''' Parses message from buffer. returns: - PARSE_RESULT - remaining buffer - Packet -object (if message was valid, else None) ''' # If the buffer doesn't contain 0x55 (start char) # the message isn't needed -> ignore if 0x55 not in buf: return PARSE_RESULT.INCOMPLETE, [], None # Valid buffer starts from 0x55 # Convert to list, as index -method isn't defined for bytearray buf = [ord(x) if not isinstance(x, int) else x for x in buf[list(buf).index(0x55):]] try: data_len = (buf[1] << 8) | buf[2] opt_len = buf[3] except IndexError: # If the fields don't exist, message is incomplete return PARSE_RESULT.INCOMPLETE, buf, None # Header: 6 bytes, data, optional data and data checksum msg_len = 6 + data_len + opt_len + 1 if len(buf) < msg_len: # If buffer isn't long enough, the message is incomplete return PARSE_RESULT.INCOMPLETE, buf, None msg = buf[0:msg_len] buf = buf[msg_len:] logging.debug(msg) packet_type = msg[4] data = msg[6:6 + data_len] opt_data = msg[6 + data_len:6 + data_len + opt_len] # Check CRCs for header and data if msg[5] != crc8.calc(msg[1:5]): # Fail if doesn't match message logging.error('Header CRC error!') # Return CRC_MISMATCH return PARSE_RESULT.CRC_MISMATCH, buf, None if msg[6 + data_len + opt_len] != crc8.calc(msg[6:6 + data_len + opt_len]): # Fail if doesn't match message logging.error('Data CRC error!') # Return CRC_MISMATCH return PARSE_RESULT.CRC_MISMATCH, buf, None # If we got this far, everything went ok (?) if packet_type == PACKET.RADIO: # Need to handle UTE Teach-in here, as it's a separate packet type... if data[0] == RORG.UTE: packet = UTETeachIn(packet_type, data, opt_data, communicator=communicator) # Send a response automatically, works only if # - communicator is set # - communicator.teach_in == True packet.send_response() else: packet = RadioPacket(packet_type, data, opt_data) elif packet_type == PACKET.RESPONSE: packet = ResponsePacket(packet_type, data, opt_data) elif packet_type == PACKET.EVENT: packet = EventPacket(packet_type, data, opt_data) else: packet = Packet(packet_type, data, opt_data) return PARSE_RESULT.OK, buf, packet
def parse_msg(buf, communicator=None): ''' Parses message from buffer. returns: - PARSE_RESULT - remaining buffer - Packet -object (if message was valid, else None) ''' # If the buffer doesn't contain 0x55 (start char) # the message isn't needed -> ignore if 0x55 not in buf: return PARSE_RESULT.INCOMPLETE, [], None # Valid buffer starts from 0x55 # Convert to list, as index -method isn't defined for bytearray buf = [ord(x) if not isinstance(x, int) else x for x in buf[list(buf).index(0x55):]] try: data_len = (buf[1] << 8) | buf[2] opt_len = buf[3] except IndexError: # If the fields don't exist, message is incomplete return PARSE_RESULT.INCOMPLETE, buf, None # Header: 6 bytes, data, optional data and data checksum msg_len = 6 + data_len + opt_len + 1 if len(buf) < msg_len: # If buffer isn't long enough, the message is incomplete return PARSE_RESULT.INCOMPLETE, buf, None msg = buf[0:msg_len] buf = buf[msg_len:] packet_type = msg[4] data = msg[6:6 + data_len] opt_data = msg[6 + data_len:6 + data_len + opt_len] # Check CRCs for header and data if msg[5] != crc8.calc(msg[1:5]): # Fail if doesn't match message Packet.logger.error('Header CRC error!') # Return CRC_MISMATCH return PARSE_RESULT.CRC_MISMATCH, buf, None if msg[6 + data_len + opt_len] != crc8.calc(msg[6:6 + data_len + opt_len]): # Fail if doesn't match message Packet.logger.error('Data CRC error!') # Return CRC_MISMATCH return PARSE_RESULT.CRC_MISMATCH, buf, None # If we got this far, everything went ok (?) if packet_type == PACKET.RADIO: # Need to handle UTE Teach-in here, as it's a separate packet type... if data[0] == RORG.UTE: packet = UTETeachIn(packet_type, data, opt_data, communicator=communicator) # Send a response automatically, works only if # - communicator is set # - communicator.teach_in == True packet.send_response() else: packet = RadioPacket(packet_type, data, opt_data) elif packet_type == PACKET.RESPONSE: packet = ResponsePacket(packet_type, data, opt_data) elif packet_type == PACKET.EVENT: packet = EventPacket(packet_type, data, opt_data) else: packet = Packet(packet_type, data, opt_data) return PARSE_RESULT.OK, buf, packet