This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
laforge gerrit-no-reply at lists.osmocom.orglaforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/pysim/+/23661 ) Change subject: pySim-shell: JSONpath support for updating files/records ...................................................................... pySim-shell: JSONpath support for updating files/records Change-Id: Iad09b3d878b8b58ad34cb549c80f8a6eb3149faa --- M docs/shell.rst M pySim/filesystem.py A pySim/jsonpath.py M requirements.txt M setup.py 5 files changed, 79 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/61/23661/1 diff --git a/docs/shell.rst b/docs/shell.rst index 2edebbf..3cfc849 100644 --- a/docs/shell.rst +++ b/docs/shell.rst @@ -226,6 +226,33 @@ :module: pySim.filesystem :func: TransparentEF.ShellCommands.upd_bin_dec_parser +In normal operation, update_binary_decoded needs a JSON document representing the entire file contents as +input. This can be inconvenient if you want to keep 99% of the content but just toggle one specific +parameter. That's where the JSONpath support comes in handy: You can specify a JSONpath to an element +inside the document as well as a new value for tat field: + +Th below example demonstrates this by modifying the ofm field within EF.AD: + +:: + + pySIM-shell (MF/ADF.USIM/EF.AD)> read_binary_decoded + { + "ms_operation_mode": "normal", + "specific_facilities": { + "ofm": true + }, + "len_of_mnc_in_imsi": 2 + } + pySIM-shell (MF/ADF.USIM/EF.AD)> update_binary_decoded --json-path specific_facilities.ofm false + pySIM-shell (MF/ADF.USIM/EF.AD)> read_binary_decoded + { + "ms_operation_mode": "normal", + "specific_facilities": { + "ofm": false + }, + "len_of_mnc_in_imsi": 2 + } + cmd2 settable parameters diff --git a/pySim/filesystem.py b/pySim/filesystem.py index a65a764..f8443f3 100644 --- a/pySim/filesystem.py +++ b/pySim/filesystem.py @@ -35,6 +35,7 @@ from pySim.utils import sw_match, h2b, b2h, is_hex from pySim.exceptions import * +from pySim.jsonpath import js_path_find, js_path_modify class CardFile(object): """Base class for all objects in the smart card filesystem. @@ -418,10 +419,16 @@ upd_bin_dec_parser = argparse.ArgumentParser() upd_bin_dec_parser.add_argument('data', help='Abstract data (JSON format) to write') + upd_bin_dec_parser.add_argument('--json-path', type=str, + help='JSON path to modify specific element of file only') @cmd2.with_argparser(upd_bin_dec_parser) def do_update_binary_decoded(self, opts): """Encode + Update (Write) data of a transparent EF""" - data_json = json.loads(opts.data) + if opts.json_path: + (data_json, sw) = self._cmd.rs.read_binary_dec() + js_path_modify(data_json, opts.json_path, json.loads(opts.data)) + else: + data_json = json.loads(opts.data) (data, sw) = self._cmd.rs.update_binary_dec(data_json) if data: self._cmd.poutput_json(data) @@ -574,10 +581,17 @@ upd_rec_dec_parser = argparse.ArgumentParser() upd_rec_dec_parser.add_argument('record_nr', type=int, help='Number of record to be read') upd_rec_dec_parser.add_argument('data', help='Data bytes (hex format) to write') + upd_rec_dec_parser.add_argument('--json-path', type=str, + help='JSON path to modify specific element of record only') @cmd2.with_argparser(upd_rec_dec_parser) def do_update_record_decoded(self, opts): """Encode + Update (write) data to a record-oriented EF""" - (data, sw) = self._cmd.rs.update_record_dec(opts.record_nr, opts.data) + if opts.json_path: + (data_json, sw) = self._cmd.rs.read_record_dec(opts.record_nr) + js_path_modify(data_json, opts.json_path, json.loads(opts.data)) + else: + data_json = json.loads(opts.data) + (data, sw) = self._cmd.rs.update_record_dec(opts.record_nr, data_json) if data: self._cmd.poutput(data) diff --git a/pySim/jsonpath.py b/pySim/jsonpath.py new file mode 100644 index 0000000..012d1d9 --- /dev/null +++ b/pySim/jsonpath.py @@ -0,0 +1,34 @@ +import json +import pprint + +from jsonpath_ng import jsonpath, parse + +"""JSONpath utliity functions as needed within pysim. + +As pySim-sell has the ability to represent SIM files as JSON strings, +adding JSONpath allows us to conveniently modify individual sub-fields +of a file or record in its JSON representation. +""" + + +def js_path_find(js_dict, js_path): + """Find/Match a JSON path within a givne JSON-serializable dict. + Args: + js_dict : JSON-serializable dict to operate on + js_path : JSONpath string + Returns: Result of the JSONpath expression + """ + jsonpath_expr = parse(js_path) + return jsonpath_expr.find(js_dict) + +def js_path_modify(js_dict, js_path, new_val): + """Find/Match a JSON path within a givne JSON-serializable dict. + Args: + js_dict : JSON-serializable dict to operate on + js_path : JSONpath string + new_val : New value for field in js_dict at js_path + """ + jsonpath_expr = parse(js_path) + jsonpath_expr.find(js_dict) + jsonpath_expr.update(js_dict, new_val) + diff --git a/requirements.txt b/requirements.txt index 978a3db..f203ed1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,3 +2,4 @@ serial pytlv cmd2 +jsonpath-ng diff --git a/setup.py b/setup.py index d9f742c..a02e327 100644 --- a/setup.py +++ b/setup.py @@ -13,6 +13,7 @@ "serial", "pytlv", "cmd2" + "jsonpath-ng" ], scripts=[ 'pySim-prog.py', -- To view, visit https://gerrit.osmocom.org/c/pysim/+/23661 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: pysim Gerrit-Branch: master Gerrit-Change-Id: Iad09b3d878b8b58ad34cb549c80f8a6eb3149faa Gerrit-Change-Number: 23661 Gerrit-PatchSet: 1 Gerrit-Owner: laforge <laforge at osmocom.org> Gerrit-MessageType: newchange -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20210406/4f9cf179/attachment.htm>