mirror of https://gerrit.osmocom.org/pysim
pySim-shell: Create + use per-RuntimeLchan SimCardCommands
This new approach will "fork" separate SimCardCommands instances for each RuntimeLchan. Higher-layer code should now always use the RuntimeLchan.scc rather than the RuntimeState.card._scc in order to make sure commands use the correct logical channel. Change-Id: I13e2e871f2afc2460d9fd1cd566de42267c7d389 Related: OS#6230
This commit is contained in:
parent
3dfab9dede
commit
46255121e0
|
@ -326,7 +326,7 @@ class PysimApp(Cmd2Compat):
|
||||||
DANGEROUS: pySim-shell will not know any card state changes, and
|
DANGEROUS: pySim-shell will not know any card state changes, and
|
||||||
not continue to work as expected if you e.g. select a different
|
not continue to work as expected if you e.g. select a different
|
||||||
file."""
|
file."""
|
||||||
data, sw = self.card._scc._tp.send_apdu(opts.APDU)
|
data, sw = self.lchan.scc._tp.send_apdu(opts.APDU)
|
||||||
if data:
|
if data:
|
||||||
self.poutput("SW: %s, RESP: %s" % (sw, data))
|
self.poutput("SW: %s, RESP: %s" % (sw, data))
|
||||||
else:
|
else:
|
||||||
|
@ -790,7 +790,7 @@ class PySimCommands(CommandSet):
|
||||||
"cannot find ADM-PIN for ICCID '%s'" % (self._cmd.iccid))
|
"cannot find ADM-PIN for ICCID '%s'" % (self._cmd.iccid))
|
||||||
|
|
||||||
if pin_adm:
|
if pin_adm:
|
||||||
self._cmd.card._scc.verify_chv(self._cmd.card._adm_chv_num, h2b(pin_adm))
|
self._cmd.lchan.scc.verify_chv(self._cmd.card._adm_chv_num, h2b(pin_adm))
|
||||||
else:
|
else:
|
||||||
raise ValueError("error: cannot authenticate, no adm-pin!")
|
raise ValueError("error: cannot authenticate, no adm-pin!")
|
||||||
|
|
||||||
|
@ -798,10 +798,10 @@ class PySimCommands(CommandSet):
|
||||||
"""Display information about the currently inserted card"""
|
"""Display information about the currently inserted card"""
|
||||||
self._cmd.poutput("Card info:")
|
self._cmd.poutput("Card info:")
|
||||||
self._cmd.poutput(" Name: %s" % self._cmd.card.name)
|
self._cmd.poutput(" Name: %s" % self._cmd.card.name)
|
||||||
self._cmd.poutput(" ATR: %s" % b2h(self._cmd.card._scc.get_atr()))
|
self._cmd.poutput(" ATR: %s" % b2h(self._cmd.lchan.scc.get_atr()))
|
||||||
self._cmd.poutput(" ICCID: %s" % self._cmd.iccid)
|
self._cmd.poutput(" ICCID: %s" % self._cmd.iccid)
|
||||||
self._cmd.poutput(" Class-Byte: %s" % self._cmd.card._scc.cla_byte)
|
self._cmd.poutput(" Class-Byte: %s" % self._cmd.lchan.scc.cla_byte)
|
||||||
self._cmd.poutput(" Select-Ctrl: %s" % self._cmd.card._scc.sel_ctrl)
|
self._cmd.poutput(" Select-Ctrl: %s" % self._cmd.lchan.scc.sel_ctrl)
|
||||||
self._cmd.poutput(" AIDs:")
|
self._cmd.poutput(" AIDs:")
|
||||||
for a in self._cmd.rs.mf.applications:
|
for a in self._cmd.rs.mf.applications:
|
||||||
self._cmd.poutput(" %s" % a)
|
self._cmd.poutput(" %s" % a)
|
||||||
|
@ -859,7 +859,7 @@ class Iso7816Commands(CommandSet):
|
||||||
call it if you authenticate yourself using the specified PIN. There usually is at least PIN1 and
|
call it if you authenticate yourself using the specified PIN. There usually is at least PIN1 and
|
||||||
PIN2."""
|
PIN2."""
|
||||||
pin = self.get_code(opts.pin_code)
|
pin = self.get_code(opts.pin_code)
|
||||||
(data, sw) = self._cmd.card._scc.verify_chv(opts.pin_nr, h2b(pin))
|
(data, sw) = self._cmd.lchan.scc.verify_chv(opts.pin_nr, h2b(pin))
|
||||||
self._cmd.poutput("CHV verification successful")
|
self._cmd.poutput("CHV verification successful")
|
||||||
|
|
||||||
unblock_chv_parser = argparse.ArgumentParser()
|
unblock_chv_parser = argparse.ArgumentParser()
|
||||||
|
@ -875,7 +875,7 @@ class Iso7816Commands(CommandSet):
|
||||||
"""Unblock PIN code using specified PUK code"""
|
"""Unblock PIN code using specified PUK code"""
|
||||||
new_pin = self.get_code(opts.new_pin_code)
|
new_pin = self.get_code(opts.new_pin_code)
|
||||||
puk = self.get_code(opts.puk_code)
|
puk = self.get_code(opts.puk_code)
|
||||||
(data, sw) = self._cmd.card._scc.unblock_chv(
|
(data, sw) = self._cmd.lchan.scc.unblock_chv(
|
||||||
opts.pin_nr, h2b(puk), h2b(new_pin))
|
opts.pin_nr, h2b(puk), h2b(new_pin))
|
||||||
self._cmd.poutput("CHV unblock successful")
|
self._cmd.poutput("CHV unblock successful")
|
||||||
|
|
||||||
|
@ -892,7 +892,7 @@ class Iso7816Commands(CommandSet):
|
||||||
"""Change PIN code to a new PIN code"""
|
"""Change PIN code to a new PIN code"""
|
||||||
new_pin = self.get_code(opts.new_pin_code)
|
new_pin = self.get_code(opts.new_pin_code)
|
||||||
pin = self.get_code(opts.pin_code)
|
pin = self.get_code(opts.pin_code)
|
||||||
(data, sw) = self._cmd.card._scc.change_chv(
|
(data, sw) = self._cmd.lchan.scc.change_chv(
|
||||||
opts.pin_nr, h2b(pin), h2b(new_pin))
|
opts.pin_nr, h2b(pin), h2b(new_pin))
|
||||||
self._cmd.poutput("CHV change successful")
|
self._cmd.poutput("CHV change successful")
|
||||||
|
|
||||||
|
@ -906,7 +906,7 @@ class Iso7816Commands(CommandSet):
|
||||||
def do_disable_chv(self, opts):
|
def do_disable_chv(self, opts):
|
||||||
"""Disable PIN code using specified PIN code"""
|
"""Disable PIN code using specified PIN code"""
|
||||||
pin = self.get_code(opts.pin_code)
|
pin = self.get_code(opts.pin_code)
|
||||||
(data, sw) = self._cmd.card._scc.disable_chv(opts.pin_nr, h2b(pin))
|
(data, sw) = self._cmd.lchan.scc.disable_chv(opts.pin_nr, h2b(pin))
|
||||||
self._cmd.poutput("CHV disable successful")
|
self._cmd.poutput("CHV disable successful")
|
||||||
|
|
||||||
enable_chv_parser = argparse.ArgumentParser()
|
enable_chv_parser = argparse.ArgumentParser()
|
||||||
|
@ -919,12 +919,12 @@ class Iso7816Commands(CommandSet):
|
||||||
def do_enable_chv(self, opts):
|
def do_enable_chv(self, opts):
|
||||||
"""Enable PIN code using specified PIN code"""
|
"""Enable PIN code using specified PIN code"""
|
||||||
pin = self.get_code(opts.pin_code)
|
pin = self.get_code(opts.pin_code)
|
||||||
(data, sw) = self._cmd.card._scc.enable_chv(opts.pin_nr, h2b(pin))
|
(data, sw) = self._cmd.lchan.scc.enable_chv(opts.pin_nr, h2b(pin))
|
||||||
self._cmd.poutput("CHV enable successful")
|
self._cmd.poutput("CHV enable successful")
|
||||||
|
|
||||||
def do_deactivate_file(self, opts):
|
def do_deactivate_file(self, opts):
|
||||||
"""Deactivate the currently selected EF"""
|
"""Deactivate the currently selected EF"""
|
||||||
(data, sw) = self._cmd.card._scc.deactivate_file()
|
(data, sw) = self._cmd.lchan.scc.deactivate_file()
|
||||||
|
|
||||||
activate_file_parser = argparse.ArgumentParser()
|
activate_file_parser = argparse.ArgumentParser()
|
||||||
activate_file_parser.add_argument('NAME', type=str, help='File name or FID of file to activate')
|
activate_file_parser.add_argument('NAME', type=str, help='File name or FID of file to activate')
|
||||||
|
@ -946,7 +946,7 @@ class Iso7816Commands(CommandSet):
|
||||||
@cmd2.with_argparser(open_chan_parser)
|
@cmd2.with_argparser(open_chan_parser)
|
||||||
def do_open_channel(self, opts):
|
def do_open_channel(self, opts):
|
||||||
"""Open a logical channel."""
|
"""Open a logical channel."""
|
||||||
(data, sw) = self._cmd.card._scc.manage_channel(
|
(data, sw) = self._cmd.lchan.scc.manage_channel(
|
||||||
mode='open', lchan_nr=opts.chan_nr)
|
mode='open', lchan_nr=opts.chan_nr)
|
||||||
# this is executed only in successful case, as unsuccessful raises exception
|
# this is executed only in successful case, as unsuccessful raises exception
|
||||||
self._cmd.lchan.add_lchan(opts.chan_nr)
|
self._cmd.lchan.add_lchan(opts.chan_nr)
|
||||||
|
@ -958,7 +958,7 @@ class Iso7816Commands(CommandSet):
|
||||||
@cmd2.with_argparser(close_chan_parser)
|
@cmd2.with_argparser(close_chan_parser)
|
||||||
def do_close_channel(self, opts):
|
def do_close_channel(self, opts):
|
||||||
"""Close a logical channel."""
|
"""Close a logical channel."""
|
||||||
(data, sw) = self._cmd.card._scc.manage_channel(
|
(data, sw) = self._cmd.lchan.scc.manage_channel(
|
||||||
mode='close', lchan_nr=opts.chan_nr)
|
mode='close', lchan_nr=opts.chan_nr)
|
||||||
# this is executed only in successful case, as unsuccessful raises exception
|
# this is executed only in successful case, as unsuccessful raises exception
|
||||||
self._cmd.rs.del_lchan(opts.chan_nr)
|
self._cmd.rs.del_lchan(opts.chan_nr)
|
||||||
|
|
|
@ -306,13 +306,13 @@ class ADF_ARAM(CardADF):
|
||||||
|
|
||||||
def do_aram_get_all(self, opts):
|
def do_aram_get_all(self, opts):
|
||||||
"""GET DATA [All] on the ARA-M Applet"""
|
"""GET DATA [All] on the ARA-M Applet"""
|
||||||
res_do = ADF_ARAM.get_all(self._cmd.card._scc._tp)
|
res_do = ADF_ARAM.get_all(self._cmd.lchan.scc._tp)
|
||||||
if res_do:
|
if res_do:
|
||||||
self._cmd.poutput_json(res_do.to_dict())
|
self._cmd.poutput_json(res_do.to_dict())
|
||||||
|
|
||||||
def do_aram_get_config(self, opts):
|
def do_aram_get_config(self, opts):
|
||||||
"""Perform GET DATA [Config] on the ARA-M Applet: Tell it our version and retrieve its version."""
|
"""Perform GET DATA [Config] on the ARA-M Applet: Tell it our version and retrieve its version."""
|
||||||
res_do = ADF_ARAM.get_config(self._cmd.card._scc._tp)
|
res_do = ADF_ARAM.get_config(self._cmd.lchan.scc._tp)
|
||||||
if res_do:
|
if res_do:
|
||||||
self._cmd.poutput_json(res_do.to_dict())
|
self._cmd.poutput_json(res_do.to_dict())
|
||||||
|
|
||||||
|
@ -373,14 +373,14 @@ class ADF_ARAM(CardADF):
|
||||||
d = [{'ref_ar_do': [{'ref_do': ref_do_content}, {'ar_do': ar_do_content}]}]
|
d = [{'ref_ar_do': [{'ref_do': ref_do_content}, {'ar_do': ar_do_content}]}]
|
||||||
csrado = CommandStoreRefArDO()
|
csrado = CommandStoreRefArDO()
|
||||||
csrado.from_dict(d)
|
csrado.from_dict(d)
|
||||||
res_do = ADF_ARAM.store_data(self._cmd.card._scc._tp, csrado)
|
res_do = ADF_ARAM.store_data(self._cmd.lchan.scc._tp, csrado)
|
||||||
if res_do:
|
if res_do:
|
||||||
self._cmd.poutput_json(res_do.to_dict())
|
self._cmd.poutput_json(res_do.to_dict())
|
||||||
|
|
||||||
def do_aram_delete_all(self, opts):
|
def do_aram_delete_all(self, opts):
|
||||||
"""Perform STORE DATA [Command-Delete[all]] to delete all access rules."""
|
"""Perform STORE DATA [Command-Delete[all]] to delete all access rules."""
|
||||||
deldo = CommandDelete()
|
deldo = CommandDelete()
|
||||||
res_do = ADF_ARAM.store_data(self._cmd.card._scc._tp, deldo)
|
res_do = ADF_ARAM.store_data(self._cmd.lchan.scc._tp, deldo)
|
||||||
if res_do:
|
if res_do:
|
||||||
self._cmd.poutput_json(res_do.to_dict())
|
self._cmd.poutput_json(res_do.to_dict())
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,7 @@ class SimCardCommands:
|
||||||
"""Fork a per-lchan specific SimCardCommands instance off the current instance."""
|
"""Fork a per-lchan specific SimCardCommands instance off the current instance."""
|
||||||
ret = SimCardCommands(transport = self._tp, lchan_nr = lchan_nr)
|
ret = SimCardCommands(transport = self._tp, lchan_nr = lchan_nr)
|
||||||
ret.cla_byte = self._cla_byte
|
ret.cla_byte = self._cla_byte
|
||||||
|
ret.sel_ctrl = self.sel_ctrl
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
@ -238,7 +238,7 @@ class ADF_SD(CardADF):
|
||||||
self._cmd.poutput('Unknown data object "%s", available options: %s' % (tlv_cls_name,
|
self._cmd.poutput('Unknown data object "%s", available options: %s' % (tlv_cls_name,
|
||||||
do_names))
|
do_names))
|
||||||
return
|
return
|
||||||
(data, sw) = self._cmd.card._scc.get_data(cla=0x80, tag=tlv_cls.tag)
|
(data, sw) = self._cmd.lchan.scc.get_data(cla=0x80, tag=tlv_cls.tag)
|
||||||
ie = tlv_cls()
|
ie = tlv_cls()
|
||||||
ie.from_tlv(h2b(data))
|
ie.from_tlv(h2b(data))
|
||||||
self._cmd.poutput_json(ie.to_dict())
|
self._cmd.poutput_json(ie.to_dict())
|
||||||
|
|
|
@ -167,6 +167,7 @@ class RuntimeLchan:
|
||||||
self.selected_adf = None
|
self.selected_adf = None
|
||||||
self.selected_file_fcp = None
|
self.selected_file_fcp = None
|
||||||
self.selected_file_fcp_hex = None
|
self.selected_file_fcp_hex = None
|
||||||
|
self.scc = self.rs.card._scc.fork_lchan(lchan_nr)
|
||||||
|
|
||||||
def add_lchan(self, lchan_nr: int) -> 'RuntimeLchan':
|
def add_lchan(self, lchan_nr: int) -> 'RuntimeLchan':
|
||||||
"""Add a new logical channel from the current logical channel. Just affects
|
"""Add a new logical channel from the current logical channel. Just affects
|
||||||
|
@ -246,7 +247,7 @@ class RuntimeLchan:
|
||||||
"Cannot select unknown file by name %s, only hexadecimal 4 digit FID is allowed" % fid)
|
"Cannot select unknown file by name %s, only hexadecimal 4 digit FID is allowed" % fid)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
(data, sw) = self.rs.card._scc.select_file(fid)
|
(data, sw) = self.scc.select_file(fid)
|
||||||
except SwMatchError as swm:
|
except SwMatchError as swm:
|
||||||
k = self.interpret_sw(swm.sw_actual)
|
k = self.interpret_sw(swm.sw_actual)
|
||||||
if not k:
|
if not k:
|
||||||
|
@ -301,7 +302,7 @@ class RuntimeLchan:
|
||||||
(data, sw) = self.rs.card.select_adf_by_aid(p.aid)
|
(data, sw) = self.rs.card.select_adf_by_aid(p.aid)
|
||||||
self.selected_adf = p
|
self.selected_adf = p
|
||||||
else:
|
else:
|
||||||
(data, sw) = self.rs.card._scc.select_file(p.fid)
|
(data, sw) = self.scc.select_file(p.fid)
|
||||||
self.selected_file = p
|
self.selected_file = p
|
||||||
except SwMatchError as swm:
|
except SwMatchError as swm:
|
||||||
self._select_post(cmd_app)
|
self._select_post(cmd_app)
|
||||||
|
@ -344,7 +345,7 @@ class RuntimeLchan:
|
||||||
if isinstance(f, CardADF):
|
if isinstance(f, CardADF):
|
||||||
(data, sw) = self.rs.card.select_adf_by_aid(f.aid)
|
(data, sw) = self.rs.card.select_adf_by_aid(f.aid)
|
||||||
else:
|
else:
|
||||||
(data, sw) = self.rs.card._scc.select_file(f.fid)
|
(data, sw) = self.scc.select_file(f.fid)
|
||||||
self.selected_file = f
|
self.selected_file = f
|
||||||
except SwMatchError as swm:
|
except SwMatchError as swm:
|
||||||
k = self.interpret_sw(swm.sw_actual)
|
k = self.interpret_sw(swm.sw_actual)
|
||||||
|
@ -364,7 +365,7 @@ class RuntimeLchan:
|
||||||
|
|
||||||
def status(self):
|
def status(self):
|
||||||
"""Request STATUS (current selected file FCP) from card."""
|
"""Request STATUS (current selected file FCP) from card."""
|
||||||
(data, sw) = self.rs.card._scc.status()
|
(data, sw) = self.scc.status()
|
||||||
return self.selected_file.decode_select_response(data)
|
return self.selected_file.decode_select_response(data)
|
||||||
|
|
||||||
def get_file_for_selectable(self, name: str):
|
def get_file_for_selectable(self, name: str):
|
||||||
|
@ -375,7 +376,7 @@ class RuntimeLchan:
|
||||||
"""Request ACTIVATE FILE of specified file."""
|
"""Request ACTIVATE FILE of specified file."""
|
||||||
sels = self.selected_file.get_selectables()
|
sels = self.selected_file.get_selectables()
|
||||||
f = sels[name]
|
f = sels[name]
|
||||||
data, sw = self.rs.card._scc.activate_file(f.fid)
|
data, sw = self.scc.activate_file(f.fid)
|
||||||
return data, sw
|
return data, sw
|
||||||
|
|
||||||
def read_binary(self, length: int = None, offset: int = 0):
|
def read_binary(self, length: int = None, offset: int = 0):
|
||||||
|
@ -389,7 +390,7 @@ class RuntimeLchan:
|
||||||
"""
|
"""
|
||||||
if not isinstance(self.selected_file, TransparentEF):
|
if not isinstance(self.selected_file, TransparentEF):
|
||||||
raise TypeError("Only works with TransparentEF")
|
raise TypeError("Only works with TransparentEF")
|
||||||
return self.rs.card._scc.read_binary(self.selected_file.fid, length, offset)
|
return self.scc.read_binary(self.selected_file.fid, length, offset)
|
||||||
|
|
||||||
def read_binary_dec(self) -> Tuple[dict, str]:
|
def read_binary_dec(self) -> Tuple[dict, str]:
|
||||||
"""Read [part of] a transparent EF binary data and decode it.
|
"""Read [part of] a transparent EF binary data and decode it.
|
||||||
|
@ -413,7 +414,7 @@ class RuntimeLchan:
|
||||||
"""
|
"""
|
||||||
if not isinstance(self.selected_file, TransparentEF):
|
if not isinstance(self.selected_file, TransparentEF):
|
||||||
raise TypeError("Only works with TransparentEF")
|
raise TypeError("Only works with TransparentEF")
|
||||||
return self.rs.card._scc.update_binary(self.selected_file.fid, data_hex, offset, conserve=self.rs.conserve_write)
|
return self.scc.update_binary(self.selected_file.fid, data_hex, offset, conserve=self.rs.conserve_write)
|
||||||
|
|
||||||
def update_binary_dec(self, data: dict):
|
def update_binary_dec(self, data: dict):
|
||||||
"""Update transparent EF from abstract data. Encodes the data to binary and
|
"""Update transparent EF from abstract data. Encodes the data to binary and
|
||||||
|
@ -436,7 +437,7 @@ class RuntimeLchan:
|
||||||
if not isinstance(self.selected_file, LinFixedEF):
|
if not isinstance(self.selected_file, LinFixedEF):
|
||||||
raise TypeError("Only works with Linear Fixed EF")
|
raise TypeError("Only works with Linear Fixed EF")
|
||||||
# returns a string of hex nibbles
|
# returns a string of hex nibbles
|
||||||
return self.rs.card._scc.read_record(self.selected_file.fid, rec_nr)
|
return self.scc.read_record(self.selected_file.fid, rec_nr)
|
||||||
|
|
||||||
def read_record_dec(self, rec_nr: int = 0) -> Tuple[dict, str]:
|
def read_record_dec(self, rec_nr: int = 0) -> Tuple[dict, str]:
|
||||||
"""Read a record and decode it to abstract data.
|
"""Read a record and decode it to abstract data.
|
||||||
|
@ -458,7 +459,7 @@ class RuntimeLchan:
|
||||||
"""
|
"""
|
||||||
if not isinstance(self.selected_file, LinFixedEF):
|
if not isinstance(self.selected_file, LinFixedEF):
|
||||||
raise TypeError("Only works with Linear Fixed EF")
|
raise TypeError("Only works with Linear Fixed EF")
|
||||||
return self.rs.card._scc.update_record(self.selected_file.fid, rec_nr, data_hex,
|
return self.scc.update_record(self.selected_file.fid, rec_nr, data_hex,
|
||||||
conserve=self.rs.conserve_write,
|
conserve=self.rs.conserve_write,
|
||||||
leftpad=self.selected_file.leftpad)
|
leftpad=self.selected_file.leftpad)
|
||||||
|
|
||||||
|
@ -484,7 +485,7 @@ class RuntimeLchan:
|
||||||
if not isinstance(self.selected_file, BerTlvEF):
|
if not isinstance(self.selected_file, BerTlvEF):
|
||||||
raise TypeError("Only works with BER-TLV EF")
|
raise TypeError("Only works with BER-TLV EF")
|
||||||
# returns a string of hex nibbles
|
# returns a string of hex nibbles
|
||||||
return self.rs.card._scc.retrieve_data(self.selected_file.fid, tag)
|
return self.scc.retrieve_data(self.selected_file.fid, tag)
|
||||||
|
|
||||||
def retrieve_tags(self):
|
def retrieve_tags(self):
|
||||||
"""Retrieve tags available on BER-TLV EF.
|
"""Retrieve tags available on BER-TLV EF.
|
||||||
|
@ -494,7 +495,7 @@ class RuntimeLchan:
|
||||||
"""
|
"""
|
||||||
if not isinstance(self.selected_file, BerTlvEF):
|
if not isinstance(self.selected_file, BerTlvEF):
|
||||||
raise TypeError("Only works with BER-TLV EF")
|
raise TypeError("Only works with BER-TLV EF")
|
||||||
data, sw = self.rs.card._scc.retrieve_data(self.selected_file.fid, 0x5c)
|
data, sw = self.scc.retrieve_data(self.selected_file.fid, 0x5c)
|
||||||
tag, length, value, remainder = bertlv_parse_one(h2b(data))
|
tag, length, value, remainder = bertlv_parse_one(h2b(data))
|
||||||
return list(value)
|
return list(value)
|
||||||
|
|
||||||
|
@ -507,7 +508,7 @@ class RuntimeLchan:
|
||||||
"""
|
"""
|
||||||
if not isinstance(self.selected_file, BerTlvEF):
|
if not isinstance(self.selected_file, BerTlvEF):
|
||||||
raise TypeError("Only works with BER-TLV EF")
|
raise TypeError("Only works with BER-TLV EF")
|
||||||
return self.rs.card._scc.set_data(self.selected_file.fid, tag, data_hex, conserve=self.rs.conserve_write)
|
return self.scc.set_data(self.selected_file.fid, tag, data_hex, conserve=self.rs.conserve_write)
|
||||||
|
|
||||||
def unregister_cmds(self, cmd_app=None):
|
def unregister_cmds(self, cmd_app=None):
|
||||||
"""Unregister all file specific commands."""
|
"""Unregister all file specific commands."""
|
||||||
|
|
|
@ -49,7 +49,7 @@ class Ts102222Commands(CommandSet):
|
||||||
self._cmd.perror("Refusing to permanently delete the file, please read the help text.")
|
self._cmd.perror("Refusing to permanently delete the file, please read the help text.")
|
||||||
return
|
return
|
||||||
f = self._cmd.lchan.get_file_for_selectable(opts.NAME)
|
f = self._cmd.lchan.get_file_for_selectable(opts.NAME)
|
||||||
(data, sw) = self._cmd.card._scc.delete_file(f.fid)
|
(data, sw) = self._cmd.lchan.scc.delete_file(f.fid)
|
||||||
|
|
||||||
def complete_delete_file(self, text, line, begidx, endidx) -> List[str]:
|
def complete_delete_file(self, text, line, begidx, endidx) -> List[str]:
|
||||||
"""Command Line tab completion for DELETE FILE"""
|
"""Command Line tab completion for DELETE FILE"""
|
||||||
|
@ -70,7 +70,7 @@ class Ts102222Commands(CommandSet):
|
||||||
self._cmd.perror("Refusing to terminate the file, please read the help text.")
|
self._cmd.perror("Refusing to terminate the file, please read the help text.")
|
||||||
return
|
return
|
||||||
f = self._cmd.lchan.get_file_for_selectable(opts.NAME)
|
f = self._cmd.lchan.get_file_for_selectable(opts.NAME)
|
||||||
(data, sw) = self._cmd.card._scc.terminate_df(f.fid)
|
(data, sw) = self._cmd.lchan.scc.terminate_df(f.fid)
|
||||||
|
|
||||||
def complete_terminate_df(self, text, line, begidx, endidx) -> List[str]:
|
def complete_terminate_df(self, text, line, begidx, endidx) -> List[str]:
|
||||||
"""Command Line tab completion for TERMINATE DF"""
|
"""Command Line tab completion for TERMINATE DF"""
|
||||||
|
@ -86,7 +86,7 @@ class Ts102222Commands(CommandSet):
|
||||||
self._cmd.perror("Refusing to terminate the file, please read the help text.")
|
self._cmd.perror("Refusing to terminate the file, please read the help text.")
|
||||||
return
|
return
|
||||||
f = self._cmd.lchan.get_file_for_selectable(opts.NAME)
|
f = self._cmd.lchan.get_file_for_selectable(opts.NAME)
|
||||||
(data, sw) = self._cmd.card._scc.terminate_ef(f.fid)
|
(data, sw) = self._cmd.lchan.scc.terminate_ef(f.fid)
|
||||||
|
|
||||||
def complete_terminate_ef(self, text, line, begidx, endidx) -> List[str]:
|
def complete_terminate_ef(self, text, line, begidx, endidx) -> List[str]:
|
||||||
"""Command Line tab completion for TERMINATE EF"""
|
"""Command Line tab completion for TERMINATE EF"""
|
||||||
|
@ -104,7 +104,7 @@ class Ts102222Commands(CommandSet):
|
||||||
if not opts.force_terminate_card:
|
if not opts.force_terminate_card:
|
||||||
self._cmd.perror("Refusing to permanently terminate the card, please read the help text.")
|
self._cmd.perror("Refusing to permanently terminate the card, please read the help text.")
|
||||||
return
|
return
|
||||||
(data, sw) = self._cmd.card._scc.terminate_card_usage()
|
(data, sw) = self._cmd.lchan.scc.terminate_card_usage()
|
||||||
|
|
||||||
create_parser = argparse.ArgumentParser()
|
create_parser = argparse.ArgumentParser()
|
||||||
create_parser.add_argument('FILE_ID', type=str, help='File Identifier as 4-character hex string')
|
create_parser.add_argument('FILE_ID', type=str, help='File Identifier as 4-character hex string')
|
||||||
|
@ -149,7 +149,7 @@ class Ts102222Commands(CommandSet):
|
||||||
ShortFileIdentifier(decoded=opts.short_file_id),
|
ShortFileIdentifier(decoded=opts.short_file_id),
|
||||||
]
|
]
|
||||||
fcp = FcpTemplate(children=ies)
|
fcp = FcpTemplate(children=ies)
|
||||||
(data, sw) = self._cmd.card._scc.create_file(b2h(fcp.to_tlv()))
|
(data, sw) = self._cmd.lchan.scc.create_file(b2h(fcp.to_tlv()))
|
||||||
# the newly-created file is automatically selected but our runtime state knows nothing of it
|
# the newly-created file is automatically selected but our runtime state knows nothing of it
|
||||||
self._cmd.lchan.select_file(self._cmd.lchan.selected_file)
|
self._cmd.lchan.select_file(self._cmd.lchan.selected_file)
|
||||||
|
|
||||||
|
@ -200,7 +200,7 @@ class Ts102222Commands(CommandSet):
|
||||||
}
|
}
|
||||||
ies.append(ProprietaryInformation(children=[ToolkitAccessConditions(decoded=toolkit_ac)]))
|
ies.append(ProprietaryInformation(children=[ToolkitAccessConditions(decoded=toolkit_ac)]))
|
||||||
fcp = FcpTemplate(children=ies)
|
fcp = FcpTemplate(children=ies)
|
||||||
(data, sw) = self._cmd.card._scc.create_file(b2h(fcp.to_tlv()))
|
(data, sw) = self._cmd.lchan.scc.create_file(b2h(fcp.to_tlv()))
|
||||||
# the newly-created file is automatically selected but our runtime state knows nothing of it
|
# the newly-created file is automatically selected but our runtime state knows nothing of it
|
||||||
self._cmd.lchan.select_file(self._cmd.lchan.selected_file)
|
self._cmd.lchan.select_file(self._cmd.lchan.selected_file)
|
||||||
|
|
||||||
|
@ -217,7 +217,7 @@ class Ts102222Commands(CommandSet):
|
||||||
ies = [FileIdentifier(decoded=f.fid),
|
ies = [FileIdentifier(decoded=f.fid),
|
||||||
FileSize(decoded=opts.file_size)]
|
FileSize(decoded=opts.file_size)]
|
||||||
fcp = FcpTemplate(children=ies)
|
fcp = FcpTemplate(children=ies)
|
||||||
(data, sw) = self._cmd.card._scc.resize_file(b2h(fcp.to_tlv()))
|
(data, sw) = self._cmd.lchan.scc.resize_file(b2h(fcp.to_tlv()))
|
||||||
# the resized file is automatically selected but our runtime state knows nothing of it
|
# the resized file is automatically selected but our runtime state knows nothing of it
|
||||||
self._cmd.lchan.select_file(self._cmd.lchan.selected_file)
|
self._cmd.lchan.select_file(self._cmd.lchan.selected_file)
|
||||||
|
|
||||||
|
|
|
@ -1512,7 +1512,7 @@ class ADF_USIM(CardADF):
|
||||||
@cmd2.with_argparser(authenticate_parser)
|
@cmd2.with_argparser(authenticate_parser)
|
||||||
def do_authenticate(self, opts):
|
def do_authenticate(self, opts):
|
||||||
"""Perform Authentication and Key Agreement (AKA)."""
|
"""Perform Authentication and Key Agreement (AKA)."""
|
||||||
(data, sw) = self._cmd.card._scc.authenticate(opts.rand, opts.autn)
|
(data, sw) = self._cmd.lchan.scc.authenticate(opts.rand, opts.autn)
|
||||||
self._cmd.poutput_json(data)
|
self._cmd.poutput_json(data)
|
||||||
|
|
||||||
term_prof_parser = argparse.ArgumentParser()
|
term_prof_parser = argparse.ArgumentParser()
|
||||||
|
@ -1526,7 +1526,7 @@ class ADF_USIM(CardADF):
|
||||||
in the context of SIM Toolkit, Proactive SIM and OTA. You
|
in the context of SIM Toolkit, Proactive SIM and OTA. You
|
||||||
must specify a hex-string with the encoded terminal profile
|
must specify a hex-string with the encoded terminal profile
|
||||||
you want to send to the card."""
|
you want to send to the card."""
|
||||||
(data, sw) = self._cmd.card._scc.terminal_profile(opts.PROFILE)
|
(data, sw) = self._cmd.lchan.scc.terminal_profile(opts.PROFILE)
|
||||||
self._cmd.poutput('SW: %s, data: %s' % (sw, data))
|
self._cmd.poutput('SW: %s, data: %s' % (sw, data))
|
||||||
|
|
||||||
envelope_parser = argparse.ArgumentParser()
|
envelope_parser = argparse.ArgumentParser()
|
||||||
|
@ -1538,7 +1538,7 @@ class ADF_USIM(CardADF):
|
||||||
variety of information is communicated from the terminal
|
variety of information is communicated from the terminal
|
||||||
(modem/phone) to the card, particularly in the context of
|
(modem/phone) to the card, particularly in the context of
|
||||||
SIM Toolkit, Proactive SIM and OTA."""
|
SIM Toolkit, Proactive SIM and OTA."""
|
||||||
(data, sw) = self._cmd.card._scc.envelope(opts.PAYLOAD)
|
(data, sw) = self._cmd.lchan.scc.envelope(opts.PAYLOAD)
|
||||||
self._cmd.poutput('SW: %s, data: %s' % (sw, data))
|
self._cmd.poutput('SW: %s, data: %s' % (sw, data))
|
||||||
|
|
||||||
envelope_sms_parser = argparse.ArgumentParser()
|
envelope_sms_parser = argparse.ArgumentParser()
|
||||||
|
@ -1556,7 +1556,7 @@ class ADF_USIM(CardADF):
|
||||||
dev_ids = DeviceIdentities(
|
dev_ids = DeviceIdentities(
|
||||||
decoded={'source_dev_id': 'network', 'dest_dev_id': 'uicc'})
|
decoded={'source_dev_id': 'network', 'dest_dev_id': 'uicc'})
|
||||||
sms_dl = SMSPPDownload(children=[dev_ids, tpdu_ie])
|
sms_dl = SMSPPDownload(children=[dev_ids, tpdu_ie])
|
||||||
(data, sw) = self._cmd.card._scc.envelope(b2h(sms_dl.to_tlv()))
|
(data, sw) = self._cmd.lchan.scc.envelope(b2h(sms_dl.to_tlv()))
|
||||||
self._cmd.poutput('SW: %s, data: %s' % (sw, data))
|
self._cmd.poutput('SW: %s, data: %s' % (sw, data))
|
||||||
|
|
||||||
get_id_parser = argparse.ArgumentParser()
|
get_id_parser = argparse.ArgumentParser()
|
||||||
|
@ -1570,7 +1570,7 @@ class ADF_USIM(CardADF):
|
||||||
context = 0x01 # SUCI
|
context = 0x01 # SUCI
|
||||||
if opts.nswo_context:
|
if opts.nswo_context:
|
||||||
context = 0x02 # SUCI 5G NSWO
|
context = 0x02 # SUCI 5G NSWO
|
||||||
(data, sw) = self._cmd.card._scc.get_identity(context)
|
(data, sw) = self._cmd.lchan.scc.get_identity(context)
|
||||||
do = SUCI_TlvDataObject()
|
do = SUCI_TlvDataObject()
|
||||||
do.from_tlv(h2b(data))
|
do.from_tlv(h2b(data))
|
||||||
do_d = do.to_dict()
|
do_d = do.to_dict()
|
||||||
|
|
|
@ -1001,7 +1001,7 @@ class DF_GSM(CardDF):
|
||||||
@cmd2.with_argparser(authenticate_parser)
|
@cmd2.with_argparser(authenticate_parser)
|
||||||
def do_authenticate(self, opts):
|
def do_authenticate(self, opts):
|
||||||
"""Perform GSM Authentication."""
|
"""Perform GSM Authentication."""
|
||||||
(data, sw) = self._cmd.card._scc.run_gsm(opts.rand)
|
(data, sw) = self._cmd.lchan.scc.run_gsm(opts.rand)
|
||||||
self._cmd.poutput_json(data)
|
self._cmd.poutput_json(data)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue