OTAMan Documentation
1. Overview
OTAMan is a Progressive Web App (PWA) for building APDU commands, assembling SCP80 secured packets, browsing the SIM Toolkit (STK) menu, and simulating a real network environment against a SIM/USIM/UICC card via a PC/SC reader.
The application is a single static index.html file. All computation runs in the browser; the card is accessed through a local HTTP server (pysim-otaman-server) that wraps the pySim library.
Browser (OTAMan PWA) → HTTP :8080 → pysim-otaman-server → pySim → PC/SC → card reader → UICC/SIM
Standards referenced across the application:
- ETSI TS 102 221 — UICC-Terminal interface (CLA 00, USIM files)
- ETSI TS 102 222 — Administrative commands
- ETSI TS 102 223 — Card Application Toolkit (CAT, proactive commands)
- ETSI TS 102 225 — Secured packet structure for (U)SIM toolkit
- ETSI TS 102 226 — Remote APDU structure for UICC based applications
- ETSI TS 151 011 — SIM-ME interface (CLA A0)
- 3GPP TS 131 111 — USIM Application Toolkit (USAT)
- 3GPP TS 31.102 — USIM application characteristics
- 3GPP TS 23.038 — GSM 7-bit alphabet and DCS
- 3GPP TS 24.008 / 24.301 / 24.501 — NAS cause codes
- GlobalPlatform Card Specification v2.3.1
- ISO/IEC 7816-4 — commands for interchange
- ISO/IEC 9797-1 — MAC algorithms
2. C-APDU tab
Builds command APDUs (C-APDUs). Five sub-tabs cover different card generations and command sets: SIM RFM, USIM RFM, Expanded Script, RAM/GP, and C-APDU Parser.
2.1 SIM RFM
CLA = A0 (GSM 11.11 / TS 151 011, ISO 7816-4). Remote File Management for classic SIM cards.
Commands are assembled as a chain: press a + Command button to append a row, fill that row’s fields, and the chain preview (above the pack button) updates automatically. Add a GET RESPONSE row to fetch data following a SELECT. Press Pack into Secured packet to wrap the whole chain into an SCP80 packet.
| Command | INS | Description |
|---|---|---|
| SELECT | A4 | Select EF/DF by FID, path, AID or chain |
| UPDATE RECORD | DC | Update a record in a record-oriented EF |
| UPDATE BINARY | D6 | Update binary content at an offset |
| READ RECORD | B2 | Read a record |
| READ BINARY | B0 | Read binary content |
| ERASE BINARY | 0E | Erase binary at an offset |
| ACTIVATE FILE | 44 | Activate a file |
| DEACTIVATE FILE | 04 | Deactivate a file |
| VERIFY PIN | 20 | Verify PIN1 or PIN2 |
| CHANGE PIN | 24 | Change PIN1 or PIN2 |
| DISABLE PIN | 26 | Disable a PIN |
| ENABLE PIN | 28 | Enable a PIN |
| UNBLOCK PIN | 2C | Unblock a PIN with PUK |
| GET RESPONSE | C0 | Fetch data indicated by a preceding 61XX/9FXX status word |
SELECT methods
| Method | P1 | P2 | Input |
|---|---|---|---|
| By FID | 00 | 00 | 2-byte FID (4 hex) |
| By full path from MF | 08 | 00 | Full path hex from MF |
| By DF name / AID | 04 | 00 | AID (application ID) |
| Chain | 00 | 00 | Comma-separated FIDs; a C0 (or C0:NN) token inserts a GET RESPONSE hop |
For record commands, the P2 mode is Absolute (04), Next (02), or Previous (03). When a Case 4 command is immediately followed by a GET RESPONSE row, the chain builder strips its trailing Le byte automatically (ETSI TS 102 226 §5.1.1). A conversion panel is embedded in the right column (IMSI, MSISDN, ICCID, SPN, PLMN, nibble swap). See §2.5.
2.2 USIM RFM
CLA = 00 (ETSI TS 102 221). Same chain builder and command set as SIM. Differences:
- SELECT requests FCP by default (P2=
04) and appends Le=00; a Silent (P2=0C) checkbox selects without requesting FCP (no Le, no response data). - By path offers from MF (P1=
08) or from current DF (P1=09). - Each SELECT hop in a chain requests FCP unless marked silent.
2.3 Expanded Script
Builds the Expanded Remote Application data format per ETSI TS 102 226 §5.2.1.
Format
- Definite (AA):
AA+ length + Command TLVs - Indefinite (AE):
AE+80+ Command TLVs +00 00
Command TLVs
| Type | Tag | Description |
|---|---|---|
| C-APDU | 22 | Raw APDU hex |
| Immediate Action | 81 | Proactive command or action indicator |
| Error Action | 82 | Conditional error recovery with action indicator or proactive command |
| Script Chaining | 83 | Multi-packet script execution with First/Intermediary/Last flags |
| Response Type | - | Expanded/Compact/None response parsing indicator |
The Immediate Action builder offers an action indicator (81/82), a structured proactive command builder (REFRESH, DISPLAY TEXT, PLAY TONE with auto-generated COMPREHENSION-TLV objects), or a freeform hex input.
Error Action TLV (Tag 82)
Error recovery per TS 102 226 §5.2.1.3 — one of three forms:
- Proactive command: COMPREHENSION-TLV set with DISPLAY TEXT or PLAY TONE (only these two are allowed in an Error Action, TS 102 226 Table 5.9)
- No action:
82 00 - Reference to EFRMA record:
82 01 <ref>with record number01–7F - Custom hex: arbitrary TLV value
Script Chaining TLV (Tag 83)
Multi-packet script execution with context preservation:
- Chaining Flags:
01first script (delete chaining info on reset),11first script (keep chaining info across reset, RFM only),02subsequent script (more to follow),03subsequent script (last) - Script ID: Correlation identifier across packets (1-4 bytes hex, auto-increment hints provided)
- Additional Data: Extended chaining information (optional hex)
- Context Preservation: UICC keeps security/transaction state open across chained scripts
Expanded Remote Response (TS 102 226 §5.2.2)
Per-command results with error details and chaining context:
- Command number, status word, response data for each command
- Error code and error info for failed commands (highlighted in red)
- Script ID and position for chained script correlation (ID, FIRST, LAST)
- Response type indicator: 'expanded' vs 'compact' vs 'none'
2.4 RAM/GP
CLA = 80 (GlobalPlatform Card Specification v2.3.1). Remote Application Management commands for card content management. Built with the same chain builder as SIM/USIM: add rows, fill fields, and the chain preview updates automatically.
| Command | INS | P1 | Description |
|---|---|---|---|
| INSTALL [for load] | E6 | 02 | Register a load file for loading |
| INSTALL [for install] | E6 | 0C | Install an application or SD |
| INSTALL [make selectable] | E6 | 08 | Make an application selectable |
| INSTALL [registry update] | E6 | 40 | Update registry entries |
| INSTALL [extradition] | E6 | 10 | Extradition between SDs |
| LOAD | E8 | 80 | Load executable code block (P1=80 last block, block number in P2) |
| DELETE | E4 | 00 | Delete application or SD (P2=00 AID only / 80 AID + related objects) |
| GET STATUS | F2 | 80/40/20/10 | Get card status |
| GET DATA | CA | tag | Read card data objects |
| STORE DATA | E2 | 00/40/80/C0/E0 | Store data (key, certificate, …) |
| SET STATUS | F0 | 80/40/60 | Lifecycle state management |
| EXTERNAL AUTHENTICATE | 82 | 00 | SCP host authentication |
| INTERNAL AUTHENTICATE | 88 | 00 | Card challenge-response |
| GET RESPONSE | C0 | 00 | Fetch data after a 61XX status (Le configurable) |
Privileges (INSTALL [for install])
Three privilege bytes (GP spec Tables 11-7/8/9), encoded as a length-value field inside the INSTALL data:
| Bit | Byte 1 | Byte 2 | Byte 3 |
|---|---|---|---|
| b8 | Security Domain | Trusted Path | Receipt Generation |
| b7 | DAP Verification | Authorized Management | |
| b6 | Delegated Management | Token Verification | |
| b5 | Card Lock | Global Delete | |
| b4 | Card Terminate | Global Lock | |
| b3 | Card Reset | Global Registry | |
| b2 | CVM Management | Final Application | |
| b1 | Mandated DAP Verification |
MSL (Minimum Security Level) — SPI1 byte per TS 102 225
| Value | Meaning |
|---|---|
| 00 | No check |
| 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 |
Refer to GlobalPlatform v2.3.1 and ETSI TS 102 226 §8.2.1.3.2 for the full GET STATUS P1/P2, GET DATA tag, DELETE P1, STORE DATA P1, and SET STATUS tables.
2.5 Conversion (SIM/USIM sidebars)
- IMSI → EF.IMSI — 15-digit IMSI to 9-byte format (TS 31.102 §4.2.3).
- MSISDN → BCD — strip
+, pad odd length withf, swap nibbles. - ICCID → hex — nibble-swap the ICCID string.
- Provider Name → SPN — GSM 7-bit packed, UCS2 non-BMP, or UCS2 BMP (TS 31.102 §4.2.5, TS 23.038).
- PLMN → EF_PLMNsel / PLMNwAcT — 3-byte BCD + optional access technology selector.
- Nibble swap — swap nibble pairs of an even-length hex string.
2.6 C-APDU Parser
Pastes raw APDU hex and renders a collapsible tree. It auto-detects the container: an Expanded Script (leading The SCP80 top-level tab groups the SCP80-related views. It is switched by three pills: Secured Packet, Cards, and RAM. Assembles SCP80 secured packets per ETSI TS 102 225. Builds SCP80 secured packets per ETSI TS 102 225. A “Verify vs pySim” button cross-checks the assembled packet against pySim’s reference Stores card presets locally in the browser ( Export as JSON / Import JSON from clipboard share presets. The selected card preset auto-fills the Secured Packet form. Delivers Remote Application Management operations as SCP80 secured packets via SMS-PP-DOWNLOAD ENVELOPE. The card must support SCP03 (AES or 3DES). A saved card preset from the Cards sub-tab provides the SPI, keys, TAR, and counter. After “Explore Card” runs, the explorer displays: Delete confirms via a browser prompt before sending the GP Decodes a raw command response: pick the command that was sent, enter the SW (e.g. Connects to a local pysim-otaman-server for live card operations. Sub-tabs: File manager, Custom files, Profiler, pySim command line, Raw APDU, and Proactive UICC. Add files that pySim’s model does not cover. Persists in Execute any pySim-shell command with usage hints (300 ms) and autocomplete. Send an arbitrary APDU and view the raw response. Interacts with the Card Application Toolkit session: the STK menu, subscribed events, the proactive command log, the PROVIDE LOCAL INFORMATION data dictionary, and STATUS polling. When the card has issued a SET UP MENU command, a “STK menu” block appears at the top of this view with an emerald STK: <title> button that opens the menu overlay (same as the card’s STK menu browser). If the card has not set up a menu, the block shows “No menu set by the card” instead. The menu state is refreshed each time the view is opened. The events the card monitors. Each event has a Send button that opens a form specific to the event type: Sending an event uses Chronological list of fetched proactive commands. Each row shows the elapsed time, type code, name, and a decoded qualifier (for commands that have one). Commands with response data show a Editable hex values for all 22 PLI qualifiers (TS 102 223 §8.6 + TS 131 111). Ten qualifiers have inline decode/encode forms: Values persist server-side until restart. When the card issues PLI, the server injects the dictionary values into the TERMINAL RESPONSE. A Send STATUS button issues a manual STATUS (F2). A Polling toggle enables background polling: after a configurable idle interval (server CLI Verifies that a card matches a named profile — an ordered set of rules describing the expected file system and (optionally) file contents. Profiles are stored in Rules run sequentially. A filesystem rule is defined by: Check runs every rule against the equipped card and shows a live progress line plus a pass/fail report (existence, each FCI attribute, and the content match). The scan dialog asks for a profile name and offers an “Ignore contents of” checklist (all checked by default) of frequently-overwritten files whose contents are skipped: B.1 Answer PROVIDE LOCAL INFORMATION (PLI) B.2 Simulate network actions via ENVELOPE (event download) B.3 Verify the simulated environment Live card operations (Card reader tab, Proactive UICC, OTA delivery) require the local pysim-otaman-server — a small HTTP server bundled with OTAMan that wraps pySim, talks to the reader over PC/SC or serial, and also serves the PWA itself (open If no reader is detected, the server starts without reader arguments and shows “Reader: none”. The card can be initialized later via the Equip button in the Card reader tab. Connect a PC/SC reader with a SIM card, then open If the PWA is served from a public HTTPS host (e.g. The PWA checks the server version on connect via AA or AE80, decoded per ETSI TS 102 226 §5.2.1) or a Compact C-APDU chain (a sequence of ISO 7816 C-APDUs). Each node shows its label, hex and a short description; parent nodes expand to reveal their sub-elements.
3. SCP80 tab
3.1 Secured Packet
Packet structure
Field Size Description 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 for ciphering KID 1 Key Identifier for MAC TAR 3 Toolkit Application Reference CNTR 5 Replay counter PCNTR 1 Padding counter RC/CC/DS 8 Cryptographic Checksum / MAC Secured Data var. Padded APDU (encrypted if required) Crypto
x2)x2)10 (counter higher) or 11 (counter +1) per TS 102 225 §5.1.2/§5.1.3.100 default, or FF)OtaDialectSms.encode_cmd. A “Send to Card” button delivers it via SMS-PP-DOWNLOAD ENVELOPE (when connected to the server).3.2 Cards
localStorage) so the Secured Packet view can auto-fill keys and parameters.
Field Description Name Human-readable label ICCID Optional card identifier KIc / KID Key and algorithm indicators (e.g. 15 = index 1, 3DES-CBC2; x2 = AES) SPI1 / SPI2 Security Parameter Indicators TAR Toolkit Application Reference Counter Replay counter (5 bytes) KIc key / KID key 16/24/32 hex chars (8/16/24-byte 3DES) or 32/48/64 hex chars (16/24/32-byte AES) keys 3.3 RAM
Operations
Operation Description Explore Card (all GP data) Queries GET STATUS for ISD, Applications, ELFs, and ELF Modules, plus GET DATA FF21 for memory info. Results appear in an explorer view with per-item Delete buttons. Install Package (.cap file) Sends a .cap file to the card via the server: INSTALL[for load] → LOAD ×N → INSTALL[for install (+make selectable)].Explorer View
DELETE by AID).0x80) buttons.DELETE command via SCP80. The explorer auto-refreshes after a successful deletion.4. Response parser tab
9000) and the response data hex, then press Decode.
5. Card reader (pySim) tab
5.1 File manager
5.2 Custom files
localStorage; JSON export/import.5.3 pySim command line
5.4 Raw APDU
5.5 Proactive UICC
5.5.1 STK menu
5.5.2 Subscribed events (SET UP EVENT LIST)
9B)BF)ENVELOPE(Event Download) per TS 102 223 / TS 131 111.5.5.3 Proactive command log
Response: line with the TERMINAL RESPONSE bytes (boilerplate TLVs stripped); PROVIDE LOCAL INFORMATION responses are decoded using the PLI data dictionary decoders.5.5.4 PROVIDE LOCAL INFORMATION data dictionary
5.5.5 STATUS polling
--poll-interval, 1–255 s, default 30 s) the server sends STATUS and handles any pending proactive command. Polling stops and card state resets if the card is removed.5.6 Profiler
localStorage.Profile list
Filesystem rules
MF (e.g. MF/7F10/6F3A) or an ADF AID (e.g. A0000000871002/6F07).? is a per-nibble wildcard (a mask with no ? is a prefix match, e.g. 0891 for the IMSI MCC/MNC). Record files store a per-record list.“Profile from card” scan options
EF.LOCI, EF.PSLOCI, EF.EPSLOCI, EF.5GS3GPPLOCI, EF.Keys, EF.KeysPS, EF.SMS, EF.Kc, EF.KcGPRS, EF.LOCIGPRS, EF.CBMID, EF.SMSS. Rules are created only for files that actually exist on the card (an FCI template is returned); missing files are skipped. Custom files from the Custom files sub-tab are included under the same existence check.5.7 Usage scenarios
Scenario A — Working with files not in pySim’s model (Custom files)
3F00/7F20/6F46) and an alias (e.g. EF.SPN).9000) it behaves like a normal file.Scenario B — Simulating a real network environment for SIM testing
01), Location Info (00), Access Technology (06), etc.
ENVELOPE(Event Download) is sent.
6. Server installation
http://127.0.0.1:8080).6.1 Prerequisites
pippcsc-lite + ccidpyscard (the PC/SC driver wrapper) ships precompiled wheels for these versions. On Python 3.9 / 3.14 pip builds pyscard from source, which requires Microsoft C++ Build Tools (“Desktop development with C++”). The SMPP bridge (smpp.twisted3) is intentionally not installed on Windows, so no C++ Build Tools are needed for Python 3.10–3.13.6.2 Quick start — Linux / macOS
git clone https://github.com/anttro/otaman.git
cd otaman
chmod +x setup.sh start.sh
./setup.sh # creates .venv, installs pysim + server (run once)
./start.sh # starts the server (serves PWA + API, auto-detects reader)
6.3 Quick start — Windows
git clone https://github.com/anttro/otaman.git
cd otaman
setup.bat # creates .venv, installs pysim + server (run once)
start.bat # starts the server (serves PWA + API)
6.4 Helper scripts
Script Purpose setup.sh / setup.bat Creates .venv/, installs pySim and the server. Run once after cloning.start.sh / start.bat Starts the server from the venv (falls back to a global install). 6.5 Reader auto-detection (
start.sh)
pcscd daemon is running, passes -p 0/dev/ttyUSB0 exists, passes -d /dev/ttyUSB0-p 0 (PC/SC is built into Windows)6.6 Manual installation
# Create and activate a venv
python3 -m venv .venv
source .venv/bin/activate # Linux/macOS
# .venv\Scripts\activate # Windows
# Install pysim
pip install git+https://github.com/osmocom/pysim.git
# Install pysim-otaman-server (editable, so it serves the bundled PWA)
pip install -e .
# Start the server (serves PWA + API)
pysim-otaman-server --http-port 8080
http://127.0.0.1:8080 — the PWA and API share one origin, so no CORS is involved.https://otaman.example.com), two things are required to reach a local card server: (1) the server must answer the preflight with Access-Control-Allow-Private-Network: true (pysim-otaman-server ≥ 1.6.1 does this automatically), and (2) the browser must be allowed to access the local network — in Chrome/Edge/Vivaldi: Site settings → Local network access → allow the site (or accept the permission prompt). Without the browser permission, the request to 127.0.0.1 is blocked before any preflight is sent.7. Version compatibility
PWA (OTAMan) Server Status 1.x.x 1.x.x ✅ Compatible 1.x.x 0.x.x ❌ Outdated — update server 1.x.x 2.x.x+ ⚠️ Server newer — update PWA GET /api/version and warns if versions are incompatible.