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()
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()
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)
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)
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
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