Example #1
0
    def create_packet(raw, operating_mode):
        """
        Override method.
        
        Returns:
            RXIPv4Packet.

        Raises:
            InvalidPacketException: if the bytearray length is less than 15. (start delim + length (2 bytes) + frame
                type + source address (4 bytes) + dest port (2 bytes) + source port (2 bytes) + network protocol +
                status + checksum = 15 bytes)
            InvalidPacketException: if the length field of ``raw`` is different than its real length. (length field:
                bytes 2 and 3)
            InvalidPacketException: if the first byte of ``raw`` is not the header byte. See :class:`.SPECIAL_BYTE`.
            InvalidPacketException: if the calculated checksum is different than the checksum field value (last byte).
            InvalidPacketException: if the frame type is not :attr:`ApiFrameType.RX_IPV4`.
            InvalidOperatingModeException: if ``operating_mode`` is not supported.

        .. seealso::
           | :meth:`.XBeePacket.create_packet`
           | :meth:`.XBeeAPIPacket._check_api_packet`
        """
        if operating_mode != OperatingMode.ESCAPED_API_MODE and operating_mode != OperatingMode.API_MODE:
            raise InvalidOperatingModeException(operating_mode.name + " is not supported.")

        XBeeAPIPacket._check_api_packet(raw, min_length=RXIPv4Packet.__MIN_PACKET_LENGTH)

        if raw[3] != ApiFrameType.RX_IPV4.code:
            raise InvalidPacketException("This packet is not an RXIPv4Packet.")

        return RXIPv4Packet(IPv4Address(bytes(raw[4:8])), utils.bytes_to_int(raw[8:10]),
                            utils.bytes_to_int(raw[10:12]), IPProtocol.get(raw[12]),
                            raw[14:-1])
Example #2
0
    def create_packet(raw, operating_mode):
        """
        Override method.

        Returns:
            TXIPv4Packet.

        Raises:
            InvalidPacketException: if the bytearray length is less than 16.
                (start delim + length (2 bytes) + frame type + frame id
                + dest address (4 bytes) + dest port (2 bytes)
                + source port (2 bytes) + network protocol + transmit options
                + checksum = 16 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:`.SPECIAL_BYTE`.
            InvalidPacketException: if the calculated checksum is different
                from the checksum field value (last byte).
            InvalidPacketException: if the frame type is not
                :attr:`ApiFrameType.TX_IPV4`.
            InvalidOperatingModeException: if `operating_mode` is not supported.

        .. seealso::
           | :meth:`.XBeePacket.create_packet`
           | :meth:`.XBeeAPIPacket._check_api_packet`
        """
        if operating_mode not in (OperatingMode.ESCAPED_API_MODE,
                                  OperatingMode.API_MODE):
            raise InvalidOperatingModeException(op_mode=operating_mode)

        XBeeAPIPacket._check_api_packet(
            raw, min_length=TXIPv4Packet.__MIN_PACKET_LENGTH)

        if raw[3] != ApiFrameType.TX_IPV4.code:
            raise InvalidPacketException(
                message="This packet is not an TXIPv4Packet.")

        return TXIPv4Packet(
            raw[4],
            IPv4Address(bytes(raw[5:9])),
            utils.bytes_to_int(raw[9:11]),
            utils.bytes_to_int(raw[11:13]),
            IPProtocol.get(raw[13]),
            raw[14],
            data=raw[15:-1]
            if len(raw) > TXIPv4Packet.__MIN_PACKET_LENGTH else None,
            op_mode=operating_mode)
