Exemplo n.º 1
0
    def _try_baudrate(self, recovery_baudrate):
        # Here we are in recovery mode
        _log.debug("Reconfiguring the serial port to recovery baudrate of %d",
                   recovery_baudrate)
        self._xbee_serial_port.apply_settings({_BAUDRATE_KEY: recovery_baudrate})

        # Set the desired configuration permanently.
        _log.debug("Forcing the current setup to %s", self._desired_cfg)

        bauds = FirmwareBaudrate.get_by_baudrate(self._desired_cfg[_BAUDRATE_KEY])
        if bauds:
            bauds = format(bauds.index, 'x')
        else:
            bauds = format(self._desired_cfg[_BAUDRATE_KEY], 'x')

        parity = FirmwareParity.get_by_parity(self._desired_cfg[_PARITY_KEY])
        if not parity:
            parity = FirmwareParity.NONE
        parity = format(parity.index, 'x')

        stop_bits = FirmwareStopbits.get_by_stopbits(self._desired_cfg[_STOPBITS_KEY])
        if not stop_bits:
            stop_bits = FirmwareStopbits.SB_1
        stop_bits = format(stop_bits.index, 'x')

        cts = -1
        rts = -1
        if self._desired_cfg[_FLOW_CTRL_KEY] == FlowControl.HARDWARE_RTS_CTS:
            cts = 1
            rts = 1
        elif self._desired_cfg[_FLOW_CTRL_KEY] == FlowControl.NONE:
            # In fact, this should be any value but 1 in any of them
            # For that, we should read the value and change to 0 only if it is 1
            cts = 0
            rts = 0

        _log.debug("In command mode: %s", enter_at_command_mode(self._xbee_serial_port))

        for command in (
                "%s%s\r" % (_AT_COMMANDS[_BAUDRATE_KEY], bauds),
                "%s%s\r" % (_AT_COMMANDS[_PARITY_KEY], parity),
                "%s%s\r" % (_AT_COMMANDS[_STOPBITS_KEY], stop_bits),
                "%s%s\r" % (_AT_COMMANDS[_CTS_KEY], cts),
                "%s%s\r" % (_AT_COMMANDS[_RTS_KEY], rts),
                "%s%s\r" % (_AT_COMMANDS[_API_ENABLE_KEY],
                            self._desired_cfg[_API_ENABLE_KEY]),
                "%s%s\r" % (_AT_COMMANDS[_CMD_SEQ_CHAR_KEY],
                            self._desired_cfg[_CMD_SEQ_CHAR_KEY]),
                "%s%s\r" % (_AT_COMMANDS[_GUARD_TIME_KEY],
                            self._desired_cfg[_GUARD_TIME_KEY]),
                _AT_COMMANDS[_APPLY_CHANGES_KEY],
                _AT_COMMANDS[_WRITE_REGISTER_KEY],
                _AT_COMMANDS[_EXIT_MODE_KEY]):
            self._xbee_serial_port.write(str.encode(command, encoding="utf8"))
            if command == _AT_COMMANDS[_EXIT_MODE_KEY]:
                time.sleep(_DEFAULT_GUARD_TIME)
            timeout = time.time() + 2
            while self._xbee_serial_port.inWaiting() == 0 and time.time() < timeout:
                time.sleep(0.1)
            read = self._xbee_serial_port.read(self._xbee_serial_port.inWaiting())
            _log.debug("command %s = %s", command[:-1], read)
            if AT_OK_RESPONSE not in read:
                return "Command {!r} failed, non OK returned value of {!r}".format(command, read)
                # self._do_exception(
                #     "Command {!r} failed, non OK returned value of {!r}".format(command, read))
            if command == _AT_COMMANDS[_APPLY_CHANGES_KEY]:
                self._xbee_serial_port.apply_settings(self._desired_cfg)

        self._restore_target_connection()
        return None
