예제 #1
0
def read_extended_data(device, size):
    """
    Read binary data blocks in response to some other command, handling segmentation
    and checksum validation.

    The command sequence is:

        While data left to read
            OUT:    0x10    ASMESSAGE_REQUEST_BLOCK_READ
            IN:     0x4d    ASMESSAGE_RESPONSE_BLOCK_READ
            OUT:    data
    """
    logger.debug('Reading extended data')
    remaining = size
    message = Message(MessageConst.REQUEST_BLOCK_READ, [])
    result = util.create_buffer(0)

    while remaining > 0:
        response = send_message(device, message)
        if response.command() == MessageConst.RESPONSE_BLOCK_READ_EMPTY:
            break
        if response.command() == MessageConst.RESPONSE_BLOCK_READ:
            blocksize = response.argument(1, 4)
            checksum = response.argument(5, 2)
            buf = device.read(blocksize)
            assert calculate_data_checksum(buf) == checksum
            result.extend(buf)
            remaining = remaining - len(buf)
        else:
            raise NeotoolsError('Unexpected response %s' % response)

    return result.tobytes()
예제 #2
0
def set_settings(device, applet_id, settings):
    settings_buf = settings.to_raw()
    checksum = calculate_data_checksum(settings_buf)
    device.dialogue_start()
    logger.info('Requesting to write settings for applet_id=%s', applet_id)
    message = Message(MessageConst.REQUEST_SET_SETTINGS,
                      [(len(settings_buf), 1, 4), (checksum, 5, 2)])
    send_message(device, message, MessageConst.RESPONSE_BLOCK_WRITE)
    logger.info('Writing settings')
    device.write(settings_buf)
    receive_message(device, MessageConst.RESPONSE_BLOCK_WRITE_DONE)

    message = Message(MessageConst.REQUEST_SET_APPLET, [(0, 1, 4),
                                                        (applet_id, 5, 2)])
    send_message(device, message, MessageConst.RESPONSE_SET_APPLET)
    device.dialogue_end()
예제 #3
0
def get_settings(device, applet_id, flags):
    device.dialogue_start()
    logger.info('Requesting settings for applet_id=%s, flags=%s', applet_id,
                flags)
    message = Message(MessageConst.REQUEST_GET_SETTINGS, [(flags, 1, 4),
                                                          (applet_id, 5, 2)])
    response = send_message(device, message,
                            MessageConst.RESPONSE_GET_SETTINGS)
    response_size = response.argument(1, 4)
    expected_checksum = response.argument(5, 2)
    logger.info('Retrieving settings data')
    result = device.read(response_size)
    assert calculate_data_checksum(result) == expected_checksum
    device.dialogue_end()
    settings_list = AppletSettingsItem.list_from_raw(result)
    return AppletSettings(settings_list)
예제 #4
0
def get_file_attributes(device, applet_id, index):
    logger.info('Getting file attributes applet_id=%s index=%s', applet_id,
                index)
    device.dialogue_start()
    message = Message(MessageConst.REQUEST_GET_FILE_ATTRIBUTES,
                      [(index, 4, 1), (applet_id, 5, 2)])
    response = send_message(device, message)
    if response.command() == MessageConst.ERROR_PARAMETER:
        # Entry not found. This probably just means that the iteration has exceeded the number of files available.
        return None
    assert_success(response, MessageConst.RESPONSE_GET_FILE_ATTRIBUTES)
    length = response.argument(1, 4)
    checksum = response.argument(5, 2)
    assert length == FILE_ATTRIBUTES_FORMAT['size']
    buf = device.read(FILE_ATTRIBUTES_FORMAT['size'])
    assert checksum == calculate_data_checksum(buf)
    device.dialogue_end()
    return FileAttributes.from_raw(index, buf)
예제 #5
0
def write_extended_data(device, buf):
    remaining = len(buf)
    offset = 0
    while remaining > 0:
        blocksize = min(1024, remaining)
        block = buf[offset:offset + blocksize]
        checksum = calculate_data_checksum(block)

        message = Message(MessageConst.REQUEST_BLOCK_WRITE, [(blocksize, 1, 4),
                                                             (checksum, 5, 2)])
        response = send_message(device, message,
                                MessageConst.RESPONSE_BLOCK_WRITE)

        device.write(block)
        response = receive_message(device,
                                   MessageConst.RESPONSE_BLOCK_WRITE_DONE)

        offset = offset + blocksize
        remaining = remaining - blocksize
예제 #6
0
def raw_read_applet_headers(device, index):
    header_size = APPLET_HEADER_FORMAT['size']
    logger.info('Requesting to read list of applets with index=%s', index)
    message = Message(MessageConst.REQUEST_LIST_APPLETS,
                      [(index, 1, 4), (LIST_APPLETS_REQUEST_COUNT, 5, 2)])
    response = send_message(device, message)
    size = response.argument(1, 4)
    expected_checksum = response.argument(5, 2)
    if size > LIST_APPLETS_REQUEST_COUNT * header_size:
        raise NeotoolsError(
            'rawReadAppletHeaders: reply will return too much data!')

    if size == 0:
        return []

    buf = device.read(size)
    if len(buf) % header_size != 0:
        logger.warning(
            'rawReadAppletHeaders: read returned a partial header (expected header size %s, bytes read %s',
            header_size, len(buf))
    if calculate_data_checksum(buf) != expected_checksum:
        raise NeotoolsError('rawReadAppletHeaders: data checksum error')
    return buf