Example #3
0
    def _parse_data(self, data):
        """
        Override.

        .. seealso::
           | :meth:`.__ZDOCommand._parse_data`
        """
        # Ensure the 16-bit address received matches the address of the device
        x16 = XBee16BitAddress.from_bytes(data[1], data[0])
        if x16 != self._xbee.get_16bit_addr():
            return False

        # Role field: 3 bits (0, 1, 2) of the next byte
        role = Role.get(utils.get_int_from_byte(data[2], 0, 3))
        # Complex descriptor available: next bit (3) of the same byte
        complex_desc_available = utils.is_bit_enabled(data[2], 3)
        # User descriptor available: next bit (4) of the same byte
        user_desc_available = utils.is_bit_enabled(data[2], 4)

        # Frequency band: 5 bits of the next byte
        freq_band = NodeDescriptorReader.__to_bits(data[3])[-5:]

        # MAC capabilities: next byte
        mac_capabilities = NodeDescriptorReader.__to_bits(data[4])

        # Manufacturer code: next 2 bytes
        manufacturer_code = utils.bytes_to_int([data[6], data[5]])

        # Maximum buffer size: next byte
        max_buffer_size = int(data[7])

        # Maximum incoming transfer size: next 2 bytes
        max_in_transfer_size = utils.bytes_to_int([data[9], data[8]])

        # Maximum outgoing transfer size: next 2 bytes
        max_out_transfer_size = utils.bytes_to_int([data[13], data[12]])

        # Maximum outgoing transfer size: next byte
        desc_capabilities = NodeDescriptorReader.__to_bits(data[14])

        self.__node_descriptor = NodeDescriptor(role, complex_desc_available, user_desc_available,
                                                freq_band, mac_capabilities, manufacturer_code,
                                                max_buffer_size, max_in_transfer_size,
                                                max_out_transfer_size, desc_capabilities)

        return True
Example #4
0
    def heartbeat(self, xbee: XBeeDevice, coordinator: RemoteXBeeDevice):
        """
        HEARTBEAT reply/"acknowledgement"
        Need to manually construct a RADIO_STATUS MAVLink message and place it at the front of
        priority_queue, as RADIO_STATUS messages are automatically constructed and sent back to the
        GCS on SiK radio firmware in response to a HEARTBEAT.  This is crucial for establishing a
        recognisable link on GCS software, such as QGroundControl.

        :param xbee:
        :param coordinator:
        """
        logging.debug('Generating fake heartbeat')
        rssi = bytes_to_int(xbee.get_parameter('DB'))
        remrssi = bytes_to_int(coordinator.get_parameter('DB'))
        errors = bytes_to_int(xbee.get_parameter('ER'))
        radio_status_msg = self.px4.mav.radio_status_encode(
            rssi=rssi, remrssi=remrssi, rxerrors=errors, txbuf=100, noise=0, remnoise=0, fixed=0)
        radio_status_msg.pack(self.px4.mav)
        self.queue_out.write(radio_status_msg)
Example #5
0
    def is_op_mode_valid(self, value):
        """
        Returns `True` if the provided value is a valid operating mode for
        the library.

        Args:
            value (Bytearray): The value to check.

        Returns:
            Boolean: `True` for a valid value, `False` otherwise.
        """
        op_mode_value = utils.bytes_to_int(value)
        op_mode = OperatingMode.get(op_mode_value)
        if op_mode not in (OperatingMode.API_MODE,
                           OperatingMode.ESCAPED_API_MODE):
            self._log.error(
                "Operating mode '%d' (%s) not set not to loose XBee connection",
                op_mode_value, op_mode.description if op_mode else "Unknown")
            return False

        return True
