Пример #1
0
def fwreboot(dev, recipient):
    event_id = (EVENT_GROUP_DFU << GROUP_FIELD_POS) | (
        DFU_REBOOT << TYPE_FIELD_POS)
    success, _ = exchange_feature_report(dev, recipient, event_id, None, True)

    if success:
        logging.debug('Firmware rebooted')
    else:
        logging.debug('FW reboot request failed')

    return success
Пример #2
0
def fwinfo(dev, recipient):
    event_id = (EVENT_GROUP_DFU << GROUP_FIELD_POS) | (
        DFU_IMGINFO << TYPE_FIELD_POS)

    success, fetched_data = exchange_feature_report(dev, recipient, event_id,
                                                    None, True)

    if success and fetched_data:
        fw_info = FwInfo(fetched_data)
        return fw_info
    else:
        return None
Пример #3
0
def change_config(dev, recipient, config_name, config_value, device_options, module_id):
    config_opts = device_options[config_name]
    opt_id = config_opts.event_id
    event_id = (EVENT_GROUP_SETUP << GROUP_FIELD_POS) | (module_id << MOD_FIELD_POS) | (opt_id << OPT_FIELD_POS)
    value_range = config_opts.range
    logging.debug('Send request to update {}: {}'.format(config_name, config_value))

    dev_name = get_device_type(recipient)
    format = get_option_format(dev_name, module_id)

    if format is not None:
        # Read out first, then modify and write back (even if there is only one member in struct, to simplify code)
        success, fetched_data = exchange_feature_report(dev, recipient, event_id, None, True)
        if not success:
            return success

        try:
            config = ConfigParser(fetched_data, *format[opt_id])
            config.config_update(config_name, config_value)
            event_data = config.serialize()
        except (ValueError, KeyError):
            print('Failed. Invalid value for {}'.format(config_name))
            return False
    else:
        if config_value is not None:
            if not check_range(config_value, value_range):
                print('Failed. Config value for {} must be in range {}'.format(config_name, value_range))
                return False
            event_data = struct.pack('<I', config_value)
        else:
            event_data = None

    success = exchange_feature_report(dev, recipient, event_id, event_data, False)

    if success:
        logging.debug('Config changed')
    else:
        logging.debug('Config change failed')

    return success
Пример #4
0
def led_send_single_step(dev, recipient, step, led_id):
    event_id = (EVENT_GROUP_LED_STREAM << GROUP_FIELD_POS) \
               | (LED_STREAM_DATA << TYPE_FIELD_POS)

    # Chosen data layout for struct is defined using format string.
    event_data = struct.pack('<BBBHHB', step.r, step.g, step.b,
                             step.substep_count, step.substep_time, led_id)

    success = exchange_feature_report(dev,
                                      recipient,
                                      event_id,
                                      event_data,
                                      False,
                                      poll_interval=0.001)

    return success
Пример #5
0
def dfu_sync(dev, recipient):
    event_id = (EVENT_GROUP_DFU << GROUP_FIELD_POS) | (
        DFU_SYNC << TYPE_FIELD_POS)

    success, fetched_data = exchange_feature_report(dev, recipient, event_id,
                                                    None, True)

    if not success:
        return None

    fmt = '<BIII'
    assert struct.calcsize(fmt) <= EVENT_DATA_LEN_MAX

    if (fetched_data is None) or (len(fetched_data) < struct.calcsize(fmt)):
        return None

    return struct.unpack(fmt, fetched_data)
Пример #6
0
def dfu_start(dev, recipient, img_length, img_csum, offset):
    # Start DFU operation at selected offset.
    # It can happen that device will reject this request - this will be
    # verified by dfu sync at data exchange.
    event_id = (EVENT_GROUP_DFU << GROUP_FIELD_POS) | (
        DFU_START << TYPE_FIELD_POS)

    event_data = struct.pack('<III', img_length, img_csum, offset)

    success = exchange_feature_report(dev, recipient, event_id, event_data,
                                      False)

    if success:
        logging.debug('DFU started')
    else:
        logging.debug('DFU start failed')

    return success
Пример #7
0
def fetch_config(dev, recipient, config_name, device_options, module_id):
    config_opts = device_options[config_name]
    opt_id = config_opts.event_id
    event_id = (EVENT_GROUP_SETUP << GROUP_FIELD_POS) | (module_id << MOD_FIELD_POS) | (opt_id << OPT_FIELD_POS)
    logging.debug('Fetch the current value of {} from the firmware'.format(config_name))

    success, fetched_data = exchange_feature_report(dev, recipient, event_id, None, True)

    if not success or not fetched_data:
        return success, None

    dev_name = get_device_type(recipient)
    format = get_option_format(dev_name, module_id)

    if format is None:
        return success, config_opts.type.from_bytes(fetched_data, byteorder='little')
    else:
        return success, ConfigParser(fetched_data, *format[opt_id]).config_get(config_name)
Пример #8
0
def send_chunk(dev, img_csum, img_file, img_length, offset, recipient, success,
               progress_callback):
    event_id = (EVENT_GROUP_DFU << GROUP_FIELD_POS) | (
        DFU_DATA << TYPE_FIELD_POS)

    while offset < img_length:
        if offset % FLASH_PAGE_SIZE == 0:
            # Sync DFU state at regular intervals to ensure everything
            # is all right.
            success = False
            dfu_info = dfu_sync(dev, recipient)

            if dfu_info is None:
                print('Lost communication with the device')
                break
            if dfu_info[0] == 0:
                print('DFU interrupted by device')
                break
            if (dfu_info[1] != img_length) or (dfu_info[2] != img_csum) or (
                    dfu_info[3] != offset):
                print('Invalid sync information')
                break

        chunk_data = img_file.read(EVENT_DATA_LEN_MAX)
        chunk_len = len(chunk_data)

        if chunk_len == 0:
            break

        logging.debug('Send DFU request: offset {}, size {}'.format(
            offset, chunk_len))

        progress_callback(int(offset / img_length * 1000))

        success = exchange_feature_report(dev, recipient, event_id, chunk_data,
                                          False)

        if not success:
            print('Lost communication with the device')
            break

        offset += chunk_len

    return offset, success
Пример #9
0
def fetch_free_steps_buffer_info(dev, recipient, led_id):
    event_id = (EVENT_GROUP_LED_STREAM << GROUP_FIELD_POS) \
               | (led_id << MOD_FIELD_POS)

    success, fetched_data = exchange_feature_report(dev,
                                                    recipient,
                                                    event_id,
                                                    None,
                                                    True,
                                                    poll_interval=0.001)

    if (not success) or (fetched_data is None):
        return False, (None, None)

    # Chosen data layout for struct is defined using format string.
    fmt = '<B?'
    assert struct.calcsize(fmt) <= EVENT_DATA_LEN_MAX

    if len(fetched_data) != struct.calcsize(fmt):
        return False, (None, None)

    return success, struct.unpack(fmt, fetched_data)