dexter has uploaded this change for review. (
https://gerrit.osmocom.org/c/pysim/+/37641?usp=email )
Change subject: pySim-shell: enable export of DF and ADF files
......................................................................
pySim-shell: enable export of DF and ADF files
Since we now have the ability to provide export methods for all files
in the file system (this also includes DF and ADF files), we need
to support this at shell command level as well.
Related: OS#6092
Change-Id: I3ee661dbae5c11fec23911775f352ac13bc2c6e5
---
M pySim-shell.py
1 file changed, 82 insertions(+), 11 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/41/37641/1
diff --git a/pySim-shell.py b/pySim-shell.py
index 168c916..8fc348e 100755
--- a/pySim-shell.py
+++ b/pySim-shell.py
@@ -494,12 +494,22 @@
self._cmd.poutput(directory_str)
self._cmd.poutput("%d files" % len(selectables))
+ def _walk_action(self, action, file, context, **kwargs):
+ df_before_action = self._cmd.lchan.selected_file
+ action(file, context, **kwargs)
+ # When walking through the file system tree the action must not
+ # always restore the currently selected file to the file that
+ # was selected before executing the action() callback.
+ if df_before_action != self._cmd.lchan.selected_file:
+ raise RuntimeError("inconsistent walk, %s is currently selected but
expecting %s to be selected"
+ % (str(self._cmd.lchan.selected_file),
str(df_before_action)))
+
def walk(self, indent=0, action_ef=None, action_df=None, context=None, **kwargs):
"""Recursively walk through the file system, starting at the
currently selected DF"""
if isinstance(self._cmd.lchan.selected_file, CardDF):
if action_df:
- action_df(context, **kwargs)
+ self._walk_action(action_df, self._cmd.lchan.selected_file.name, context,
**kwargs)
files = self._cmd.lchan.selected_file.get_selectables(
flags=['FNAMES', 'ANAMES'])
@@ -536,14 +546,7 @@
self._cmd.lchan.select_parent(self._cmd)
elif action_ef:
- df_before_action = self._cmd.lchan.selected_file
- action_ef(f, context, **kwargs)
- # When walking through the file system tree the action must not
- # always restore the currently selected file to the file that
- # was selected before executing the action() callback.
- if df_before_action != self._cmd.lchan.selected_file:
- raise RuntimeError("inconsistent walk, %s is currently selected
but expecting %s to be selected"
- % (str(self._cmd.lchan.selected_file),
str(df_before_action)))
+ self._walk_action(action_ef, f, context, **kwargs)
def do_tree(self, opts):
"""Display a filesystem-tree with all selectable
files"""
@@ -594,11 +597,58 @@
self._cmd.poutput("#")
+ def export_df(self, filename, context, as_json):
+ """ Select and export a single application dedicated file (ADF)
"""
+ context['COUNT'] += 1
+ 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 ADF we want to export. To maintain consistency we will then
+ # select the current DF again (see comment below).
+ 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)
+ self._cmd.poutput(boxed_heading_str(file_str))
+
+ self._cmd.poutput("# directory: %s (%s)" % (df_path, df_path_fid))
+ try:
+ fcp_dec = self._cmd.lchan.select(filename, self._cmd)
+ self._cmd.poutput("# file: %s (%s)" %
+ (self._cmd.lchan.selected_file.name,
self._cmd.lchan.selected_file.aid))
+ self._cmd.poutput("# RAW FCP Template: %s" %
str(self._cmd.lchan.selected_file_fcp_hex))
+ self._cmd.poutput("# Decoded FCP Template: %s" %
str(self._cmd.lchan.selected_file_fcp))
+ self._cmd.poutput("select " +
self._cmd.lchan.selected_file.fully_qualified_path_str())
+ self._cmd.poutput(self._cmd.lchan.selected_file.export(as_json,
self._cmd.lchan))
+
+ except Exception as e:
+ bad_file_str = df_path + "/" + str(filename) + ", " +
str(e)
+ self._cmd.poutput("# bad file: %s" % bad_file_str)
+ context['ERR'] += 1
+ context['BAD'].append(bad_file_str)
+
+ # When reading the file is done, make sure the parent file is
+ # selected again. This will be the usual case, however we need
+ # to check before since we must not select the same DF twice
+ if df != self._cmd.lchan.selected_file:
+ self._cmd.lchan.select_parent(self._cmd)
+
+ self._cmd.poutput("#")
+
+
export_parser = argparse.ArgumentParser()
export_parser.add_argument(
'--filename', type=str, default=None, help='only export specific
file')
export_parser.add_argument(
'--json', action='store_true', help='export as JSON (less
reliable)')
+ export_parser.add_argument(
+ '--include_df', action='store_true', help='also export DF and
ADF files (where possible)')
@cmd2.with_argparser(export_parser)
def do_export(self, opts):
@@ -609,10 +659,17 @@
exception_str_add = ""
if opts.filename:
- self.export_ef(opts.filename, context, **kwargs_export)
+ file = self._cmd.lchan.get_file_for_filename(opts.filename)
+ if isinstance(file, CardDF):
+ self.export_df(opts.filename, context, **kwargs_export)
+ else:
+ self.export_ef(opts.filename, context, **kwargs_export)
else:
try:
- self.walk(0, self.export_ef, None, context, **kwargs_export)
+ if opts.include_df:
+ self.walk(0, self.export_ef, self.export_df, context,
**kwargs_export)
+ else:
+ self.walk(0, self.export_ef, None, context, **kwargs_export)
except Exception as e:
print("# Stopping early here due to exception: " + str(e))
print("#")
--
To view, visit
https://gerrit.osmocom.org/c/pysim/+/37641?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: I3ee661dbae5c11fec23911775f352ac13bc2c6e5
Gerrit-Change-Number: 37641
Gerrit-PatchSet: 1
Gerrit-Owner: dexter <pmaier(a)sysmocom.de>
Gerrit-MessageType: newchange