Example #6
0
    def _refresh_serial_params(self, node, parameter, value, apply=True):
        """
        Refreshes the proper cached parameter depending on `parameter` value.

        If `parameter` is not a cached parameter, this method does nothing.

        Args:
            node (:class:`.AbstractXBeeDevice`): The XBee to refresh.
            parameter (String): the parameter to refresh its value.
            value (Bytearray): the new value of the parameter.
            apply (Boolean, optional, default=`True`): `True` to apply
                immediately, `False` otherwise.

        Returns:
            Boolean: `True` if a network event must be sent, `False` otherwise.
        """
        node_fut_apply = self._future_apply.get(str(node.get_64bit_addr()), {})

        if parameter == ATStringCommand.AP.command:
            new_op_mode = OperatingMode.get(utils.bytes_to_int(value))
            changed = bool(new_op_mode != node.operating_mode
                           and new_op_mode in (OperatingMode.API_MODE,
                                               OperatingMode.ESCAPED_API_MODE))

            if changed and apply:
                node._operating_mode = new_op_mode
                node_fut_apply.pop(parameter, None)
            elif changed:
                node_fut_apply.update({parameter: value})

            return changed and apply

        if not node.serial_port or parameter not in (
                ATStringCommand.BD.command, ATStringCommand.NB.command,
                ATStringCommand.SB.command):
            return False

        if parameter == ATStringCommand.BD.command:
            from digi.xbee.profile import FirmwareBaudrate
            new_bd = utils.bytes_to_int(value)
            baudrate = FirmwareBaudrate.get(new_bd)
            new_bd = baudrate.baudrate if baudrate else new_bd
            changed = new_bd != node.serial_port.baudrate
            parameter = "baudrate" if changed and apply else parameter
            value = new_bd if changed and apply else value
        elif parameter == ATStringCommand.NB.command:
            from digi.xbee.profile import FirmwareParity
            new_parity = FirmwareParity.get(utils.bytes_to_int(value))
            new_parity = new_parity.parity if new_parity else None
            changed = new_parity != node.serial_port.parity
            parameter = "parity" if changed and apply else parameter
            value = new_parity if changed and apply else value
        else:
            from digi.xbee.profile import FirmwareStopbits
            new_sbits = FirmwareStopbits.get(utils.bytes_to_int(value))
            new_sbits = new_sbits.stop_bits if new_sbits else None
            changed = new_sbits != node.serial_port.stopbits
            parameter = "stopbits" if changed and apply else parameter
            value = new_sbits if changed and apply else value

        if changed and apply:
            node.serial_port.apply_settings({parameter: value})
            node_fut_apply.pop(parameter, None)
        elif changed:
            node_fut_apply.update({parameter: value})

        return False
Example #7
0
    def _refresh_if_cached(self, node, parameter, value, apply=True):
        """
        Refreshes the proper cached parameter depending on `parameter` value.

        If `parameter` is not a cached parameter, this method does nothing.

        Args:
            node (:class:`.AbstractXBeeDevice`): The XBee to refresh.
            parameter (String): the parameter to refresh its value.
            value (Bytearray): the new value of the parameter.
            apply (Boolean, optional, default=`True`): `True` to apply
                immediately, `False` otherwise.
        """
        updated = False
        param = parameter.upper()

        key = str(node.get_64bit_addr())
        if key not in self._future_apply:
            self._future_apply[key] = {}

        node_fut_apply = self._future_apply.get(key, {})

        # Node identifier
        if param == ATStringCommand.NI.command:
            node_id = str(value, encoding='utf8', errors='ignore')
            changed = node.get_node_id() != node_id
            updated = changed and apply
            if updated:
                node._node_id = node_id
                node_fut_apply.pop(param, None)
            elif changed:
                node_fut_apply.update({param: value})
        # 16-bit address / IP address
        elif param == ATStringCommand.MY.command:
            if XBeeProtocol.is_ip_protocol(node.get_protocol()):
                ip_addr = IPv4Address(utils.bytes_to_int(value))
                changed = node.get_ip_addr() != ip_addr
                updated = changed and apply
                if updated:
                    node._ip_addr = ip_addr
                    node_fut_apply.pop(param, None)
                elif changed:
                    node_fut_apply.update({param: value})
            elif XBee16BitAddress.is_valid(value):
                x16bit_addr = XBee16BitAddress(value)
                changed = node.get_16bit_addr() != x16bit_addr
                updated = changed and apply
                if updated:
                    node._16bit_addr = x16bit_addr
                    node_fut_apply.pop(param, None)
                elif changed:
                    node_fut_apply.update({param: value})
        elif not node.is_remote():
            updated = self._refresh_serial_params(node,
                                                  param,
                                                  value,
                                                  apply=apply)

        if updated:
            network = node.get_local_xbee_device().get_network() if node.is_remote() \
                else node.get_network()
            if (network
                    and (not node.is_remote()
                         or network.get_device_by_64(node.get_64bit_addr())
                         or network.get_device_by_16(node.get_16bit_addr()))):
                from digi.xbee.devices import NetworkEventType, NetworkEventReason
                network._network_modified(NetworkEventType.UPDATE,
                                          NetworkEventReason.READ_INFO,
                                          node=node)