Exemplo n.º 2
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
Exemplo n.º 3
0
    def autorecover_device(self):
        """
        Recovers the XBee from an unknown state.

        Raises:
            RecoveryException: If there is any error performing the recovery action.
        """
        if self._xbee_device and self._xbee_device.is_open:
            self._xbee_device.close()

        self._xbee_serial_port.open()
        self._xbee_serial_port.purge_port()

        _log.debug("Autorecovering the device by entering in recovery mode")
        recovery_baudrate = self._get_recovery_baudrate(
            _RECOVERY_DETECTION_TRIES)

        # If we couldn't enter in recovery mode, assume we are in bootloader
        # and retry
        if recovery_baudrate is None:
            _log.error("Could not determine the baudrate in recovery mode, "
                       "assuming device is in bootloader mode and retrying")
            # Only for XBee 3 modules
            self._xbee_serial_port.apply_settings(
                {_BAUDRATE_KEY: _BOOTLOADER_BAUDRATE})
            self._xbee_serial_port.write(str.encode(_BOOTLOADER_CONTINUE_KEY))

            _log.debug("Retrying to determine the baudrate in recovery mode")
            recovery_baudrate = self._get_recovery_baudrate(
                _RECOVERY_DETECTION_TRIES)

        if recovery_baudrate is None:
            self._do_exception(
                "Could not determine the baudrate in recovery mode")

        # Here we are in recovery mode
        _log.debug("Reconfiguring the serial port to recovery baudrate of %d",
                   recovery_baudrate)
        self._xbee_serial_port.apply_settings(
            {_BAUDRATE_KEY: recovery_baudrate})

        # Set the desired configuration permanently.
        _log.debug("Forcing the current setup to %s", self._desired_cfg)

        bauds = FirmwareBaudrate.get_by_baudrate(
            self._desired_cfg[_BAUDRATE_KEY])
        if bauds:
            bauds = format(bauds.index, 'x')
        else:
            bauds = format(self._desired_cfg[_BAUDRATE_KEY], 'x')

        parity = FirmwareParity.get_by_parity(self._desired_cfg[_PARITY_KEY])
        if not parity:
            parity = FirmwareParity.NONE
        parity = format(parity.index, 'x')

        stop_bits = FirmwareStopbits.get_by_stopbits(
            self._desired_cfg[_STOPBITS_KEY])
        if not stop_bits:
            stop_bits = FirmwareStopbits.NONE
        stop_bits = format(stop_bits.index, 'x')

        cts = -1
        rts = -1
        if self._desired_cfg[_FLOW_CTRL_KEY] == FlowControl.HARDWARE_RTS_CTS:
            cts = 1
            rts = 1
        elif self._desired_cfg[_FLOW_CTRL_KEY] == FlowControl.NONE:
            # In fact, this should be any value but 1 in any of them
            # For that, we should read the value and change to 0 only if it is 1
            cts = 0
            rts = 0

        for command in ("%s%s\r" % (_AT_COMMANDS[_BAUDRATE_KEY], bauds),
                        "%s%s\r" % (_AT_COMMANDS[_PARITY_KEY], parity),
                        "%s%s\r" % (_AT_COMMANDS[_STOPBITS_KEY], stop_bits),
                        "%s%s\r" % (_AT_COMMANDS[_CTS_KEY], cts),
                        "%s%s\r" % (_AT_COMMANDS[_RTS_KEY], rts),
                        "%s%s\r" % (_AT_COMMANDS[_API_ENABLE_KEY],
                                    self._desired_cfg[_API_ENABLE_KEY]),
                        "%s%s\r" % (_AT_COMMANDS[_CMD_SEQ_CHAR_KEY],
                                    self._desired_cfg[_CMD_SEQ_CHAR_KEY]),
                        "%s%s\r" % (_AT_COMMANDS[_GUARD_TIME_KEY],
                                    self._desired_cfg[_GUARD_TIME_KEY]),
                        _AT_COMMANDS[_APPLY_CHANGES_KEY],
                        _AT_COMMANDS[_WRITE_REGISTER_KEY],
                        _AT_COMMANDS[_EXIT_MODE_KEY]):
            self._xbee_serial_port.write(str.encode(command))
            if command == _AT_COMMANDS[_EXIT_MODE_KEY]:
                time.sleep(_DEFAULT_GUARD_TIME)
            timeout = time.time() + 2
            while self._xbee_serial_port.inWaiting(
            ) == 0 and time.time() < timeout:
                time.sleep(0.1)
            read = self._xbee_serial_port.read(
                self._xbee_serial_port.inWaiting())
            _log.debug("command %s = %s", command[:-1], read)
            if AT_OK_RESPONSE not in read:
                self._do_exception(
                    "Command {!r} failed, non OK returned value of {!r}".
                    format(command, read))
            if command == _AT_COMMANDS[_APPLY_CHANGES_KEY]:
                self._xbee_serial_port.apply_settings(self._desired_cfg)

        self._restore_target_connection()