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:
Harald Welte 2023-10-21 23:40:42 +02:00
parent 3dfab9dede
commit 46255121e0
8 changed files with 45 additions and 43 deletions

View File

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

View File

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

View File

@ -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

View File

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

View File

@ -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."""

View File

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

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

View File

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