Example #8
0
def run():
    global device
    #dev_logger = utils.enable_logger("digi.xbee.devices", logging.DEBUG)
    dev_logger = utils.disable_logger("digi.xbee.devices")
###################################################################################################
#    Look for XBee USB port, to avoid conflicts with other USB devices
###################################################################################################
    rospy.init_node('fleetCoordinator', anonymous=True)

    rospy.loginfo("Looking for XBee...")

    context = pyudev.Context()
    usbPort = 'No XBee found'

    for device in context.list_devices(subsystem='tty'):
        if 'ID_VENDOR' in device and device['ID_VENDOR'] == 'FTDI':
            usbPort = device['DEVNAME']

    device = XBeeDevice(usbPort, 57600)
    #device = XBeeDevice("/dev/ttyUSB0", 57600)
    device.open()
    print("Current timeout: %d seconds" % device.get_sync_ops_timeout())
    device.set_sync_ops_timeout(0.1)

###################################################################################################
#    Get local XBee ID (should be 0, convention for Coordinator)
###################################################################################################
    ID = utils.bytes_to_int(device.get_16bit_addr().address)

    if ID == 0:
        rospy.loginfo("\nHello,\nI am Coordinator " + str(ID)+'\n')
    else:
        raise Exception("This XBee device is not the coordinator of the network,\nlook for the XBee device stamped with 'C'.")


###################################################################################################
#    Initialisation
###################################################################################################
    #Variables storing the data received by the subscribers
    global remote_devices, pubGps, pubEuler, pubLB, pubLE, lastDataStr, lastData
    remote_devices = {}
    lastDataStr = {}
    lastData = {}
    pubGps = []
    pubEuler = []
    pubLB = []
    pubLE = []

    xnet = device.get_network()
    xnet.add_device_discovered_callback(network_callback)
    xnet.add_discovery_process_finished_callback(network_finished)
    device.add_data_received_callback(data_received)

    rate = rospy.Rate(10)

    GPSdata = GPSFix()
    eulerAnglesData = Vector3()
    lineStartData, lineEndData = Pose2D(), Pose2D()

    global chosen, mode, cmd
    mode = 0
    chosen = 0
    cmd = Twist()

    pygame.init()
    screen = pygame.display.set_mode( (640,480) )
    pygame.display.set_caption('Python numbers')


###################################################################################################
# Transmission Loop
###################################################################################################

    while not rospy.is_shutdown():
        if(xnet.is_discovery_running() is False):
            xnet.start_discovery_process()

        display(screen)

        send_command()

        rate.sleep()

    if(xnet.is_discovery_running()):
        xnet.stop_discovery_process()
    device.close()
