fix: keep pySim's command-set bookkeeping in sync in the ES10 selections
After a profile switch the shell was unusable: every file select failed
with 'Attribute already exists: do_decode_hex (ShellCommands)' and even
equipping did not help - only a server restart recovered it.
pySim's equip() unregisters only the command sets of the file that is
selected at that moment, then re-registers everything while selecting
MF/EF.ICCID and MF with the app as cmd_app. esim._select_isdr() selected
the ISD-R ADF without cmd_app, so MF's sets (ShellCommands, ...) stayed
registered while the selection moved to the ADF; the equip after the
profile switch then died re-registering them (cmd2 raises
CommandSetRegistrationError), leaving the app broken.
- _select_isdr() passes the shell app as cmd_app, so the old file's sets
are unregistered and the ADF's (none) registered.
- _restore() passes it to soft_reset() too, so the MF re-selection updates
the bookkeeping on both the success and the failure path.
- _esim_reinit() probes select('MF', app) after the equip and reports
reinitialized: false on a registration error (a card-level select
failure, e.g. no active profile, is tolerated).
- tests assert the cmd_app plumbing on the ISD-R select and the restore
(profiles, chip and both switch paths).
This commit is contained in:
@@ -54,14 +54,20 @@ def is_euicc(app):
|
||||
|
||||
|
||||
def _select_isdr(app):
|
||||
"""Select ISD-R on logical channel 0; returns the lchan's scc."""
|
||||
"""Select ISD-R on logical channel 0; returns the lchan's scc.
|
||||
|
||||
The shell app is passed as cmd_app so pySim keeps its command-set
|
||||
bookkeeping in sync with the selection: ``equip()`` only unregisters the
|
||||
sets of the file selected at that moment, so a selection made without
|
||||
cmd_app leaves the old file's sets registered and the next equip dies
|
||||
re-registering them (cmd2: 'Attribute already exists')."""
|
||||
rs = getattr(app, 'rs', None)
|
||||
apps = getattr(getattr(rs, 'mf', None), 'applications', None) or {}
|
||||
isd_r = apps.get(AID_ISD_R.lower())
|
||||
if isd_r is None:
|
||||
raise EsimError('not_an_euicc')
|
||||
lchan = rs.lchan[0]
|
||||
lchan.select_file(isd_r)
|
||||
lchan.select_file(isd_r, app)
|
||||
return lchan.scc
|
||||
|
||||
|
||||
@@ -70,9 +76,10 @@ def _restore(app):
|
||||
|
||||
Best effort: a card whose active profile is disabled has no filesystem to
|
||||
select, so the restore can legitimately fail - the selection metadata is
|
||||
then guarded by the status endpoint instead of crashing it."""
|
||||
then guarded by the status endpoint instead of crashing it. The shell app
|
||||
is passed as cmd_app so the command-set bookkeeping follows the selection."""
|
||||
try:
|
||||
app.rs.soft_reset()
|
||||
app.rs.soft_reset(app)
|
||||
except Exception as e:
|
||||
sys.stderr.write('ESIM: selection restore failed: %s\n' % e)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user