예제 #1
0
    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
예제 #2
0
    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
예제 #3
0
    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
예제 #4
0
    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]))
예제 #5
0
    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