Example #9
0
def main(argv):

    if len(argv) != 3:
        print("Usage: long_test.py <port> <baud_rate> <duration_in_seconds>")
        return

    print(" +-------------------------------+")
    print(" | Long duration and stress test |")
    print(" +-------------------------------+\n")

    port = argv[0]
    baud_rate = int(argv[1])
    duration = int(argv[2])

    device = ZigBeeDevice(port, baud_rate)

    try:
        device.open()

        # Discover the network.
        network = device.get_network()
        network.start_discovery_process()

        print("Discovering network...")

        # Wait until the discovery process has finished.
        while network.is_discovery_running():
            time.sleep(0.1)

        if not network.has_devices():
            print("No remote modules in the network")
            return

        # Get the first device of the network that is not an end device.
        remote = None
        for dev in network.get_devices():
            if utils.bytes_to_int(dev.get_parameter("SM")) == 0:
                remote = dev
                break

        if remote is None:
            print("No routers in the network")
            return

        print("Selected remote device: %s" % remote)

        # Add a data received callback.
        def data_callback(message):
            if message.remote_device.get_64bit_addr() == remote.get_64bit_addr(
            ):
                print("%s - [C] - %s" %
                      (datetime.datetime.now(), message.data.decode()))
                # Ensure that the sent and received messages are equal.
                assert (data == message.data.decode())

        device.add_data_received_callback(data_callback)

        print("Sending data...\n")

        dead_line = time.time() + duration

        while dead_line > time.time():
            retries = MAX_RETRIES
            data_received = False
            while not data_received:
                try:
                    data = ''.join(
                        random.choice(string.ascii_letters)
                        for i in range(random.randint(1, 84)))
                    print("%s - [S] - %s" % (datetime.datetime.now(), data))
                    # Send explicit data to the loopback cluster.
                    device.send_expl_data(remote, data, SOURCE_ENDPOINT,
                                          DEST_ENDPOINT, CLUSTER_ID,
                                          PROFILE_ID)
                    # Read new data from the remote device.
                    msg = device.read_data_from(remote, 10)
                    print("%s - [P] - %s" %
                          (datetime.datetime.now(), msg.data.decode()))
                    data_received = True
                    # Ensure that the sent and received messages are equal.
                    assert (data == msg.data.decode())
                except TimeoutException as ex:
                    retries -= 1
                    if retries == 0:
                        raise ex

                # Wait some time between 1 and 5 seconds.
                time.sleep(random.randint(1, 5))

        print("\nTest finished successfully")

    finally:
        if device is not None and device.is_open():
            device.close()
Example #10
0
    def create_packet(raw, operating_mode):
        """
        Override method.

        Returns:
            :class:`.RouteInformationPacket`.

        Raises:
            InvalidPacketException: If the bytearray length is less than 46.
                (start delim. + length (2 bytes) + frame type + src_event
                + length + timestamp (4 bytes) + ack timeout count
                + tx blocked count + reserved + dest addr (8 bytes)
                + src addr (8 bytes) + responder addr (8 bytes)
                + successor addr (8 bytes) + checksum = 46 bytes).
            InvalidPacketException: If the length field of `raw` is different
                from its real length. (length field: bytes 1 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).
            InvalidPacketException: If the frame type is not
                :attr:`.ApiFrameType.DIGIMESH_ROUTE_INFORMATION`.
            InvalidPacketException: If the internal length byte of the rest
                of the frame (without the checksum) is different from its real
                length.
            InvalidOperatingModeException: If `operating_mode` is not
                supported.

        .. seealso::
           | :meth:`.XBeePacket.create_packet`
           | :meth:`.XBeeAPIPacket._check_api_packet`
        """
        if operating_mode not in (OperatingMode.ESCAPED_API_MODE,
                                  OperatingMode.API_MODE):
            raise InvalidOperatingModeException(operating_mode.name +
                                                " is not supported.")

        XBeeAPIPacket._check_api_packet(
            raw, min_length=RouteInformationPacket.__MIN_PACKET_LENGTH)

        if raw[3] != ApiFrameType.DIGIMESH_ROUTE_INFORMATION.code:
            raise InvalidPacketException(
                "This packet is not a Route Information packet.")

        # 7: frame len starting from this byte (index 5) and without the checksum
        if raw[5] != len(raw) - 7:
            raise InvalidPacketException(
                "Length does not match with the data length")

        additional_data = []
        if len(raw) > RouteInformationPacket.__MIN_PACKET_LENGTH:
            additional_data = raw[45:]
        packet = RouteInformationPacket(raw[4],
                                        utils.bytes_to_int(raw[6:10]),
                                        raw[10],
                                        raw[11],
                                        XBee64BitAddress(raw[13:21]),
                                        XBee64BitAddress(raw[21:29]),
                                        XBee64BitAddress(raw[29:37]),
                                        XBee64BitAddress(raw[37:45]),
                                        additional_data,
                                        op_mode=operating_mode)
        packet._reserved = raw[12]

        return packet
