- TP_BITS: fill the value-field rows that were all-RFU (byte 11 soft keys,
byte 13 b6-b8 channels, byte 14 height + ND/NK/sizing, byte 15 width +
variable fonts, byte 16 effects + width reduction, byte 19 TIA version,
byte 24 max frames), per TS 102 223 5.2.
- TP_VALUE_FIELDS + tpGetValue/tpSetValue (little-endian bit ranges) and
number inputs in the Configure dialog; the byte 11 'FF' reserved note
stays visible in the hint; flags remain checkboxes.
- Tests: new label spot checks, value round-trips/clamping, render guard.
- docs/TERMINAL_PROFILE.md: byte 22 b1 not universal (S25 Ultra/edge 60
clear, WISMO228 sets), b2/b3 counts fixed, byte 21 markup present in
Pixel 3/4 + OnePlus 12, ESN is a capability bit not a CDMA marker,
0xFE sentinel unexplained by the spec, channel count 5 added, new
Appendix A with the value-field ranges.
- Version 2.2.21, SW cache otaman-v188.
The spec tables (TS 102 223 5.2) list b1 - the least significant bit - first:
verified from the PDF connector geometry (label row 1 connects to the
rightmost cell) and from Wireshark's packet-gsm_sim.c masks ('Profile
download' = 0x01, 'E-UTRAN bearer' = 0x40, 'HSDPA bearer' = 0x80). The
Configure dialog had it mirrored: TP_BITS[n] was matched with 0x80 >> (n%8)
and displayed as b8..b1, so every label toggled the wrong physical bit
(our own BIP-capable default proved it: byte 12 = 0x1F read as DECLARE
SERVICE.. instead of OPEN/CLOSE/RECEIVE/SEND/GET CHANNEL STATUS).
- tpGetBit/tpSetBit now use 1 << (n%8); the form lists b1 first, matching
the spec; tpBitLabel names the RFU fallback bit accordingly.
- Tests pin the new mapping and the corrected spot-check indices, and the
project default is asserted to decode as BIP-capable (OPEN/SEND DATA,
E-UTRAN, HSDPA).
- docs/TERMINAL_PROFILE.md (in projects/docs): everything gathered about
inferring device characteristics from a TP - bit order, profile-length era
bands, headless/modem markers (Annex S ND/NK plus the byte 11/screen-size
heuristics), radio generation (byte 17 b7/b8 with the 'capability, not
attach' caveat), standards family (ESN/IMEISV/TIA/CCAT), BIP capability,
UI paradigm, and a suggested inference model. Corpus: samples/tp_db.csv
(185 profiles, CC-BY-SA, kept out of the repo).
- Help EN/RU note the bit order and point at the new document; AGENTS
records the mapping rule and the doc location.
The actions sat below the note line and the (long, 45vh) bits grid, so they
needed scrolling to reach. They now sit to the right of the preset selector
and hex field, aligned with the preset row; the bit grid is unchanged.
TERMINAL PROFILE form (Phone simulator):
- The compact block no longer shows the hex value (no room); Send +
Configure + status remain. Preset selector sits above the hex field.
- Bits are never spread horizontally: each byte is one vertical list.
Byte blocks are placed by the fixed TP_LAYOUT groups - bytes 1-12 in
2 columns, 13-16 in 4, 17-18 in 2, 19-21 in 3, 22-25 in 2, 26-28 in 3,
29-30 in 2, 31+ one per row - in strict byte order.
Bit descriptions audited against the pinned specs:
- Table regenerated from ETSI TS 102 223 V18.3.0 5.2 (bytes 1-39) with
the 3GPP-defined bits named per ETSI TS 131 111 V18.12.0 5.2; the
"reserved by 3GPP" placeholders are gone (tests guard this).
- Fixes found in the audit: byte 7 b6 PERFORM CARD APDU (pySim had
RESET), MO short message control by USIM, USSD string DO support in
Call Control by USIM, the earlier "Data available" typo.
- Presets: project default + Quectel example + Samsung S21+ 5G, Samsung
A55 5G, Xiaomi Redmi Note 10 LTE, Sony Xperia Z5c LTE, Huawei
E5573c/M150 (LTE), Huawei E173 3G modem, Nokia 7210 2G (9 total).
Also fixes a page-load TDZ regression: the custom-files init (which
calls t()) now runs after the language init (guard test added).
SW cache otaman-v174; help EN/RU updated; tests 236 Python + 374 frontend.
TERMINAL PROFILE:
- GET /api/terminal-profile returns the profile in effect + the CLI default;
POST /api/terminal-profile validates ({profile}, hex, even, 1-255 bytes),
stores it in memory and re-sends it, resetting the STK session like
/api/rescue (the shared _resend_terminal_profile helper; rescue now
delegates to it). __main__ keeps server.cli_terminal_profile.
- Phone tab: a TERMINAL PROFILE block next to STATUS and Polling with the
current hex/byte count, Send (re-send) and Configure. The Configure
dialog has a device-model preset selector, a hex field and a per-bit
form generated from a 264-entry table for TS 102 223 V18.3.0 5.2 bytes
1-33 (pySim's table as scaffold, later bytes/3GPP bits added from the
spec; beyond the table generic RFU labels). Form <-> hex sync both
ways, hex authoritative, bits preserved. Apply posts the new value.
- Presets: Xiaomi Mi A1 (project default), Quectel GSM module example.
In-memory only, no persistence.
Custom files:
- Canonical paths rooted at MF / ADF.USIM / ADF.ISIM; entries are
{path, name, kind}. The editor now uses root + parent-DF selector +
4-hex FID + alias, requires the parent DF to be defined first, rejects
duplicates, rewrites descendants when a DF's path changes and cascades
deletes after a confirmation.
- Legacy forms are normalized on load/import (3F00/... -> MF/..., relative
a153/4954 resolved against the custom DFs); unresolvable entries are
dropped and reported in the list.
- Tree injection matches by exact parent path via the new pysimFsNodePath
(same-FID DFs under different parents no longer collide);
profilerCustomNameForPath uses the same normalization.
SW cache otaman-v167; help EN/RU + docs/api.md + AGENTS updated.
Tests: 236 Python + 371 frontend.