Commit Graph
32 Commits
Author SHA1 Message Date
catarrh 174df8a8ad Fix CAT registries per TS 102 223 V18.3/TS 31.111 V18.12; decode all ENVELOPE types
Spec audit found three registries drifted from an old release, plus
missing command/envelope coverage:

- EVENT_TYPES: correct from '14' up — Access Technology Change
  (multiple), IMS Registration/Incoming data, Profile Container ('19),
  Secured Profile Container, Poll Interval Negotiation, Data Connection
  Status Change, CAG cell selection, Slices Status Change ('1F);
  '20-'22 reserved. Old table wrongly showed LTE D2D/ECall/SCEF names.
- TR_RESULTS: session/user results live at '10-'14 ('14 = USSD/SS
  transaction terminated), not '0A-'0E; single '20 = ME currently
  unable (per-cause details are additional-info bytes); add '22-'27,
  '3A BIP error; unshift '3B-'3D; '39 permanent-problem wording.
- ENVELOPE_TYPES: add D9 USSD Download, DA/DB MMS, DC Terminal
  Applications, DD Geo Location Reporting, DE Envelope Container,
  DF ProSe Report, E0 5G ProSe Report, E1-E3 reserved, E4 GSMA.
- CAT_COMMAND_TYPES: add '79 LSI COMMAND; F0-FE render as Proprietary.
- PLI_QUALIFIERS: add '07 ESN, '1A Supported RATs.

Phase 2:
- _decode_envelope: MENU SELECTION (item id + help request), TIMER
  EXPIRATION (id + semi-octet h/m:s value), CALL CONTROL (address +
  CCP), USSD DOWNLOAD (DCS text), GEO LOCATION REPORTING, ENVELOPE
  CONTAINER (recursive inner dispatch); unknown inner TLVs preserved
  in raw_tlv for every type.
- Device Identities now decode to names (Keypad/Display/UICC/
  Terminal/Network/Card reader n/Channel n/eCAT client) in proactive
  commands and envelopes; frontend renders "src → dst".

Tags verified against ETSI TS 101 220 registry (help request '15/'95,
timer id/value '24/'A4, USSD string '0A/'8A). Tests: +16 spec-derived
fixtures, one stale expectation corrected — 306 total. Version 1.13.0,
SW cache simtrace-analyser-v16.
2026-08-22 23:35:20 +03:00
catarrh fac6bd09af Decode SET UP IDLE MODE TEXT command data; bump to 1.11.0
TS 102 223 §6.6.13 support for the SET UP IDLE MODE TEXT (0x28)
proactive command:

- Command qualifier: COMMAND_QUALIFIERS entries may now be callables
  for bitmask-style qualifiers; _idle_text_qualifier decodes bit 1
  as "icon self-explanatory", hides 0x00, falls back to raw hex on
  RFU bits.
- Icon Identifier TLV (0x1E) parsed into icon_id (image record
  number in EF_IMG, 0 = none); rendered as an "Icon" detail row in
  the PWA.
- Zero-length Text String TLV now yields text='' ("remove idle mode
  text") instead of being silently skipped.

Tests: +6 TestIdleModeText cases (8-bit/UCS-2 text, icon TLV,
qualifier variants, empty text) — 285 total. SW cache bumped to
simtrace-analyser-v14.
2026-08-22 22:17:27 +03:00
catarrh ed25fcecf5 Fix APDU/SPI/SW decoder bugs per TS 102 221/TS 102 225; bump to 1.10.0
Spec-correctness release, verified against TS 102 221 V18.2.0 and
TS 102 225 §5.1.1:

- SPI1 ciphering bit: b3 (0x04), not b4 (0x08) — both the SPI dict
  and the KIc-unused check. Real MegaFon captures (SPI1=16) decoded
  as unciphered with "KIc unused" before this fix.
- SPI2 PoR-ciphering bit: b5 (0x10), not b6 (0x20); add por_transport
  field from SPI2 b6 (SMS-DELIVER-REPORT vs SMS-SUBMIT).
- SW table: add UICC-specific SWs 62F1/F2/F3, 63F1/F2, 6401, 9300
  (SAT busy), 9850, 9862/63/64; fix 6500 text ("NV memory changed");
  91XX now decodes as "Proactive command pending" via pattern.
- 63CX no longer hardcoded as PIN failure — exact 63F1/F2 entries take
  precedence; all other 63CX route through one verification-retry
  pattern (_SW_PATTERNS dict → ordered list).
- APDU_SPEC: +9 commands (D7/DD odd-INS update, D2 write record,
  82 external auth, 86/87 general auth, 22 MSE, 0E/0C erase, 7C LSI).
- decode_cla: proper ISO 7816-4 §5.1.1 coding — SM bits b4-b3,
  chain bit b5, further-interindustry channel offset (+4).

Tests: +27 (TestSwUiccSpecific, TestSpiBits, TestApduSpecCoverage,
TestClaDecode) — 279 total. SW cache bumped to simtrace-analyser-v12.
2026-08-21 22:41:16 +03:00
catarrh 582c42c5cd Decode SCP80 Response Packet (PoR) in GET RESPONSE after SMS-PP DOWNLOAD 2026-08-20 21:48:28 +03:00
catarrh 5d91450b55 Track device connection and capture gaps; surface sniff error flags 2026-08-19 18:00:52 +03:00
catarrh 26043e5381 Decode EF_DIR EAP discretionary template (TS 102 310) 2026-08-19 09:02:39 +03:00
catarrh f11a6a62e6 Fix IMSI decode: drop TS 24.008 type+parity nibble 2026-08-19 02:00:25 +03:00
catarrh ee5cd8e1fe Resolve SFI addressing for record commands; track selection per logical channel 2026-08-19 01:40:04 +03:00
catarrh 86317d0105 Decode READ/UPDATE BINARY SFI vs offset; surface proactive command qualifiers; fix capture stop 2026-08-18 23:31:26 +03:00
catarrh 166cf4ed0f Decode KIc/KID algorithms unconditionally; expand packet-length labels 2026-08-17 21:40:12 +03:00
catarrh f6ce7dfe3e Decode STATUS FCP, REFRESH mode, and length mismatches 2026-08-17 20:06:28 +03:00
catarrh 017c65de27 Add trace map view; decode PNN/SPN and 7-bit SMS TP-UD 2026-08-17 01:08:49 +03:00
catarrh 1c2d6af9e4 Decode OTA secured command/response packets in SMS TP-UD; collapse RFU P1/P2 2026-08-16 23:08:54 +03:00
catarrh 58af838e72 Decode P1/P2 for all commands; fix PIN/SEARCH RECORD references
- Always emit raw P1/P2 in decode_message (with name/bits when the spec
  provides them), so FETCH/ENVELOPE/GET RESPONSE/etc. show P1/P2.
- Add PIN key-reference table (TS 102 221 Table 9.3) and move PIN
  reference from P1 to P2 for VERIFY/CHANGE/DISABLE/ENABLE/UNBLOCK PIN.
- Fix SEARCH RECORD P2 mode bits (forward/backward/enhanced/proprietary).
- Add MANAGE CHANNEL P2 (channel number), RETRIEVE/SET DATA block mode,
  GET/PUT DATA tag, STATUS/DELETE FILE P2.
- Frontend renders raw-only P1/P2 cleanly.
2026-08-16 22:15:20 +03:00
catarrh 0fdaed503e Deepen AUTHENTICATE decode: P2 auth context + AUTN/AUTS decomposition
- Add a P2 spec for AUTHENTICATE (auth context bits + specific-reference-data
  flag), so P2 is displayed instead of only leaking through cmd.context.
- Fix P1 name to 'No indication' (was the misleading 'Run GSM algorithm').
- Decompose AUTN into SQN(xor)AK / AMF / MAC and AUTS into SQN(xor)AK / MAC-S
  per TS 33.102; surface 'specific reference data' key flag.
2026-08-16 21:44:57 +03:00
catarrh 35067f8d9d Color-code SW in APDU list + fix empty ISIM record decode
- SW column now shows green (success 90/92-9F), blue (pending 61/91/6C),
  amber (warning 62/63), red (error 64-6F) per ISO 7816-4 / TS 102 221.
- _decode_nai: treat all-FF records as empty instead of emitting
  replacement characters; strip FF padding before the ASCII fallback.
2026-08-16 13:22:01 +03:00
catarrh 747974460e Harden selection tracking against dropped/failed SELECTs
- Only update the selected-file state on a successful SELECT (SW1 in
  61/62/63/90/91/92/9E/9F); a failed SELECT (e.g. 6A82) leaves the
  current file unchanged.
- Track the file structure from the FCP (GET RESPONSE after SELECT).
- Skip file decoding for record ops (READ/UPDATE/SEARCH RECORD) when the
  selected file is transparent/DF, marking the result 'stale' instead of
  decoding garbage — this catches silently-dropped SELECTs.
2026-08-16 00:20:32 +03:00
catarrh 91cb4e6e02 Add file-aware decoding for READ/UPDATE/SEARCH RECORD
- Track the currently selected file (SELECT by FID/path) across the
  session and pass it to the decoder; reset on ATR/card change; seed via
  a bounded backward scan on paged views.
- Decode READ BINARY/RECORD, UPDATE BINARY/RECORD and (via GET RESPONSE)
  SEARCH RECORD bodies using a FILE_DECODERS registry: IMSI, ICCID,
  LI/PL, ADN-format (MSISDN/SDN/FDN/...), SMS records (SMSC + TPDU),
  UST/SST/IST service tables, PLMN lists (+access tech), EF_DIR,
  CBMI/R, ARR, PNN, ECC, SPN, LOCI, ACC, Phase, ISIM IMPI/DOMAIN/IMPU.
- File formats verified against TS 51.011 / TS 102 221 / TS 31.102
  (PLMNwAcT is 5-byte entries; EF_SMS = status + SMSC + TPDU; ISIM
  identities are 0x80 TLV).
- Offset != 0 READ BINARY/UPDATE BINARY is skipped (fragment reads).
- SEARCH RECORD results (record numbers) decoded in GET RESPONSE.
- GET RESPONSE summary now shows FCP file type/structure/size.
- New 'File data' section in the detail view.
2026-08-15 23:11:31 +03:00
catarrh 143e1854e2 Add ATR/PPS + SMS TPDU decoding, command summaries, SW column
- Decode ATR (convention, interface bytes, historical, TCK) and PPS (Fi/Di, PCK)
- Decode ENVELOPE SMS-PP DOWNLOAD + SEND SHORT MESSAGE TPDU: SCTS, VP,
  DCS/PID, UDH IEIs, best-effort 8-bit text
- Fix Duration data object ([time unit][interval], not a 16-bit int)
- List view: command summary instead of raw hex, SW column, raw APDU
  first line in detail view
- Expand FID tables (full pySim USIM/ISIM/SIM set) + context-aware
  SELECT-path resolution (7FFF = current ADF)
- Fix SELECT P1 names (0x09 = path from current DF)
- Bump version to 1.3.0
2026-08-15 21:24:50 +03:00
catarrh 5ba55ac3a9 Decode EVENT DOWNLOAD location/caller and CELL BROADCAST DOWNLOAD CB page
- EVENT DOWNLOAD: decode location information (PLMN/LAC/Cell), caller
  number (MT call Address), transaction identifier, subaddress
- CELL BROADCAST DOWNLOAD: decode CB page header (serial, message ID,
  DCS, page) with raw content hex
- frontend: render Caller/Transaction/Subaddress and CB page fields

Tests: 114.
2026-08-15 00:55:07 +03:00
catarrh e5a6000bfe parse_tlv: support BER-TLV long-form lengths
Proactive commands with a body over 127 bytes (e.g. SET UP MENU with a
long item list) use a long-form length (0x81 NN / 0x82 NN NN) in their
D0 wrapper.  Previously parse_tlv bailed on those, so the FETCH decoded
as a bare 'FETCH' without its command name or items.

Tests: 105 (long-form 1/2-byte, real SET UP MENU sample).
2026-08-13 10:24:59 +03:00
catarrh 6b2bcefbac decode_cla: label standard ETSI class bytes precisely
CLA 0x80 is the ETSI/3GPP-defined UICC/USIM class (TS 102 221 Table 10.3),
not ISO 7816-4 'proprietary'. Relabel 0x80 -> ETSI-defined (UICC/USIM),
0xA0 -> ETSI-defined (SIM/GSM), 0x00 -> inter-industry (ISO 7816-4);
drop the now-redundant note field.
2026-08-13 09:14:41 +03:00
catarrh 4e67948dce Add CAT deep decode: TR local info (PLI) + proactive command bodies
TERMINAL RESPONSE additional information:
- PLI local-info decoders by tag: Location (PLMN/LAC/Cell), IMEI (BCD),
  date-time (TS 23.040 SCTS), language, access technology, timing
  advance, battery state, network search mode, NMR
- Duration (POLL INTERVAL) and Item Identifier (SELECT ITEM)

Proactive commands (FETCH, D0 TLV, tag&0x7F normalized):
- Annex A text (0x80/0x81/0x82 UCS2 variants, else GSM-7 default) and
  DCS text decoders
- SET UP MENU / SELECT ITEM title + items, SEND SHORT MESSAGE TPDU,
  SET UP EVENT LIST events, POLL INTERVAL duration, DISPLAY TEXT etc.

Tests: 96 (TR PLI, proactive, Annex A variants, DCS text).
2026-08-13 09:00:14 +03:00
catarrh 0785e4d1df Add deeper command-body decoding: AUTHENTICATE, ENVELOPE, SM TPDU
- _decode_auth_cmd: AUTHENTICATE command body → RAND/AUTN (GSM/3G,
  context from P2)
- EVENT_TYPES + event download decode (Event List → event name,
  Location status → Normal/Limited/No service)
- _decode_envelope: D1 SMS-PP (SMSC + SMS TPDU), D2 Cell Broadcast
  (structure), D5 MO SM control (SMSC + TP-DA + location), D3/D4/D7 basic
- _decode_sm_tpdu: SMS-DELIVER/SMS-SUBMIT → TP-MTI, BCD address, TP-PID,
  TP-DCS (encoding + class), text (GSM 7-bit / UCS2 only; 8-bit stays
  hex; PID 0x7F → secured packet hex)
- helpers: _decode_bcd_address, _decode_gsm7, GSM 7-bit alphabet

decode_message stores command-body decode in decoded.cmd for
AUTHENTICATE (0x88/0x89) and ENVELOPE (0xC2).

tests: 79 total (auth-cmd, event download, SM TPDU, BCD, GSM-7).
2026-08-12 22:23:39 +03:00
catarrh 31011301ea Add PLI qualifier description to PROVIDE LOCAL INFORMATION decode
- PLI_QUALIFIERS: TS 102 223 qualifier values (Location Info, IMEI,
  NMR, Date/time, Timing Advance, Access Technology, etc.)
- _command_details_name(): appends the qualifier description to
  PROVIDE LOCAL INFORMATION (type 0x26) in Command Details
- decode_cat (FETCH) and decode_tr_command (TR) now use it, so both
  'cat_command' and 'response_to' carry the qualifier (e.g.
  'PROVIDE LOCAL INFORMATION — IMEI')

tests: PLI qualifier cases (TR/FETCH, IMEI/location/date, non-PLI)
2026-08-12 20:58:15 +03:00
catarrh f30fe41d75 Add per-command response decoders (FCP, AUTH, TERMINAL RESPONSE)
decode.py:
- _decode_fcp: FCP/FCI/FMD template — full bit-level file descriptor
  (TS 102 221 Table 11.5: file type, structure, shareable, data coding,
  record length, num records), file ID (+ KNOWN_FIDS name), DF name,
  SFI, life cycle
- _decode_auth: GSM SRES+Kc, or 3G tag DB (RES/CK/IK/KC) / DC (AUTS)
- _decode_tr_result: TERMINAL RESPONSE Result TLV (code + name)
- _decode_response_for(ins, data): GET RESPONSE decodes its body using
  the previous command's INS (SELECT→FCP, AUTHENTICATE→auth)
- decode_message wires response decoding for TR and GET RESPONSE

database.py: prev context now carries 'ins' (INS byte) via
_context_from_decoded, used by GET RESPONSE response decoding

tests: FCP, AUTH (GSM/3G), TR result, GET RESPONSE wiring (57 total)
2026-08-12 20:45:06 +03:00
catarrh e68df163a9 TERMINAL RESPONSE: label as 'TERMINAL RESPONSE', keep command type as context
decode.py: split decode_tr_command() out of decode_cat(); TR (0x14)
now stores the echoed proactive command type in 'response_to' instead
of 'cat_command', so it no longer overrides the INS name.

FETCH/ENVELOPE still use cat_command as the primary label.

tests: TR now asserts response_to + no cat_command
2026-08-12 20:02:45 +03:00
catarrh 083924c976 Add context-aware decoding for GET RESPONSE and TERMINAL RESPONSE
decode.py:
- decode_cat: TERMINAL RESPONSE (0x14) now extracts the proactive
  command type from its echoed Command Details (tag 81) — no history
  lookup needed since TR carries its own type
- decode_message gains prev param; GET RESPONSE (0xC0) resolves
  'response_for' from the previous command when its SW1 was 0x61,
  else None (orphaned)
- decode_sniff_msg threads prev through

database.py:
- _row_to_message accepts prev; new _decode_rows tracks previous-TPDU
  context in sequence; get_messages/get_messages_after seed context
  from the message before the window/cursor

tests: TR cat_command + GET RESPONSE context/orphaned cases (49 total)
2026-08-12 19:41:57 +03:00
catarrh 2a58fec0a3 Fix dropped change flags + FIDI parsing
- capture.py: DirectSniffer/GsmtapListener yield (type, data, flags),
  CaptureManager passes flags to insert_message (change flags were
  previously dropped, leaving every change row with flags=0)
- protocol.py: add _parse_fidi (1-byte value) — FIDI was mis-mapped to
  _parse_change (4-byte flags), so FIDI messages were silently dropped
- database.py: pass flags into decode_sniff_msg
- decode.py: decode_change(flags) reads flags directly; decode_sniff_msg
  gains flags parameter; change messages no longer require non-empty data
- tests: fix FIDI test, add change/fidi decode tests (43 total)
2026-08-12 19:25:14 +03:00
catarrh 11d0f29b6a Add CAT (TS 102 223) command decoding + fix AUTHENTICATE naming
- CAT_COMMAND_TYPES: complete Type of Command table from TS 102 223 §9.4
- ENVELOPE_TYPES: D1-D7 envelope tags
- parse_tlv(): minimal BER-TLV parser
- decode_cat(): FETCH → proactive command name (via D0→81 type byte);
  ENVELOPE → envelope type name
- AUTHENTICATE (0x88/0x89) unified to 'AUTHENTICATE' (no suffix)
- decoded dict gains 'cat_command' field for FETCH/ENVELOPE
- tests/test_decode.py: 14 new tests (TLV, naming, CAT, tables)
2026-08-12 18:26:58 +03:00
catarrh e211dd91bc Add decode for change, fidi, atr, pps message types
decode_sniff_msg() dispatches to type-specific decoders:
- change: 4-byte flags bitmask → card insert/eject/reset/timeout
- fidi: 1-byte Fi/Di index → decoded values
- atr/pps: raw hex value
database.py now decodes all message types, not just tpdu.
2026-08-12 17:46:03 +03:00
catarrh 7ada4345b8 Add server-side APDU decoder (decode.py)
Pure Python, no dependencies. Decodes raw TPDU bytes into
structured JSON: CLA bitfield, INS->name via APDU_SPEC table,
P1/P2 field breakdown, body extraction, SW name lookup.
~40 command types, 40+ SW codes, known FID notes.

database.py: _row_to_message() calls decode_message() for tpdu
messages, adding 'decoded' field to API responses.

Decoding happens at query time, not storage time — no schema
migration, all past sessions get decode retroactively.
2026-08-12 17:21:25 +03:00