def run():
    global device, modeV
    modeV = 0

    #dev_logger = utils.enable_logger("digi.xbee.devices", logging.DEBUG)
    dev_logger = utils.disable_logger("digi.xbee.devices")
    ###################################################################################################
    #    Look for XBee USB port, to avoid conflicts with other USB devices
    ###################################################################################################
    rospy.init_node('fleetEndPoint', anonymous=True)

    rospy.loginfo("Looking for XBee...")

    context = pyudev.Context()
    usbPort = 'No XBee found'

    for device in context.list_devices(subsystem='tty'):
        if 'ID_VENDOR' in device and device['ID_VENDOR'] == 'FTDI':
            usbPort = device['DEVNAME']

    device = XBeeDevice(usbPort, 57600)
    #device = XBeeDevice("/dev/ttyUSB1", 57600)
    device.open()
    print("Current timeout: %d seconds" % device.get_sync_ops_timeout())
    device.set_sync_ops_timeout(0.1)

    ###################################################################################################
    #    Get local XBee ID (should be 0, convention for Coordinator)
    ###################################################################################################
    ID = utils.bytes_to_int(device.get_64bit_addr().address)

    if ID == 0:
        raise Exception("\nThis Shouldn't be a Coordinator" + '\n')
    else:
        print("Hello This is " + str(ID))


###################################################################################################
#    Initialisation
###################################################################################################
#Variables storing the data received by the subscribers
    global windForceString, windDirectionString, gpsString, eulerAnglesString, posString, beginString, endString, lastData, lastDataStr, pub_send_u_rudder_sail, pub_send_control_mode
    windForceData, windDirectionData, GPSdata, eulerAnglesData, lineStartData, lineEndData = Float32(
    ), Float32(), String(), Vector3(), Pose2D(), Pose2D()

    remote_devices = {}
    lastDataStr = ''
    lastData = {}
    lastData["NMEA"] = ''
    lastData["windF"] = 0.0
    lastData["windT"] = 0.0
    lastData["eulerx"] = 0.0
    lastData["eulery"] = 0.0
    lastData["eulerz"] = 0.0

    #xnet = device.get_network()
    #xnet.add_device_discovered_callback(network_callback)
    #xnet.add_discovery_process_finished_callback(network_finished)
    device.add_data_received_callback(data_received)

    rate = rospy.Rate(10)

    rospy.Subscriber('/sailboat/GPS/NMEA', String, sub_GPS)
    rospy.Subscriber('/sailboat/wind', Pose2D, sub_WIND)
    rospy.Subscriber('/sailboat/IMU', Imu, sub_IMU)
    rospy.Subscriber('regulator_send_lineBegin', Pose2D, sub_lineBegin)
    rospy.Subscriber('regulator_send_lineEnd', Pose2D, sub_lineEnd)

    pub_send_u_rudder_sail = rospy.Publisher('xbee/sailboat_cmd',
                                             Twist,
                                             queue_size=2)
    pub_send_control_mode = rospy.Publisher('xbee/mode', Float32, queue_size=2)

    ###################################################################################################
    # Transmission Loop
    ###################################################################################################

    while not rospy.is_shutdown():
        #if(xnet.is_discovery_running() is False):
        #    xnet.start_discovery_process()
        try:
            device.send_data(
                RemoteXBeeDevice(device,
                                 XBee64BitAddress.from_hex_string("00")),
                data_to_bytearray(lastData))
        except TimeoutException:
            #print("timeout")
            pass
        except XBeeException:
            pass

        if (modeV == 1):
            pub_send_u_rudder_sail.publish(rudder_sail)

        mode = Float32(data=0.)
        mode.data = modeV
        pub_send_control_mode.publish(mode)

        rate.sleep()

    #if(xnet.is_discovery_running()):
    #    xnet.stop_discovery_process()
    device.close()