def wait_for_frame(self, operating_mode): """ Reads the next packet. Starts to read when finds the start delimiter. The last byte read is the checksum. If there is something in the COM buffer after the start delimiter, this method discards it. If the method can't read a complete and correct packet, it will return `None`. Args: operating_mode (:class:`.OperatingMode`): The operating mode in which the packet should be read. Returns: Bytearray: The read packet as bytearray if a packet is read, `None` otherwise. """ self._is_reading = True try: xbee_packet = bytearray(1) # Add packet delimiter. xbee_packet[0] = self.read_byte() while xbee_packet[0] != SpecialByte.HEADER_BYTE.value: # May be set to false by self.quit_reading() as a stop reading # request. if not self._is_reading: return None xbee_packet[0] = self.read_byte() # Add packet length. packet_length_byte = bytearray() for _ in range(2): packet_length_byte += self.__read_next_byte(operating_mode) xbee_packet += packet_length_byte # Length needs to be un-escaped in API escaped mode to obtain its # integer equivalent. if operating_mode == OperatingMode.ESCAPED_API_MODE: length = utils.length_to_int( XBeeAPIPacket.unescape_data(packet_length_byte)) else: length = utils.length_to_int(packet_length_byte) # Add packet payload. for _ in range(length): xbee_packet += self.__read_next_byte(operating_mode) # Add packet checksum. xbee_packet += self.__read_next_byte(operating_mode) # Return the packet unescaped. if operating_mode == OperatingMode.ESCAPED_API_MODE: return XBeeAPIPacket.unescape_data(xbee_packet) return xbee_packet except digi.xbee.exception.TimeoutException: return None
def __try_read_packet(self, operating_mode=OperatingMode.API_MODE): """ Reads the next packet. Starts to read when finds the start delimiter. The last byte read is the checksum. If there is something in the COM buffer after the start delimiter, this method discards it. If the method can't read a complete and correct packet, it will return ``None``. Args: operating_mode (:class:`.OperatingMode`): the operating mode in which the packet should be read. Returns: Bytearray: the read packet as bytearray if a packet is read, ``None`` otherwise. """ try: xbee_packet = bytearray(1) # Add packet delimiter. xbee_packet[0] = self.__serial_port.read_byte() while xbee_packet[0] != SpecialByte.HEADER_BYTE.value: xbee_packet[0] = self.__serial_port.read_byte() # Add packet length. packet_length_byte = bytearray() for _ in range(0, 2): packet_length_byte += self.__read_next_byte(operating_mode) xbee_packet += packet_length_byte # Length needs to be un-escaped in API escaped mode to obtain its integer equivalent. if operating_mode == OperatingMode.ESCAPED_API_MODE: length = utils.length_to_int( XBeeAPIPacket.unescape_data(packet_length_byte)) else: length = utils.length_to_int(packet_length_byte) # Add packet payload. for _ in range(0, length): xbee_packet += self.__read_next_byte(operating_mode) # Add packet checksum. for _ in range(0, 1): xbee_packet += self.__read_next_byte(operating_mode) # Return the packet unescaped. if operating_mode == OperatingMode.ESCAPED_API_MODE: return XBeeAPIPacket.unescape_data(xbee_packet) else: return xbee_packet except TimeoutException: return None
def __try_read_packet(self): """ Reads the next packet. Starts to read when finds the start delimiter. The last byte read is the checksum. If there is something in the COM buffer after the start delimiter, this method discards it. If the method can't read a complete and correct packet, it will return ``None``. Returns: Bytearray: the read packet as bytearray if a packet is read, ``None`` otherwise. """ try: xbee_packet = bytearray(1) xbee_packet[0] = self.__serial_port.read_byte() while xbee_packet[0] != SpecialByte.HEADER_BYTE.value: xbee_packet[0] = self.__serial_port.read_byte() packet_length = self.__serial_port.read_bytes(2) xbee_packet += packet_length length = utils.length_to_int(packet_length) xbee_packet += self.__serial_port.read_bytes(length) xbee_packet.append(self.__serial_port.read_byte()) return xbee_packet except TimeoutException: return None
def _check_api_packet(raw, min_length=5): """ Checks the not escaped bytearray 'raw' meets conditions. Args: raw (Bytearray): non-escaped bytearray to be checked. min_length (Integer): the minimum length of the packet in bytes. Raises: InvalidPacketException: if the bytearray length is less than 5. (start delim. + length (2 bytes) + frame type + checksum = 5 bytes). InvalidPacketException: if the length field of 'raw' is different from its real length. (length field: bytes 2 and 3) InvalidPacketException: if the first byte of 'raw' is not the header byte. See :class:`.SpecialByte`. InvalidPacketException: if the calculated checksum is different from the checksum field value (last byte). .. seealso:: | :mod:`.factory` """ if len(raw) < min_length: raise InvalidPacketException( message="Bytearray must have, at least, 5 of complete length " "(header, length, frameType, checksum)") if raw[0] & 0xFF != SpecialByte.HEADER_BYTE.code: raise InvalidPacketException( message="Bytearray must start with the header byte " "(SpecialByte.HEADER_BYTE.code)") # real frame specific data length real_length = len(raw[3:-1]) # length is specified in the length field. length_field = utils.length_to_int(raw[1:3]) if real_length != length_field: raise InvalidPacketException( message="The real length of this frame does not match the " "specified in length field (bytes 2 and 3) (real %d, " "length field %d)" % (real_length, length_field)) checksum = 0xFF - (sum(raw[3:-1]) & 0xFF) if checksum != raw[-1]: raise InvalidPacketException( message="Wrong checksum (expected %02X, received %02X)" % (checksum, raw[-1]))
def __try_read_packet(self, operating_mode=OperatingMode.API_MODE): """ Reads the next packet. Starts to read when finds the start delimiter. The last byte read is the checksum. If there is something in the COM buffer after the start delimiter, this method discards it. If the method can't read a complete and correct packet, it will return ``None``. Returns: Bytearray: the read packet as bytearray if a packet is read, ``None`` otherwise. """ try: xbee_packet = bytearray(1) # Add packet delimiter. xbee_packet[0] = self.__serial_port.read_byte() while xbee_packet[0] != SpecialByte.HEADER_BYTE.value: xbee_packet[0] = self.__serial_port.read_byte() packet_length = self.__serial_port.read_bytes(2) # Add packet length. xbee_packet += packet_length length = utils.length_to_int(packet_length) # Add packet payload. for _ in range(0, length): read_byte = self.__serial_port.read_byte() xbee_packet.append(read_byte) # Read escaped bytes in API escaped mode. if operating_mode == OperatingMode.ESCAPED_API_MODE and read_byte == XBeePacket.ESCAPE_BYTE: xbee_packet.append(self.__serial_port.read_byte()) # Add packet checksum. xbee_packet.append(self.__serial_port.read_byte()) return xbee_packet except TimeoutException: return None