9363f209ee
- Phone pill: STK menu, STATUS and polling and the subscribed-events list
in one row, proactive command log full-width below (room for more
elements)
- TR Config pill: response data injected into TERMINAL RESPONSEs;
currently the PROVIDE LOCAL INFORMATION dictionary, structured as
heading + body blocks for future proactive-command responses
- phoneSwitchSubtab() mirrors the other sub-tab switchers and sets help
anchors stk-menu / pli-dict; switchTab('phone') always opens Phone
- refreshDynamicI18n renders only the visible phone panel
- help EN/RU section 6 regrouped (6.4 STATUS polling under Phone, 6.5
TR Config response data), READMEs and AGENTS.md updated
- structural and behavioral tests (html.test.js, phone_tabs.test.js);
SW cache v93 -> v94
629 lines
38 KiB
Markdown
629 lines
38 KiB
Markdown
# OTAMan — SIM OTA toolkit: PWA + локальный сервер карт
|
||
|
||
OTAMan — автономный offline-PWA (HTML/JS) для создания APDU-команд (SIM, USIM, GlobalPlatform RAM), сборки защищённых пакетов SCP80 по ETSI TS 102 225 и построения Expanded Remote Application data format APDU по ETSI TS 102 226. В комплекте — [`pysim-otaman-server`](pysim_otaman_server/) — локальный HTTP-сервер поверх pySim для работы с картой: файловый менеджер, сырые APDU, меню SIM Toolkit и доставка OTA.
|
||
|
||
**Демо:** [otaman.atroshin.ru](https://otaman.atroshin.ru) — только PWA, для экспериментов. Для функций картридера установите сервер (ниже).
|
||
|
||
## Быстрый старт
|
||
|
||
**Только PWA (клиентские функции):** откройте `frontend/index.html` в любом браузере или раздайте `frontend/` любым статическим сервером. Python не нужен.
|
||
|
||
**Полная установка (PWA + сервер карт):**
|
||
|
||
```sh
|
||
git clone https://github.com/anttro/otaman.git
|
||
cd otaman
|
||
./setup.sh # или setup.bat в Windows — создаёт .venv, ставит pysim + сервер
|
||
./start.sh # или start.bat — запускает сервер (он же раздаёт PWA)
|
||
```
|
||
|
||
Затем откройте http://127.0.0.1:8080 — интерфейс и API на одном origin, поэтому CORS и разрешения браузера не нужны.
|
||
|
||
## Сборка
|
||
|
||
Для стилей используется Tailwind CSS. После клонирования пересоберите CSS:
|
||
|
||
```sh
|
||
cd frontend
|
||
npm install
|
||
npm run build
|
||
```
|
||
|
||
## Интерфейс
|
||
|
||
Пять вкладок: **Remote APDU**, **SCP80**, **Card reader**, **Profiler** и **Phone simulator**. Вкладки Remote APDU и SCP80 используют пиллы-подвкладки; во вкладке Card reader четыре подвкладки: **File manager**, **Custom files**, **pySim command line** и **Raw APDU**.
|
||
|
||
---
|
||
|
||
## Вкладка Remote APDU
|
||
|
||
Построение команд APDU (C-APDU). Семь подвкладок для разных поколений карт, наборов команд и инструментов разбора: **SIM RFM**, **USIM RFM**, **Expanded Script**, **RAM/GP**, **HTTP OTA**, **Разбор C-APDU** и **«Парсер ответов»**.
|
||
|
||
### SIM RFM
|
||
|
||
CLA = `A0` (GSM 11.11 / ISO 7816-4).
|
||
|
||
#### Команды
|
||
|
||
| Команда | INS | Описание |
|
||
|---|---|---|
|
||
| SELECT | A4 | Выбор EF/DF по FID, пути, dfname или цепочке |
|
||
| UPDATE RECORD | DC | Обновление записи |
|
||
| UPDATE BINARY | D6 | Обновление бинарных данных |
|
||
| READ RECORD | B2 | Чтение записи |
|
||
| READ BINARY | B0 | Чтение бинарных данных |
|
||
| ERASE BINARY | 0E | Стирание бинарных данных |
|
||
| ACTIVATE FILE | 44 | Активация файла |
|
||
| DEACTIVATE FILE | 04 | Деактивация файла |
|
||
| VERIFY PIN | 20 | Проверка PIN1 или PIN2 |
|
||
| CHANGE PIN | 24 | Смена PIN1 или PIN2 |
|
||
|
||
#### Методы SELECT
|
||
|
||
| Метод | P1 | P2 | Ввод |
|
||
|---|---|---|---|
|
||
| By FID | 00 | 00 | FID (4 hex) |
|
||
| By full path from MF | 08 | 00 | Полный путь от MF |
|
||
| By DF name / AID | 04 | 00 | AID |
|
||
| ADF RFM chain | 00 | 00 | FID через запятую |
|
||
|
||
#### Опции
|
||
|
||
- **Start with SELECT** — добавить SELECT перед командой.
|
||
- **Selection mode (P2)** — для record-команд: Absolute (04), Next (06), Previous (02).
|
||
- **Record size** — дополнить/обрезать данные до указанного размера.
|
||
- **Allow P1/P2 editing** — ручное редактирование P1/P2.
|
||
|
||
#### Ссылки
|
||
|
||
- ISO/IEC 7816-4: Organization, security and commands for interchange
|
||
- ETSI TS 102 226: Remote APDU structure for UICC based applications
|
||
- GSM 11.11: SIM-ME Interface
|
||
|
||
### USIM RFM
|
||
|
||
CLA = `00` (ETSI TS 102 221). Те же команды, что и SIM, но SELECT использует P1=09, P2=0C.
|
||
|
||
#### Ссылки
|
||
|
||
- ETSI TS 102 221: UICC-Terminal Interface
|
||
- ETSI TS 102 226: Remote APDU structure
|
||
|
||
### Expanded Script
|
||
|
||
Построение Expanded Remote Application data format по ETSI TS 102 226 §5.2.1.
|
||
|
||
#### Формат
|
||
|
||
- **Definite (AA)**: `AA` + длина + Command TLV
|
||
- **Indefinite (AE)**: `AE` + `80` + Command TLV + `00 00`
|
||
|
||
#### Command TLV
|
||
|
||
| Тип | Тег | Описание |
|
||
|---|---|---|
|
||
| C-APDU | 22 | APDU |
|
||
| Immediate Action | 81 | Proactive-команда или action indicator |
|
||
| Error Action | 82 | Proactive-команда при ошибке |
|
||
| Script Chaining | 83 | Данные для многопакетных скриптов |
|
||
|
||
#### Сборщик Immediate Action
|
||
|
||
- **Action indicator**: `81` / `82`
|
||
- **Proactive command**: REFRESH, DISPLAY TEXT, PLAY TONE
|
||
- **Custom hex**: ручной ввод
|
||
|
||
#### Ссылки
|
||
|
||
- ETSI TS 102 226 §5.2.1
|
||
- ETSI TS 102 223: Card Application Toolkit
|
||
- ETSI TS 101 220: BER-TLV tag assignments
|
||
|
||
### RAM/GP
|
||
|
||
CLA = `80` (GlobalPlatform v2.3.1). Удалённое управление содержимым карты через SCP80.
|
||
|
||
#### Справочник GP-команд
|
||
|
||
| Команда | INS | P1 | Описание |
|
||
|---|---|---|---|
|
||
| INSTALL [for load] | E6 | 02 | Регистрация загружаемого файла |
|
||
| INSTALL [for install] | E6 | 0C | Установка приложения или SD |
|
||
| INSTALL [for make selectable] | E6 | 10 | Сделать приложение выбираемым |
|
||
| INSTALL [for registry update] | E6 | 01 | Обновление реестра |
|
||
| INSTALL [for extradition] | E6 | 04 | Перемещение между SD |
|
||
| LOAD | E8 | 00 | Загрузка кода |
|
||
| DELETE | E4 | 00/80 | Удаление приложения или SD |
|
||
| GET STATUS | F2 | 80/40/20/10 | Статус карты |
|
||
| GET DATA | CA | tag | Чтение объектов данных |
|
||
| STORE DATA | E2 | 00/40/80/C0 | Запись данных |
|
||
| SET STATUS | F0 | 80/40/60 | Управление жизненным циклом |
|
||
| EXTERNAL AUTHENTICATE | 82 | 00 | Аутентификация SCP |
|
||
| INTERNAL AUTHENTICATE | 88 | 00 | Challenge-response |
|
||
|
||
#### Привилегии (INSTALL [for install])
|
||
|
||
Три байта привилегий по GP Spec Tables 11-7, 11-8, 11-9.
|
||
|
||
**Байт 1:**
|
||
| Бит | Привилегия |
|
||
|---|---|
|
||
| b8 | Security Domain |
|
||
| b7 | DAP Verification |
|
||
| b6 | Delegated Management |
|
||
| b5 | Card Lock |
|
||
| b4 | Card Terminate |
|
||
| b3 | Card Reset |
|
||
| b2 | CVM Management |
|
||
|
||
**Байт 2:**
|
||
| Бит | Привилегия |
|
||
|---|---|
|
||
| b8 | Trusted Path |
|
||
| b7 | Authorized Management |
|
||
| b6 | Token Verification |
|
||
| b5 | Global Delete |
|
||
| b4 | Global Lock |
|
||
| b3 | Global Registry |
|
||
| b2 | Final Application |
|
||
|
||
**Байт 3:**
|
||
| Бит | Привилегия |
|
||
|---|---|
|
||
| b8 | Receipt Generation |
|
||
|
||
#### Параметры SIM/UICC Toolkit
|
||
|
||
- **Tag `CA`** (SIM Toolkit): Priority, Timers, Text Length, Menu Entries, Positions, Channels, MSL, TAR, Access Domain
|
||
- **Tag `80`** (UICC Toolkit, внутри `EA`): те же поля без Access Domain
|
||
|
||
**MSL (Minimum Security Level):**
|
||
| Значение | Описание |
|
||
|---|---|
|
||
| 00 | Нет проверки |
|
||
| 11 | RC/CC/DS |
|
||
| 12 | RC/DS/CC |
|
||
| 15 | RC/DS/CC + MAC |
|
||
| 16 | RC/DS/CC + MAC + Cipher |
|
||
| 19 | RC/DS/CC + MAC + Cipher + DS |
|
||
|
||
#### GET STATUS P1
|
||
|
||
| Значение | Описание |
|
||
|---|---|
|
||
| 80 | Issuer Security Domain (ISD) |
|
||
| 40 | Applications и SSD |
|
||
| 20 | Executable Load Files |
|
||
| 10 | ELF и модули |
|
||
|
||
#### GET STATUS P2
|
||
|
||
| Значение | Описание |
|
||
|---|---|
|
||
| 40 | Первые/все, GP TLV (по умолчанию) |
|
||
| 42 | Следующие, GP TLV |
|
||
| 00 | Первые/все, старый формат (deprecated) |
|
||
| 02 | Следующие, старый формат (deprecated) |
|
||
|
||
#### GET DATA теги
|
||
|
||
| Тег | Объект данных |
|
||
|---|---|
|
||
| 42 | Issuer Identification Number (IIN) |
|
||
| 45 | Card Image Number (CIN) |
|
||
| 66 | Card Data / SD Management Data |
|
||
| 67 | Card Capability Information |
|
||
| E0 | Key Information Template |
|
||
| D3 | Current Security Level |
|
||
| 2F00 | List of Applications |
|
||
| FF21 | Extended Card Resources Info |
|
||
| 5F50 | SD Manager URL |
|
||
| C1 | Sequence Counter (SCP02/03) |
|
||
| C2 | Confirmation Counter |
|
||
| 7F21 | Certificate (SD public key) |
|
||
| 5031 | Certificate info (EF.OD) |
|
||
|
||
#### DELETE P1
|
||
|
||
| Значение | Описание |
|
||
|---|---|
|
||
| 00 | Только AID |
|
||
| 80 | AID и связанные объекты |
|
||
|
||
#### STORE DATA P1
|
||
|
||
| Значение | Описание |
|
||
|---|---|
|
||
| 00 | Последний блок, без шифрования |
|
||
| 40 | Ещё блоки, без шифрования |
|
||
| 80 | Последний блок, с шифрованием |
|
||
| C0 | Ещё блоки, с шифрованием |
|
||
|
||
#### SET STATUS
|
||
|
||
**P1:** 80 = ISD, 40 = Приложение или SSD, 60 = SD и его приложения
|
||
|
||
**P2:** 00 = Разблокировать, 80 = Заблокировать (LOCKED)
|
||
|
||
#### Ссылки
|
||
|
||
- GlobalPlatform Card Specification v2.3.1
|
||
- ETSI TS 102 226 §8.2.1.3.2: Параметры SIM/UICC Toolkit
|
||
|
||
### Конвертация (боковые панели SIM/USIM)
|
||
|
||
#### IMSI → EF.IMSI
|
||
|
||
15-значный IMSI → 9 байт EF.IMSI.
|
||
|
||
#### MSISDN → BCD
|
||
|
||
Удаление `+`, добавление `f`, обмен полубайтов.
|
||
|
||
#### ICCID → hex
|
||
|
||
Обмен полубайтов строки ICCID.
|
||
|
||
#### Provider Name → SPN
|
||
|
||
По 3GPP TS 31.102 §4.2.5. Три варианта кодирования:
|
||
1. GSM 7-bit packed
|
||
2. UCS2 non-BMP
|
||
3. UCS2 BMP non-GSM7
|
||
|
||
#### PLMN → EF_PLMNsel / PLMNwAcT
|
||
|
||
3-байтное BCD-кодирование + опциональный Access Technology.
|
||
|
||
#### Nibble swap
|
||
|
||
Обмен полубайтов hex-строки.
|
||
|
||
#### Ссылки
|
||
|
||
- 3GPP TS 31.102
|
||
- 3GPP TS 23.038
|
||
- ETSI TS 102 225
|
||
- pySim: enc_imsi()
|
||
|
||
### Разбор C-APDU
|
||
|
||
Вставьте сырой hex APDU — отобразится раскрывающееся дерево. Контейнер определяется автоматически: **Expanded Script** (ведущие `AA` или `AE80`, разбор по ETSI TS 102 226 §5.2.1) или **компактная цепочка C-APDU** (последовательность ISO 7816 C-APDU). У каждого узла — метка, hex и краткое описание; родительские узлы раскрываются до подэлементов.
|
||
|
||
### HTTP OTA
|
||
|
||
Сборка payload-ов Remote Application Management over HTTP по GlobalPlatform **GPC v2.2 Amendment B v1.1** (§4.7). Два режима:
|
||
|
||
- **Trigger (Push SMS)** — параметры запуска административной сессии (`81 > 83 > 84/[85]/[86]/89`, Table 4-3). Это сообщение просит Security Domain карты выйти в сеть и начать HTTP-сессию.
|
||
- **Store (SD admin params)** — запись тех же параметров как данных карты (Security Domain) через **STORE DATA в TLV-режиме** (`80 E2 90 00`, P1=90 = последний блок + BER-TLV по GP v2.2 Amendment B v1.1.3), обёрнутых в тег `85` (или `A5`) по Table 4-4.
|
||
|
||
| Секция | Тег | Содержимое |
|
||
|---|---|---|
|
||
| Параметры соединения | `84` | COMPREHENSION-TLV для открытия TCP-соединения (OPEN CHANNEL по TS 102 223): Device Identities `02`, Alpha `80`, Bearer `01`, вендорские TLV. Редактор строк + пресеты, редактируемый hex. |
|
||
| Параметры безопасности | `85` | Table 4-6: LV PSK Identity (текст), LV Key version/KID. Идентифицирует ключ PSK TLS (RFC 4279). |
|
||
| Политика повторов | `86` | Table 4-7: счётчик повторов (2 байта, напр. `B000`), задержка повтора как timer TLV TS 102 223 (`25 03 HH MM SS`), опциональный вендорский TLV отчёта об ошибке. |
|
||
| HTTP POST | `89` | Tables 4-8/9/10: заголовок Host (`8A`), X-Admin-From agent ID (`8B`), URI (`8C`) — текст преобразуется в октеты. |
|
||
|
||
Чекбокс **Command Scripting template** оборачивает всю команду `81` в формат Expanded Remote Application с определённой длиной (`AA`, ETSI TS 102 226 §5.2.1) для TAR, обрабатывающих расширенный формат. **Pack into Secured packet** отправляет собранный payload на вкладку SCP80 для заполнения SPI/счётчика — укажите там TAR, который слушает SD (обычно OTASD).
|
||
|
||
---
|
||
|
||
|
||
### Парсер ответов
|
||
|
||
Декодирование ответа команды: выберите отправленную команду, введите SW (например, `9000`) и данные ответа в hex, затем нажмите **Decode**.
|
||
|
||
- **Команда** — группа SIM/USIM (SELECT, STATUS, READ/UPDATE, операции с PIN, CAT-команды TERMINAL PROFILE/ENVELOPE/FETCH/TERMINAL RESPONSE, MANAGE CHANNEL, ...) или группа RAM/GP (INSTALL, LOAD, DELETE, GET/STORE DATA, аутентификация, команды SCP).
|
||
- **Декодирование SW** — статусные слова по картам generic, UICC (TS 102 221) и GlobalPlatform с автоопределением контекста.
|
||
- **Декодирование привилегий** — байты привилегий из ответов GET DATA / INSTALL в читаемые флаги.
|
||
- **Данные ответа** — hex с интерпретацией по команде (например, шаблоны FCP из SELECT).
|
||
|
||
---
|
||
|
||
|
||
## Вкладка SCP80
|
||
|
||
Вкладка **SCP80** группирует SCP80-виды, переключаемые тремя пиллами: **Secured Packet**, **Cards** и **RAM**. Сборка защищённых пакетов по ETSI TS 102 225.
|
||
|
||
### Secured Packet
|
||
|
||
Сборка защищённых пакетов SCP80 по ETSI TS 102 225.
|
||
|
||
#### Структура пакета
|
||
|
||
| Поле | Размер | Описание |
|
||
|---|---|---|
|
||
| CPI | 1 | Command Packet Identifier (`02`) |
|
||
| CPL | 1 | Command Packet Length |
|
||
| CHI | 1 | Command Header Identifier (`01`) |
|
||
| CHL | 1 | Command Header Length |
|
||
| SPI | 2 | Security Parameter Indicator |
|
||
| KIc | 1 | Key Identifier для шифрования |
|
||
| KID | 1 | Key Identifier для MAC |
|
||
| TAR | 3 | Toolkit Application Reference |
|
||
| CNTR | 5 | Счётчик повторов |
|
||
| PCNTR | 1 | Padding counter |
|
||
| RC/CC/DS | 8 | Контрольная сумма / MAC |
|
||
| Secured Data | переменная | APDU (с шифрованием при необходимости) |
|
||
|
||
#### SPI1 (Уровень безопасности)
|
||
|
||
Битовое поле SPI1 (TS 102 225 §5.1.1): `b8–b6` — паддинг, `b5–b4` — счётчик, `b3` — шифрование, `b2–b1` — RC/CC/DS.
|
||
|
||
| Значение | Безопасность | Шифрование | Счётчик (b5 b4) |
|
||
|---|---|---|---|
|
||
| 00 | Нет | Нет | 00 нет |
|
||
| 01 | RC | Нет | 00 нет |
|
||
| 02 | CC/MAC | Нет | 00 нет |
|
||
| 06 | CC/MAC | Да | 00 нет |
|
||
| 0A | CC/MAC | Нет | 01 available |
|
||
| 0E | CC/MAC | Да | 01 available |
|
||
| 12 | CC/MAC | Нет | 10 higher |
|
||
| 16 | CC/MAC | Да | 10 higher |
|
||
| 1A | CC/MAC | Нет | 11 +1 |
|
||
| 1E | CC/MAC | Да | 11 +1 |
|
||
|
||
> **AES требует `b5 b4 = 10` (higher) или `11` (+1)** согласно TS 102 225 §5.1.2 и §5.1.3.1.
|
||
> Значения `00/01/02/06` (без счётчика) допустимы только для 3DES.
|
||
|
||
#### SPI2 (PoR)
|
||
|
||
| Значение | Режим |
|
||
|---|---|
|
||
| 00 | No PoR |
|
||
| 01 | PoR required, no security |
|
||
| 05 | PoR required, RC |
|
||
| 09 | PoR required, CC |
|
||
| 0D | PoR required, DS |
|
||
| 11 | PoR required, ciphered |
|
||
| 02 | PoR on error, no security |
|
||
| 06 | PoR on error, RC |
|
||
|
||
#### Крипто
|
||
|
||
- **3DES-CBC** шифрование, ключи 8/16/24 байт — устарело с Rel-18, но поддерживается для обратной совместимости
|
||
- **AES-CBC** шифрование (нулевой ICV, дополнение нулями до 16), ключи 16/24/32 байта (TS 102 225 §5.1.2, KIc `x2`)
|
||
- **Retail MAC** (ISO 9797-1 MAC algorithm 3) для DES/3DES
|
||
- **AES-CMAC** (NIST SP 800-38B, усечённый до 8 октетов) для AES (TS 102 225 §5.1.3.1, KID `x2`)
|
||
- Padding byte: `00` (по умолчанию) или `FF`
|
||
|
||
#### PoR (Proof of Reception)
|
||
|
||
PoR подтверждает, что карта получила и выполнила защищённый пакет. Два режима:
|
||
|
||
| SPI2 (бит 5) | Режим | Описание |
|
||
|---|---|---|
|
||
| `0x00` | Delivery PoR | PoR возвращается в ответе ENVELOPE (SW+данные) |
|
||
| `0x20` | Submit PoR | PoR отправляется обратно как SMS-SUBMIT через прокоманду FETCH |
|
||
|
||
Delivery PoR (SPI2 `01`) проще — карта возвращает PoR напрямую в ответе ENVELOPE. Submit PoR (SPI2 `21`) используется, когда карта не может ответить inline (ограничено пространство ответа ENVELOPE).
|
||
|
||
#### Ссылки
|
||
|
||
- ETSI TS 102 225 V18.1.0
|
||
- ETSI TS 102 226
|
||
- ISO 9797-1
|
||
- NIST SP 800-38B (CMAC)
|
||
|
||
### Cards
|
||
|
||
Пилл **Cards** управляет сохранёнными конфигурациями карт (пресеты). Каждый пресет хранит криптографические ключи, настройки TAR и счётчик повторов для SCP80-операций.
|
||
|
||
| Поле | Описание |
|
||
|---|---|
|
||
| SPI1 / SPI2 | Уровень безопасности и настройки PoR |
|
||
| Ключ KIc / KID | Hex ключи шифрования и MAC |
|
||
| Индекс KIc / KID | Номер версии ключа |
|
||
| TAR | Toolkit Application Reference (3 байта) |
|
||
| Счётчик (CNTR) | 10-значный hex счётчик повторов, автоматически увеличивается после каждой успешной отправки SCP80 |
|
||
|
||
**Добавить карту:** заполните имя, SPI1/SPI2, ключи KIc/KID и их индексы, TAR, нажмите **Add**. Карта появится в списке и станет доступна в выпаданом списке **Card preset** на RAM-вкладке.
|
||
|
||
**Редактировать карту:** выберите карту в списке, измените поля, нажмите **Save**.
|
||
|
||
**Удалить карту:** выберите карту, нажмите **Delete**. Удаляет пресет из `localStorage`.
|
||
|
||
**Счётчик:** 10-значный hex-счётчик (CNTR) автоматически увеличивается после каждой успешной отправки SCP80 (ручные отправки Secured Packet и RAM-операции). Обновлённый счётчик автоматически сохраняется обратно в пресет.
|
||
|
||
### RAM
|
||
|
||
Все операции RAM отправляются как защищённые пакеты SCP80 (ETSI TS 102 225) через SMS-PP-DOWNLOAD ENVELOPE. Карта должна поддерживать SCP03 (AES или 3DES) для безопасной транспортировки.
|
||
|
||
Выберите сохранённую конфигурацию карты из выпадающего списка **Card preset**. Если пресет не выбран, RAM-вкладка предупреждает и отказывается выполнять.
|
||
|
||
В RAM-подвкладке доступны две операции через выпадающий список **Operation**:
|
||
|
||
| Операция | Описание |
|
||
|---|---|
|
||
| **Explore Card (all GP data)** | Запрос GET STATUS для ISD, приложений, ELF и модулей ELF, а также GET DATA FF21 для информации о памяти. Результаты отображаются в обзоре с кнопками **Delete** для каждого элемента. |
|
||
| **Install Package (.cap file)** | Отправка `.cap` файла на карту через сервер: INSTALL\[for load\] → LOAD ×N → INSTALL\[for install (+make selectable)\]. |
|
||
|
||
#### Обзор карты (Explorer View)
|
||
|
||
После выполнения "Explore Card" отображается:
|
||
|
||
- **ISD** — AID, жизненный цикл, привилегии (без удаления; ISD нельзя удалить)
|
||
- **Приложения** — AID, жизненный цикл, привилегии, связанный ELF/SD. Каждое имеет кнопку **Delete** (GP `DELETE` по AID).
|
||
- **Executable Load Files** — AID, жизненный цикл, версии, AID модулей. Каждый имеет **Delete** (только ELF) и **Delete All** (каскадное: ELF + модули + установленные приложения, P2=0x80).
|
||
|
||
Удаление подтверждается через диалог браузера перед отправкой команды GP `DELETE` через SCP80. Обзор автоматически обновляется после успешного удаления.
|
||
|
||
---
|
||
|
||
## Card Reader (интеграция с pySim)
|
||
|
||
Подключение к встроенному [`pysim-otaman-server`](pysim_otaman_server/) для работы с картой.
|
||
|
||
> **Ограничение браузера:** если PWA раздаётся с публичного HTTPS-хоста, для доступа к локальному серверу (`http://127.0.0.1:8080`) нужны два условия: сервер должен отправлять `Access-Control-Allow-Private-Network: true` (pysim-otaman-server ≥ 1.6.1 делает это автоматически), и браузеру должно быть разрешено обращаться к локальной сети — в Chrome/Edge/Vivaldi: Настройки сайта → Доступ к локальной сети → разрешить сайт (или подтвердить запрос). Без разрешения браузера запрос к `127.0.0.1` блокируется ещё до отправки preflight.
|
||
|
||
### Файловый менеджер
|
||
|
||
Дерево файлов UICC. Отображаются имена, FID и AID (для ADF). Клик для чтения содержимого.
|
||
|
||
- **Read** — чтение файла (автоопределение transparent/record)
|
||
- **Edit** — режим редактирования, измените hex-данные и нажмите **Save** для записи
|
||
- **Raw / Decoded** — переключение между hex-дампом и декодированным JSON
|
||
|
||
### Пользовательские файлы
|
||
|
||
Файлы, отсутствующие в модели pysim, можно добавить вручную:
|
||
|
||
1. Перейдите на вкладку **Custom files**
|
||
2. Введите путь (например, `3F00/6F46`) и псевдоним (например, `EF.SPN`)
|
||
3. Нажмите **Add** — файл появится в дереве курсивом (непроверенный)
|
||
4. Кликните для проверки существования — при успехе работает как обычный файл
|
||
|
||
Пользовательские файлы сохраняются в `localStorage`. Экспорт/импорт в JSON для обмена.
|
||
|
||
### Подсказки команд
|
||
|
||
Введите имя команды в **pySim command line**. Подсказки по использованию появляются через 300 мс. Автодополнение команд — над полем ввода.
|
||
|
||
---
|
||
|
||
## Профайлер
|
||
|
||
Проверка соответствия карты именованному **профилю** — упорядоченному набору правил, описывающих ожидаемую файловую систему и (опционально) содержимое файлов. Профили хранятся в `localStorage`.
|
||
|
||
- **Новый профиль** создаёт пустой набор правил; **Профиль с карты** сканирует подключённую карту и создаёт по правилу на каждый существующий файл; **Импорт профиля** загружает набор из JSON (имя хранится внутри файла).
|
||
- В каждой строке профиля: **Проверить карту ▶** (на подключённой карте), **Проверить снимок карты** (offline по сохранённому снимку), **Редактировать**, **Экспорт** и **Удалить**.
|
||
|
||
Правило файловой системы задаётся:
|
||
|
||
- **Путь** — от `MF` (напр. `MF/7F10/6F3A`) или от AID ADF (напр. `A0000000871002/6F07`).
|
||
- **Проверка FCP/FCI** — **Только тип файла (FCP)**, **Тип файла + размер (FCP)** (добавляет размер файла или длину/число записей) либо **Полный FCI** (побайтовое сравнение сырого шаблона FCP `'62'` из ответа SELECT — ловит изменения FID/AID, life-cycle, security attributes и проприетарных параметров).
|
||
- **Атрибуты файла** — тип, размер, длина и число записей из шаблона FCP (любое можно не задавать).
|
||
- **Проверка содержимого** (опционально) — **Exact** (точное равенство hex) или **Mask**, где `?` — пониббловый джокер (маска без `?` — префиксное совпадение, напр. `0891` для MCC/MNC IMSI). Для record-файлов хранится список записей.
|
||
|
||
Отчёт проверки помечает каждый аспект (напр. *тип файла ✓, размер ✗, содержимое ✓*), показывает расхождения как поля только для чтения (ожидаемое/фактическое в одной колонке) и декодированное сравнение параметров FCI для расхождений FCI. Повреждённые FCI показывают всё, что удалось декодировать, плюс явное сообщение об ошибке; для записей указываются *совпадающие записи*. Опция **«Только расхождения»** скрывает все совпавшие файлы, оставляя несовпадения и ошибки.
|
||
|
||
#### Опции сканирования «Профиль с карты»
|
||
|
||
Диалог сканирования запрашивает имя профиля и предлагает режим FCP/FCI, список **«Игнорировать содержимое файлов»** (все включены, кроме `EF.ARR`; чекбокс в заголовке переключает весь список) — `EF.LOCI`, `EF.PSLOCI`, `EF.EPSLOCI`, `EF.5GS3GPPLOCI`, `EF.Keys`, `EF.KeysPS`, `EF.SMS`, `EF.Kc`, `EF.KcGPRS`, `EF.LOCIGPRS`, `EF.CBMID`, `EF.SMSS`, `EF.ACC`, `EF.EPSNSC`, `EF.START-HFN`, `EF.ARR` — и две включённые по умолчанию маски, сохраняющие только первые 4 байта `EF.IMSI` и `EF.ICCID`. Строка прогресса показывает *N / всего файлов* с текущим путём; во время сканирования опции заблокированы. Правила создаются только для существующих файлов; пользовательские файлы из подвкладки **Custom files** проверяются на существование так же.
|
||
|
||
#### Снимки карт
|
||
|
||
Представление списка имеет две вкладки — **«Профили»** и **«Снимки карт»**. Снимок — неизменяемая фиксация файловой системы: путь, символьное имя, тип, размер (или длина/число записей), сырой FCI и содержимое (если читается) каждого существующего файла. ICCID декодируется из EF.ICCID и показывается рядом с именем.
|
||
|
||
- **Новый снимок** сканирует карту; **Импорт снимка** загружает JSON.
|
||
- В строке снимка: **Открыть** (все данные только для чтения, сырой FCI с декодированным и содержимое; редактируется только имя), **Экспорт**, **Удалить**.
|
||
- **Проверить снимок карты** в строке профиля выполняет правила профиля на выбранном снимке без картридера. Файлы без захваченного содержимого помечаются как непроверяемые ошибки.
|
||
- **Сравнить снимки** сравнивает два снимка offline так же, как проверка профиля: выберите *эталонный* снимок и *снимок для проверки*, при необходимости включите маску первых 4 байт EF.IMSI/EF.ICCID (включена по умолчанию). Всё должно совпадать точно (FCI, содержимое); файлы только в проверяемом снимке помечаются как лишние.
|
||
|
||
---
|
||
|
||
---
|
||
|
||
## Симулятор телефона
|
||
|
||
Вкладка **«Симулятор телефона»** обеспечивает взаимодействие с CAT-сессией в реальном времени. Две подвкладки: **«Телефон»** (меню STK, STATUS и опрос, подписанные события, журнал проактивных команд) и **«Конфигурация TR»** (данные ответов, подставляемые в TERMINAL RESPONSE для проактивных команд).
|
||
|
||
**Subscribed Events** — список событий SET UP EVENT LIST с кнопками **Send**. Клик открывает форму для конкретного типа события:
|
||
|
||
- **События без данных** (User Activity, Idle Screen и др.) — однократное уведомление
|
||
- **Location Status** — выпадающий список: Normal / Limited / No service
|
||
- **Access Technology Change** — 13 типов RAT
|
||
- **Network Rejection** — полная адаптивная форма: тип регистрации (LU / GPRS / EPS / 5GS), поля локации (MCC, MNC, LAC, RAC, TAC), доступные технологии, 53-позиционный выпадающий список причин отказа (EMM, GMM, 5GMM, LU)
|
||
|
||
**Proactive Command Log** — хронологический список проактивных команд. Каждая строка показывает время, код типа, имя и декодированный квалификатор.
|
||
|
||
**Конфигурация TR: словарь PLI** — редактируемые hex-значения для всех 22 квалификаторов PROVIDE LOCAL INFORMATION (TS 102 223 + TS 131 111). 10 квалификаторов имеют встроенные формы декодирования/кодирования:
|
||
|
||
| Код | Декодированные поля |
|
||
|------|--------------|
|
||
| 00 | MCC, MNC, LAC/TAC |
|
||
| 01 | IMEI (15 цифр) |
|
||
| 03 | Дата, время, TZ |
|
||
| 04 | Язык (2-символьный код) |
|
||
| 05 | ME Status, Timing Advance |
|
||
| 06 | Access Technology (выпадающий список) |
|
||
| 08 | IMEISV (16 цифр) |
|
||
| 09 | Search Mode (Auto/Manual) |
|
||
| 0A | Battery charge (%) |
|
||
| 0E | Multiple Access Technologies (список через запятую) |
|
||
|
||
Значения сохраняются на сервере до перезапуска. Apply → hex обновляется; Save → POST на сервер.
|
||
|
||
## PWA
|
||
|
||
OTAMan — Progressive Web App. Можно установить для offline-использования через кнопку **INSTALL PWA** или через браузер.
|
||
|
||
- Service worker кеширует все ресурсы при первом посещении
|
||
- Иконки 192×192 и 512×512
|
||
|
||
## Тема
|
||
|
||
Тёмная тема поддерживается. Следует системной теме, переключается вручную кнопкой (🌙/☀️). Выбор сохраняется в `localStorage`.
|
||
|
||
## Локализация
|
||
|
||
Интерфейс на английском с поддержкой русского языка. Язык определяется из `navigator.language`. Кнопка переключения (EN/RU) в заголовке сохраняет выбор в `localStorage`. При переключении языка динамические представления (списки профилей, отчёты проверок, снимки, карты, proactive) перерисовываются.
|
||
|
||
## Совместимость версий
|
||
|
||
| PWA (OTAMan) | Сервер | Статус |
|
||
|---|---|---|
|
||
| 1.x.x | 1.x.x | ✅ Совместимы |
|
||
| 1.x.x | 0.x.x | ❌ Сервер устарел |
|
||
| 1.x.x | 2.x.x+ | ⚠️ Сервер новее — обновите PWA |
|
||
|
||
PWA проверяет версию сервера при подключении через `GET /api/version`.
|
||
|
||
---
|
||
|
||
## Сервер (pysim-otaman-server)
|
||
|
||
Встроенный Python-сервер оборачивает [pySim](https://osmocom.org/projects/pysim/wiki) и раздаёт как PWA (из `frontend/`), так и JSON API по `/api/*`.
|
||
|
||
### Требования
|
||
|
||
- **Python 3.8+** с `pip`, и **Git**
|
||
- **Смарт-картридер** (PC/SC или serial/FTDI) — предпочтителен PC/SC (`pcsc-lite` + `ccid` на Linux)
|
||
- **Windows** — используйте Python 3.10–3.13 (рекомендуется 3.13): у `pyscard` есть готовые wheel. На 3.9 / 3.14 он собирается из исходников (нужны MSVC C++ Build Tools). SMPP-мост (`smpp.twisted3`) в Windows сознательно не ставится.
|
||
|
||
### Скрипты
|
||
|
||
| Скрипт | Назначение |
|
||
|--------|-------------|
|
||
| `setup.sh` / `setup.bat` | Создаёт `.venv/`, ставит pysim и сервер. Запускать один раз после клонирования. |
|
||
| `start.sh` / `start.bat` | Запускает сервер из venv (раздаёт PWA + API на `:8080`). |
|
||
|
||
`start.sh` автоопределяет ридер (PC/SC при работающем `pcscd`, иначе `/dev/ttyUSB0`); `start.bat` всегда использует `-p 0`. Без ридера сервер всё равно стартует («Reader: none») — карту можно инициализировать позже кнопкой **Equip**.
|
||
|
||
### Ручная установка
|
||
|
||
```sh
|
||
python3 -m venv .venv
|
||
source .venv/bin/activate # Linux/macOS (Windows: .venv\Scripts\activate)
|
||
pip install git+https://github.com/osmocom/pysim.git
|
||
pip install -e . # editable — раздаёт frontend/ из исходного дерева
|
||
pysim-otaman-server --http-port 8080
|
||
```
|
||
|
||
### Параметры CLI
|
||
|
||
| Параметр | Описание |
|
||
|----------|-------------|
|
||
| `--http-host` | Адрес привязки (по умолчанию `127.0.0.1`) |
|
||
| `--http-port` | Порт (по умолчанию `8080`) |
|
||
| `--web-dir` | Каталог со статикой PWA (по умолчанию `<repo>/frontend`) |
|
||
| `-p` / `--pcsc-device` | Номер слота PC/SC |
|
||
| `-d` / `--device` | Путь к serial-устройству |
|
||
| `--no-card-init` | Пропустить инициализацию карты (сохранить CAT-сессию) |
|
||
| `--apdu-trace` | Лог APDU-трафика в stderr |
|
||
| `--log-requests` | Лог запросов/ответов в stderr |
|
||
| `--poll-interval` | Интервал автоопроса STATUS (по умолчанию 30с; `0` отключает опрос) |
|
||
| `--full-pysim-init` | Штатная инициализация/equip из pysim (с лишними сбросами карты). По умолчанию инициализация без лишних сбросов — карта переподключается только по явным equip/reset |
|
||
| `--no-auto-equip` | Не инициализировать карту автоматически сразу после вставки (по умолчанию автоинициализация включена) |
|
||
| `--menu-timeout` | Автоответ timeout TERMINAL RESPONSE на приостановленную STK-команду (по умолчанию 60с; `0` отключает) |
|
||
| `--timing` | Лог длительности фаз, сбросов карты и счётчиков APDU с отметками времени |
|
||
|
||
### Устранение неполадок
|
||
|
||
- **"Failed to establish context: Access denied"** — `pcscd` не запущен или нет прав: `sudo systemctl enable --now pcscd && sudo usermod -a -G pcscd $USER`.
|
||
- **"device file /dev/ttyUSB0 does not exist"** — нет serial-ридера; подключите USB-ридер или укажите `-d`. Сервер всё равно стартует без ридера.
|
||
|
||
### Справочник API
|
||
|
||
Полный справочник endpoints: [docs/api.md](docs/api.md).
|