forked from public/pysim
pySim-shell: improve fsdump
In the previous patch we have improved the export command. Since the implementation of the fsdump command is very similar to the implementation of the export command we can now apply the same improvements to the fsdump command as well. Change-Id: I4d2ef7b383025a5bbf122f18ecd51b7d73aaba14 Related: OS#6092
This commit is contained in:
164
pySim-shell.py
164
pySim-shell.py
@@ -633,118 +633,80 @@ class PySimCommands(CommandSet):
|
|||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
"unable to export %i dedicated files(s)%s" % (context['ERR'], exception_str_add))
|
"unable to export %i dedicated files(s)%s" % (context['ERR'], exception_str_add))
|
||||||
|
|
||||||
def fsdump_df(self, filename, context, as_json):
|
def __dump_file(self, filename, context, as_json):
|
||||||
"""Dump information about currently selected [A]DF"""
|
""" Select and dump a single file (EF, DF or ADF) """
|
||||||
df = self._cmd.lchan.selected_file
|
file = self._cmd.lchan.get_file_by_name(filename)
|
||||||
df_path_list = df.fully_qualified_path(True)
|
if file:
|
||||||
df_path = df.fully_qualified_path_str(True)
|
res = {
|
||||||
|
'path': file.fully_qualified_path(True)
|
||||||
res = {
|
|
||||||
'path': df_path_list,
|
|
||||||
}
|
|
||||||
|
|
||||||
try:
|
|
||||||
if not self._cmd.lchan.selected_file_fcp_hex:
|
|
||||||
# An application without a real ADF (like ADF.ARA-M) / filesystem
|
|
||||||
return
|
|
||||||
|
|
||||||
fcp_dec = self._cmd.lchan.selected_file_fcp
|
|
||||||
res['fcp_raw'] = str(self._cmd.lchan.selected_file_fcp_hex)
|
|
||||||
res['fcp'] = fcp_dec
|
|
||||||
|
|
||||||
except SwMatchError as e:
|
|
||||||
res['error'] = {
|
|
||||||
'sw_actual': e.sw_actual,
|
|
||||||
'sw_expected': e.sw_expected,
|
|
||||||
'message': e.description,
|
|
||||||
}
|
}
|
||||||
except Exception as e:
|
else:
|
||||||
raise(e)
|
# If this is called from self.__walk(), then it is ensured that the file exists.
|
||||||
res['error'] = {
|
raise RuntimeError("cannot dump, file %s does not exist in the file system tree" % filename)
|
||||||
'message': str(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
context['result']['files'][df_path] = res
|
|
||||||
|
|
||||||
def fsdump_ef(self, filename, context, as_json):
|
|
||||||
"""Select and dump a single elementary file (EF) """
|
|
||||||
# TODO: this is very similar to export_ef(), but I couldn't really come up with a way to share
|
|
||||||
# code between the two. They only hypothetical option could be turn "export" into a mere
|
|
||||||
# post-processing / printing function that works on the fsdump-generated dict/json?
|
|
||||||
df = self._cmd.lchan.selected_file
|
|
||||||
|
|
||||||
# The currently selected file (not the file we are going to export)
|
|
||||||
# must always be an ADF or DF. From this starting point we select
|
|
||||||
# the EF we want to export.
|
|
||||||
if not isinstance(df, CardDF):
|
|
||||||
raise RuntimeError("currently selected file %s is not a DF or ADF" % str(df))
|
|
||||||
|
|
||||||
df_path_list = df.fully_qualified_path(True)
|
|
||||||
df_path = df.fully_qualified_path_str(True)
|
|
||||||
df_path_fid = df.fully_qualified_path_str(False)
|
|
||||||
|
|
||||||
file_str = df_path + "/" + str(filename)
|
|
||||||
|
|
||||||
res = {
|
|
||||||
'path': df_path_list + [str(filename)],
|
|
||||||
}
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
fcp_dec = self._cmd.lchan.select(filename, self._cmd)
|
fcp_dec = self._cmd.lchan.select(filename, self._cmd)
|
||||||
|
|
||||||
|
# File control parameters (common for EF, DF and ADF files)
|
||||||
|
if not self._cmd.lchan.selected_file_fcp_hex:
|
||||||
|
# An application without a real ADF (like ADF.ARA-M) / filesystem
|
||||||
|
return
|
||||||
|
|
||||||
res['fcp_raw'] = str(self._cmd.lchan.selected_file_fcp_hex)
|
res['fcp_raw'] = str(self._cmd.lchan.selected_file_fcp_hex)
|
||||||
res['fcp'] = fcp_dec
|
res['fcp'] = fcp_dec
|
||||||
|
|
||||||
structure = self._cmd.lchan.selected_file_structure()
|
# File structure and contents (EF only)
|
||||||
if structure == 'transparent':
|
if isinstance(self._cmd.lchan.selected_file, CardEF):
|
||||||
if as_json:
|
structure = self._cmd.lchan.selected_file_structure()
|
||||||
result = self._cmd.lchan.read_binary_dec()
|
if structure == 'transparent':
|
||||||
body = result[0]
|
if as_json:
|
||||||
else:
|
result = self._cmd.lchan.read_binary_dec()
|
||||||
result = self._cmd.lchan.read_binary()
|
body = result[0]
|
||||||
body = str(result[0])
|
else:
|
||||||
elif structure == 'cyclic' or structure == 'linear_fixed':
|
result = self._cmd.lchan.read_binary()
|
||||||
body = []
|
body = str(result[0])
|
||||||
# Use number of records specified in select response
|
elif structure == 'cyclic' or structure == 'linear_fixed':
|
||||||
num_of_rec = self._cmd.lchan.selected_file_num_of_rec()
|
body = []
|
||||||
if num_of_rec:
|
# Use number of records specified in select response
|
||||||
for r in range(1, num_of_rec + 1):
|
num_of_rec = self._cmd.lchan.selected_file_num_of_rec()
|
||||||
if as_json:
|
if num_of_rec:
|
||||||
result = self._cmd.lchan.read_record_dec(r)
|
for r in range(1, num_of_rec + 1):
|
||||||
body.append(result[0])
|
|
||||||
else:
|
|
||||||
result = self._cmd.lchan.read_record(r)
|
|
||||||
body.append(str(result[0]))
|
|
||||||
|
|
||||||
# When the select response does not return the number of records, read until we hit the
|
|
||||||
# first record that cannot be read.
|
|
||||||
else:
|
|
||||||
r = 1
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
if as_json:
|
if as_json:
|
||||||
result = self._cmd.lchan.read_record_dec(r)
|
result = self._cmd.lchan.read_record_dec(r)
|
||||||
body.append(result[0])
|
body.append(result[0])
|
||||||
else:
|
else:
|
||||||
result = self._cmd.lchan.read_record(r)
|
result = self._cmd.lchan.read_record(r)
|
||||||
body.append(str(result[0]))
|
body.append(str(result[0]))
|
||||||
except SwMatchError as e:
|
|
||||||
# We are past the last valid record - stop
|
# When the select response does not return the number of records, read until we hit the
|
||||||
if e.sw_actual == "9402":
|
# first record that cannot be read.
|
||||||
break
|
else:
|
||||||
# Some other problem occurred
|
r = 1
|
||||||
raise e
|
while True:
|
||||||
r = r + 1
|
try:
|
||||||
elif structure == 'ber_tlv':
|
if as_json:
|
||||||
tags = self._cmd.lchan.retrieve_tags()
|
result = self._cmd.lchan.read_record_dec(r)
|
||||||
body = {}
|
body.append(result[0])
|
||||||
for t in tags:
|
else:
|
||||||
result = self._cmd.lchan.retrieve_data(t)
|
result = self._cmd.lchan.read_record(r)
|
||||||
(tag, l, val, remainer) = bertlv_parse_one(h2b(result[0]))
|
body.append(str(result[0]))
|
||||||
body[t] = b2h(val)
|
except SwMatchError as e:
|
||||||
else:
|
# We are past the last valid record - stop
|
||||||
raise RuntimeError('Unsupported structure "%s" of file "%s"' % (structure, filename))
|
if e.sw_actual == "9402":
|
||||||
res['body'] = body
|
break
|
||||||
|
# Some other problem occurred
|
||||||
|
raise e
|
||||||
|
r = r + 1
|
||||||
|
elif structure == 'ber_tlv':
|
||||||
|
tags = self._cmd.lchan.retrieve_tags()
|
||||||
|
body = {}
|
||||||
|
for t in tags:
|
||||||
|
result = self._cmd.lchan.retrieve_data(t)
|
||||||
|
(tag, l, val, remainer) = bertlv_parse_one(h2b(result[0]))
|
||||||
|
body[t] = b2h(val)
|
||||||
|
else:
|
||||||
|
raise RuntimeError('Unsupported structure "%s" of file "%s"' % (structure, filename))
|
||||||
|
res['body'] = body
|
||||||
|
|
||||||
except SwMatchError as e:
|
except SwMatchError as e:
|
||||||
res['error'] = {
|
res['error'] = {
|
||||||
@@ -758,7 +720,7 @@ class PySimCommands(CommandSet):
|
|||||||
'message': str(e)
|
'message': str(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
context['result']['files'][file_str] = res
|
context['result']['files'][file.fully_qualified_path_str(True)] = res
|
||||||
|
|
||||||
fsdump_parser = argparse.ArgumentParser()
|
fsdump_parser = argparse.ArgumentParser()
|
||||||
fsdump_parser.add_argument(
|
fsdump_parser.add_argument(
|
||||||
@@ -785,11 +747,11 @@ class PySimCommands(CommandSet):
|
|||||||
exception_str_add = ""
|
exception_str_add = ""
|
||||||
|
|
||||||
if opts.filename:
|
if opts.filename:
|
||||||
self.__walk_action(self.fsdump_ef, opts.filename, context, **kwargs_export)
|
self.__walk_action(self.__dump_file, opts.filename, context, **kwargs_export)
|
||||||
else:
|
else:
|
||||||
# export an entire subtree
|
# export an entire subtree
|
||||||
try:
|
try:
|
||||||
self.__walk(0, self.fsdump_ef, self.fsdump_df, context, **kwargs_export)
|
self.__walk(0, self.__dump_file, self.__dump_file, context, **kwargs_export)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print("# Stopping early here due to exception: " + str(e))
|
print("# Stopping early here due to exception: " + str(e))
|
||||||
print("#")
|
print("#")
|
||||||
|
|||||||
Reference in New Issue
Block a user