From 0d92ea8f24f19db39e2fb486ebdf483cf5989e45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D1=82=D0=BE=D0=BD=20=D0=A2=D1=80=D0=BE=D1=88?= =?UTF-8?q?=D0=B8=D0=BD?= Date: Sat, 19 Sep 2026 22:24:57 +0300 Subject: [PATCH] net-sim: network-condition simulation in the Phone tab (v2.5.0) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Server (pysim_simple_server/netsim.py + POST /api/net-sim): - pure builders for the observed phone write vocabulary (UICC_NAA.md §13): EPSNSC (A0 TLV with KSI/KASME/counts/algo, padded to the card's FCP record size; invalidate-wipe and invalidate-keep-key), LOCI/PSLOCI/EPSLOCI real and dummy forms (PLMN kept, LAC FFFE, status 01/02), Kc/KcGPRS (9-byte USIM and 33-byte GSM forms, 07 invalidates), EF.SMSstatus counter bump (read-modify-write), CBMI/CBMIR, the Location status event (9B 01 , with the optional 13 07 location info for normal service) and the AUTHENTICATE APDU (TS 31.102 7.1.2.1) with DB/DC response parsing - scenario runner executes the recipes under _CARD_LOCK, picks the first existing candidate path (ADF.USIM vs DF.GSM/DF.TELECOM), reads FCP/current records where the format is card-specific, skips the event unless the card subscribed to Location status, honours the scenario toggles and returns a per-step log; only D6/DC, ENVELOPE and AUTHENTICATE are ever sent - GET /api/mcc-mnc serves the optional worldwide operator list (--mcc-mnc-list, default /samples/mcc-mnc-list.json): ?q= search and ?random=1&exclude= for roaming; the list stays out of the repo PWA: - Phone pill gains a 'Network simulation' fieldset: one button per scenario (cold boot, EPS/2G attach, service lost, limited service, roaming denied, churn, SMS received, CB reconfig, AUTHENTICATE), a collapsed Parameters block (operator search + random roaming, LAC/Cell ID/TAC/RAC, optional identities, toggles, churn count/delay) and a step log with SWs - i18n EN/RU, help/README/api.md/AGENTS.md updated; version 2.5.0, SW cache simple-v193 Tests: tests/test_netsim.py (19), frontend/tests/netsim.test.js (3) and html guards - 423 frontend / 280 Python, all passing --- README.md | 2 + README_RUS.md | 2 + docs/api.md | 33 ++ frontend/help-ru.html | 13 + frontend/help.html | 13 + frontend/index.html | 275 ++++++++++++- frontend/style.css | 22 ++ frontend/sw.js | 2 +- frontend/tests/html.test.js | 15 + frontend/tests/netsim.test.js | 86 ++++ pyproject.toml | 2 +- pysim_simple_server/__main__.py | 11 + pysim_simple_server/netsim.py | 670 ++++++++++++++++++++++++++++++++ pysim_simple_server/server.py | 114 +++++- tests/test_netsim.py | 315 +++++++++++++++ 15 files changed, 1571 insertions(+), 4 deletions(-) create mode 100644 frontend/tests/netsim.test.js create mode 100644 pysim_simple_server/netsim.py create mode 100644 tests/test_netsim.py diff --git a/README.md b/README.md index a4cf1c0..b472cfa 100644 --- a/README.md +++ b/README.md @@ -595,6 +595,8 @@ The **Phone simulator** tab provides real-time CAT session interaction. It has t Values persist on the server until restart. Apply → hex updates; Save → POSTs to server. The server will use these values to populate TERMINAL RESPONSE data for future PLI proactive commands. +**Network simulation** — replays the card-facing write patterns of a real phone on network-condition changes (trace study: `projects/UICC_NAA.md`): **Cold boot**, **EPS attach**, **2G attach**, **Service lost**, **Limited service**, **Roaming denied**, **Churn**, **SMS received**, **CB reconfig** and **AUTHENTICATE**. Each scenario sends the Location status event (only when the card subscribed to it), updates the EPS NAS context, location files, Kc and CB/SMS files exactly as observed, and logs every step with its SW. Parameters (collapsed) cover the operator (searchable worldwide MCC/MNC list served by the server, plus a random roaming picker), LAC/Cell ID/TAC/RAC, optional identity values (empty = random: TMSI, GUTI, KSI, KASME, Kc, NAS counts, algorithm, RAND/AUTN), scenario toggles and the churn count/delay. Only UPDATE BINARY/RECORD, ENVELOPE and AUTHENTICATE are sent; FPLMN and 5GS location files are never touched. The operator list comes from `--mcc-mnc-list` (default `/samples/mcc-mnc-list.json`). + ## SCP81 The **SCP81** tab drives HTTP OTA (GP RAM over HTTP, GPC v2.2 Amendment B) and has two pills: **Listener** and **Scripts**. diff --git a/README_RUS.md b/README_RUS.md index 2e800e6..3309c84 100644 --- a/README_RUS.md +++ b/README_RUS.md @@ -565,6 +565,8 @@ Delivery PoR (SPI2 `01`) проще — карта возвращает PoR на Значения сохраняются на сервере до перезапуска. Apply → hex обновляется; Save → POST на сервер. +**Симуляция сети** — воспроизводит шаблоны записи реального телефона при смене сетевых условий (исследование трасс: `projects/UICC_NAA.md`): **Холодная загрузка**, **Подключение EPS**, **Подключение 2G**, **Потеря сервиса**, **Ограниченный сервис**, **Роуминг запрещён**, **Серия переподключений**, **Принято SMS**, **Перенастройка CB** и **AUTHENTICATE**. Каждый сценарий отправляет событие Location status (только если карта на него подписана), обновляет контекст EPS NAS, location-файлы, Kc и файлы CB/SMS в точности как в трассах и журналирует каждый шаг с его SW. Параметры (свёрнуты) задают оператора (поиск по мировому списку MCC/MNC с сервера плюс случайный роуминг-оператор), LAC/Cell ID/TAC/RAC, необязательные идентификаторы (пусто = случайно: TMSI, GUTI, KSI, KASME, Kc, счётчики NAS, алгоритм, RAND/AUTN), переключатели и число циклов/задержку. Отправляются только UPDATE BINARY/RECORD, ENVELOPE и AUTHENTICATE; FPLMN и 5GS location-файлы не затрагиваются. Список операторов задаётся `--mcc-mnc-list` (по умолчанию `/samples/mcc-mnc-list.json`). + ## SCP81 Вкладка **SCP81** управляет HTTP OTA (GP RAM over HTTP, GPC v2.2 Amendment B) и содержит две подвкладки: **Listener** и **Scripts**. diff --git a/docs/api.md b/docs/api.md index e857e25..2a62547 100644 --- a/docs/api.md +++ b/docs/api.md @@ -40,6 +40,8 @@ a 2.x PWA). | `/api/stk-status` | GET | STK session state (active/pending/type) | | `/api/events` | GET | Event list from SET UP EVENT LIST | | `/api/event-send` | POST | Send ENVELOPE(Event Download) | +| `/api/net-sim` | POST | Run a network-condition scenario (attach, service loss, roaming, churn, 2G, SMS, CB, AUTHENTICATE) | +| `/api/mcc-mnc` | GET | Search the optional MCC/MNC operator list (`?q=`; `?random=1&exclude=`) | | `/api/proactive-log` | GET | Last 50 proactive commands | | `/api/status-poll` | POST | Manual STATUS poll + FETCH if 91XX | | `/api/rescue` | POST | Re-send TERMINAL PROFILE to recover CAT session | @@ -95,6 +97,15 @@ Runs pySim's `cardinfo` command and returns its output as `{"output": "..."}` (card type, ATR, ICCID and other information pySim reports for the equipped card). A shortcut for `POST /api/command` with `{"cmd": "cardinfo"}`. +### `GET /api/mcc-mnc` + +Searches the optional worldwide operator list loaded from +`--mcc-mnc-list` (default `/samples/mcc-mnc-list.json`). +`?q=` matches country, country code, MCC/MNC, brand and operator +(compact results, max 50); `?random=1[&exclude=MCCMNC]` returns one random +entry (for roaming tests). When the list is not configured or missing the +response is `{"available": false}`. + ### `POST /api/command` Execute any pysim-shell command. @@ -405,6 +416,28 @@ event byte values, or `[]` when none was received). Sends an `ENVELOPE(Event Download)` for a subscribed event. +### `POST /api/net-sim` + +Runs one network-condition scenario from `projects/UICC_NAA.md` section 13 +against the equipped card and returns the step log: + +```json +{"scenario": "service_lost", "mcc": "262", "mnc": "01", "lac": "6CD7", + "send_event": true, "dummy_locations": true, "keep_kasme": true} +``` + +Scenarios: `cold_boot`, `attach_eps`, `attach_2g`, `service_lost`, +`limited_service`, `roaming_denied`, `churn`, `sms_received`, `cb_reconfig`, +`authenticate`. Optional parameters: `mcc`/`mnc` (or `plmn`), `lac`, +`cell_id`, `tac`, `rac`, `tmsi`, `ptmsi`, `ptmsi_sig`, `guti`, `ksi`, +`kasme`, `ul`, `dl`, `algo`, `kc`, `rand`, `autn`, `churn_count`, +`churn_delay_ms`, and the toggles `send_event`, `dummy_locations`, +`invalidate_epsnsc`, `keep_kasme`, `write_kc`, `sms_location`, `cb_clear` +(empty identity values are randomized). The event step is skipped when the +card did not subscribe to Location status; only UPDATE BINARY/RECORD, +ENVELOPE and AUTHENTICATE are sent (never FPLMN/5GS location files). The +response is `{success, error, steps:[{action, file, path, data, sw, ok}]}`. + ```json {"event_type": 4, "event_data": "01A0"} ``` diff --git a/frontend/help-ru.html b/frontend/help-ru.html index 1ac607e..5dcd539 100644 --- a/frontend/help-ru.html +++ b/frontend/help-ru.html @@ -474,6 +474,19 @@

Значения хранятся на сервере до перезапуска. Когда карта выдаёт PLI, сервер вставляет значения словаря в TERMINAL RESPONSE.

+

8.7 Симуляция сети

+

Воспроизводит шаблоны записи реального телефона при смене сетевых условий (исследование трасс в projects/UICC_NAA.md): подключение EPS, потеря сервиса / ограниченный сервис, запрет роуминга, откат на 2G, приём SMS, перенастройка cell broadcast и AUTHENTICATE. По кнопке на сценарий; карта должна быть подключена.

+
    +
  • Холодная загрузка — инвалидация EPSNSC (KSI 07, ключ стирается) и фиктивные location-файлы.
  • +
  • Подключение EPS / 2G — запись реального контекста EPS NAS (KSI, KASME, счётчики NAS, алгоритм) и реальных LOCI/PSLOCI/EPSLOCI (в 2G дополнительно реальные Kc/KcGPRS).
  • +
  • Потеря сервиса / ограниченный сервис / запрет роуминга — событие Location status (только если карта на него подписана), инвалидация EPSNSC (по желанию с сохранением старого KASME), фиктивные location-файлы (PLMN сохраняется, LAC FFFE, статус 01/02) и инвалидация Kc.
  • +
  • Серия переподключений — реальная → невалидная запись EPSNSC подряд (число циклов и задержка настраиваются).
  • +
  • Принято SMS — инкремент счётчика EF.SMSstatus (чтение-изменение-запись) и, по желанию, перезапись location-файлов.
  • +
  • Перенастройка CB — запись списков CBMI/CBMIR или их очистка (все FF).
  • +
  • AUTHENTICATE — команда AUTHENTICATE (3G/EPS/5G, 00 88 00 81 22) с заданными или случайными RAND/AUTN и показ ответа (успех DB или ошибка синхронизации DC с AUTS).
  • +
+

Параметры (свёрнуты) задают оператора (поиск по мировому списку MCC/MNC с сервера плюс выбор случайного роуминг-оператора), LAC/Cell ID/TAC/RAC, необязательные идентификаторы (пусто = случайно: TMSI, GUTI, KSI, KASME, Kc, счётчики NAS, алгоритм, RAND/AUTN), переключатели сценария и число циклов/задержку. Журнал шагов показывает каждую запись, ENVELOPE и AUTHENTICATE с их SW. Отправляются только UPDATE BINARY/RECORD, ENVELOPE и AUTHENTICATE — FPLMN и 5GS location-файлы никогда не записываются (ни один наблюдаемый телефон этого не делает); записи меняют карту и видны в последующих сравнениях снимков.

+
diff --git a/frontend/help.html b/frontend/help.html index 690970c..5ebb645 100644 --- a/frontend/help.html +++ b/frontend/help.html @@ -474,6 +474,19 @@

Values persist server-side until restart. When the card issues PLI, the server injects the dictionary values into the TERMINAL RESPONSE.

+

8.7 Network simulation

+

Replays the write patterns a real phone performs when the network condition changes (trace study in projects/UICC_NAA.md): EPS attach, service loss / limited service, roaming denial, 2G fallback, SMS delivery, cell-broadcast reconfiguration and AUTHENTICATE. One button per scenario; the card must be equipped.

+
    +
  • Cold boot — invalidate EPSNSC (KSI 07, key wiped) and dummy the location files.
  • +
  • EPS attach / 2G attach — store a real EPS NAS context (KSI, KASME, NAS counts, algorithm) and write real LOCI/PSLOCI/EPSLOCI (2G also writes real Kc/KcGPRS).
  • +
  • Service lost / Limited service / Roaming denied — send the Location status event (only when the card subscribed to it), invalidate EPSNSC (optionally keeping the old KASME), dummy the location files (PLMN kept, LAC FFFE, status 01/02) and invalidate Kc.
  • +
  • Churn — replay real → invalid EPSNSC records back-to-back (count and delay configurable).
  • +
  • SMS received — bump the EF.SMSstatus counter (read-modify-write) and optionally rewrite the location files.
  • +
  • CB reconfig — write the CBMI/CBMIR message-ID lists or clear them (all FF).
  • +
  • AUTHENTICATE — send AUTHENTICATE (3G/EPS/5G, 00 88 00 81 22) with the given or random RAND/AUTN and show the response (success DB or synchronisation failure DC with AUTS).
  • +
+

Parameters (collapsed) provide the operator (searchable worldwide MCC/MNC list served from the server, plus a random roaming picker), LAC/Cell ID/TAC/RAC, optional identity values (empty = random: TMSI, GUTI, KSI, KASME, Kc, NAS counts, algorithm, RAND/AUTN), the scenario toggles and the churn count/delay. The step log lists every write, ENVELOPE and AUTHENTICATE with its SW. Only UPDATE BINARY/RECORD, ENVELOPE and AUTHENTICATE are sent — FPLMN and 5GS location files are never written (no observed phone does); the writes change the card and are visible to later snapshot comparisons.

+
diff --git a/frontend/index.html b/frontend/index.html index 875d2f9..9e8e987 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -943,6 +943,93 @@ Fetched proactive commands:
+
+ Network simulation +
Replays the write patterns a real phone performs on network-condition changes (EPS attach, service loss, roaming denial, 2G fallback, SMS delivery, cell-broadcast reconfiguration, AUTHENTICATE) - see projects/UICC_NAA.md. Only UPDATE BINARY/RECORD, ENVELOPE and AUTHENTICATE are sent; FPLMN and 5GS location files are never touched.
+
+ + + + + + + + + + +
+
+ Parameters +
+
+
+ + +
+
+ + +
+
+ + +
+ +
+
+
+
+ + +
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ +
+
+ Advanced identity (empty = random) +
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + + + + + + + + +
+
+
+
+
+