esim: local eUICC operations in the Phone simulator tab (v2.8.0)

New eSIM pill (Phone simulator) for SGP.22/32 cards, built on pySim's
ES10 static API — no lpac, no new dependencies, no pysim patches, no
SM-DP+ interaction:

- Chip: EID, EUICCInfo1/2, configured addresses (ES10a/b).
- Profiles: GetProfilesInfo with metadata (state, nickname, provider,
  ICCID, ISD-P AID, class, owner, icon).
- Notifications: read-only ListNotification viewer.
- Switch: Enable/DisableProfile with RefreshFlag=1; the card's REFRESH
  (fetched/answered/logged by the transport's proactive handler) or an ok
  result triggers _esim_reinit() — reset + equip + _apply_equipped_card —
  so the ICCID, network state and cached views are re-read.
- Server: pysim_simple_server/esim.py, GET /api/esim/chip|profiles|
  notifications, POST /api/esim/profile (all under _CARD_LOCK; 400
  not_an_euicc), euicc/eid in /api/status.
- Tests: tests/test_esim.py (fake scc, monkeypatched store_data_tlv),
  frontend/tests/esim.test.js; help EN/RU, docs/api.md, AGENTS.
This commit is contained in:
2026-09-21 23:10:52 +03:00
parent e3502c059e
commit a4d5415034
11 changed files with 1051 additions and 8 deletions
+35
View File
@@ -31,6 +31,10 @@ a 2.x PWA).
| `/api/write` | POST | Write raw hex data to a file |
| `/api/apdu` | POST | Raw APDU send |
| `/api/verify-adm` | POST | Verify the card's ADM PIN (from the matched card preset) |
| `/api/esim/chip` | GET | eUICC chip details (EID, EUICCInfo1/2, configured addresses) |
| `/api/esim/profiles` | GET | Installed eSIM profiles with their metadata |
| `/api/esim/notifications` | GET | Pending eSIM notifications (read-only) |
| `/api/esim/profile` | POST | Enable/disable an eSIM profile (card re-initialized after the switch) |
| `/api/help` | POST | pySim help for a given command |
| `/api/send-ota` | POST | SCP80 OTA secured packet delivery |
| `/api/ram-install` | POST | Install a Java Card `.cap` file via SCP80 (INSTALL[for load] → LOAD ×N → INSTALL[for install]) |
@@ -162,6 +166,37 @@ On a wrong key (`63Cx`, x attempts left):
A blocked ADM (`6983`/`9804`) reports `{"ok": false, "sw": "9804",
"blocked": true}` and cannot be recovered without the card's unblock key.
### eSIM / LPA (local ES10 operations)
These endpoints work only when the equipped card is an eUICC (SGP.22/32);
otherwise they answer `400` with `{"error": "The equipped card is not an
eUICC"}`. They use pySim's ES10 static API — no lpac, no SM-DP+ contact, no
profile downloads and no notification processing. All run under the card
lock; `GET /api/status` reports `euicc` and `eid` for the PWA.
- `GET /api/esim/chip` — `{"eid": "8904…", "info1": {…}, "info2": {…},
"addresses": {"default_dp_address": …, "root_ds_address": …},
"errors": {"<part>": "<reason>"}}` (a part the card does not support is
reported in `errors` instead of failing the whole request).
- `GET /api/esim/profiles` — `{"profiles": [{"iccid": "8970…",
"isdp_aid": "A000…", "state": "enabled"|"disabled", "nickname": …,
"provider": …, "name": …, "class": "test"|"provisioning"|"operational",
"owner": "250-99", "icon_type": "png"|"jpg"}], "error": null}`.
- `GET /api/esim/notifications` — `{"notifications": [{"seq_number": 3,
"operations": ["enable"], "address": "smdp.example.org",
"iccid": "8970…"}], "error": null}`.
- `POST /api/esim/profile` — `{"action": "enable"|"disable", "iccid"?: …,
"isdp_aid"?: …, "refresh"?: true}` (one identifier required). The card
usually answers with a REFRESH proactive command first (logged in
`/api/proactive-log`); after a successful switch — or whenever a REFRESH
was seen — the server re-initializes the card like an equip (reset,
re-read ICCID/network state, new `card_session`) and returns
`{"ok": true, "result": "ok", "refresh_seen": true, "reinitialized": true,
"iccid": …, "card_session": N}`. Failures carry the ES10c result code
(`iccidOrAidNotFound`, `profileNotInDisabledState`,
`profileNotInEnabledState`, `disallowedByPolicy`, `wrongProfileReenabling`,
`catBusy`, `undefinedError`) and a short `message`.
### `POST /api/help`
Get structured help for a shell command.