Commit Graph

11 Commits

Author SHA1 Message Date
catarrh 6360dc5bae v3.10.0: preset TAR table with per-TAR MSL; derive the SPI1 from the TAR
Presets drop the card-wide SPI1/SPI2 and the fixed tar/uiccTar/usimTar
fields: a preset now carries `tars` - the three mandatory role entries
(isd/uiccRfm/usimRfm, spec defaults pre-settled) plus free TARs with an
optional description, each with its MSL (Minimum SPI1, TS 102 226
8.2.1.3.2.4).  v3.9.1 presets convert on load/import (the spi1 seeds all
three MSLs); duplicate TARs and empty TAR/MSL values are refused; the
store schema version is 3.

Operations derive a packet's SPI1 from its TAR's MSL (_spi1_for_tar): the
RAM ops, the test runner (per-step overrides still win), the counter probe
and each TAR-probe row; the plain send keeps an explicit SPI1 with a
`warning` when it is below the MSL, and a TAR outside the preset without an
explicit SPI1 is refused with a hint.  The TAR probe resolves per checked
TAR before sending and reports the effective spi1 per row.  The secured
packet form's SPI2 default is 00 (the RAM/probe operations pin their own).

PWA: the Cards form edits the TAR table (role rows with MSL inputs plus
Add/Remove free rows with a description), the list shows a TARs (MSL)
column, the SCP80 TAR field suggests the preset's entries (datalist) and a
preset apply seeds the SPI1 from the operation TAR's MSL with an amber
warning below it; the preset-wide SPI1/SPI2 fields and the header marker's
SPI requirement are gone (completeness = a keyset + the three role entries
with their MSLs).  Help EN/RU, docs/api.md and AGENTS updated; sw cache
simple-v358.

Live: TAR probe 000000 at its MSL 16 (registered, por_ok, counter
advanced); a send without spi1 derived 16 (por_ok, counter advanced); a
send with spi1 0A returned the warning and the card refused it (6200, no
counter consumed); an unknown TAR without spi1 was refused with the hint.
2026-10-02 08:28:46 +03:00
catarrh 0cccd62230 release: v3.9.0 - the operation start buttons wait for a preset and a keyset
Gating: the SCP80 "Send to Card", the RAM Execute and the TAR-probe Execute
buttons carry `data-needs-keyset`; pysimApplyAvailability() disables them
(with the hint "Select a card preset and its keyset" when the card itself is
fine) unless the view's preset is selected and the form's keyset number is one
of its keysets - `spKeysetStartReady`, the same rule the click-time guards
enforce, which stay as the last line of defence.  spKeysetSync() refreshes the
gate on every preset/keyset change, and the KIc/KID index selects now call
spKeysetSync() so the keyset selector follows a manual index change too.

Version 3.9.0: server VERSION, pyproject.toml and the PWA header; sw cache
simple-v346; the workspace AGENTS gains its v3.9.0 history entry.

Tests: indicator.test.js drives the gate (no preset -> disabled with the hint,
an undefined keyset -> disabled, a matching keyset -> enabled) and guards the
three buttons' attribute; the cards/keysets/ram sandboxes stub
pysimApplyAvailability.  Help EN/RU notes the disabled start buttons.
2026-10-01 22:03:36 +03:00
catarrh 722e237ea4 feat: Test script pill in the Phone simulator (v3.5.11)
- Phone simulator tab: a fourth pill **Test script** - script list
  (localStorage `simple_tests`) with New/Clone/Delete/Export/Import, a
  form-based step editor (modal) and a run panel.
- Actions: ENVELOPE (Event Download), Menu Selection, UPDATE/READ file by
  path, raw APDU, SCP80 (C-APDU or a pre-built packet, per-step TAR/SPI1/
  SPI2 overrides; the preset is matched by the equipped card's ICCID and
  the final counter is written back) and STATUS with an optional poll.
  Every action has SW/data checks (exact or ?-mask) and a PoR check for
  SCP80, with an error (stops) / warning (continues) fail level.
- Expectations: FETCH the command announced by the previous step, verify
  type/qualifier/text/item/raw and answer with the scripted TERMINAL
  RESPONSE (result, item id, text, extra TLVs); templates for STK menu
  browsing and an applet via SCP80.
- Run panel: progress banner (plus a marker on the pill), per-step
  OK/Warning/Error badges with expected vs actual values, sent/received
  hex, decoded commands and the SCP80 counter; 500 ms polling while a run
  is active, and a running script disables other card controls
  (data-needs gate; the server answers 409 to other card endpoints).
- Help EN/RU (8.9 Test script), AGENTS; version 3.5.11; sw simple-v264.

579 frontend / 467 Python green.
2026-09-27 01:19:32 +03:00
catarrh e9f0a50ea5 ui: gate Read decoded on client-side decoder availability (v2.7.10)
Files without a client-side decoder used to fall back to a raw view when
the Decoded pill was pressed.  The decoder is resolved by name/FID
(efFindDecoder) before any read, so the pill can be disabled instead.

- pysimFsHasDecoder() mirrors the decoded view's resolution (tree node
  name, FID fallback).
- pysimApplyAvailability() honours a new data-needs-decoder marker:
  disabled with the existing 'No decoder for this file' tooltip; the
  card hint still wins when no card is equipped.
- pysimFsClickFile() re-runs the availability pass after selecting a
  file; pysimFsSetMode('dec') ignores the call without a decoder.
- tests: indicator (enable/disable/tooltip precedence), fs_edit
  (decoded guard, name/FID resolution); help EN/RU.
2026-09-20 23:21:06 +03:00
catarrh 81b50199cc ui: bordered header badges and ICCID-labelled card actions (v2.6.2)
- ADM/SCP80/SCP81 header indicators become bordered chips (neutral gray
  border, rounded, px-1.5 py-0.5); SCP80/SCP81 get an even ml-1 gap, so no
  separator glyph is needed
- profiler/snapshot card actions carry the equipped card's ICCID:
  'Profile from card <ICCID>', 'Check card <ICCID>' (row button, arrow
  dropped), 'New snapshot: <ICCID>'; pysimUpdateCardActionLabels() fills
  the spans on every status poll and after a language switch
- these buttons switch to data-needs='card-iccid': disabled without a
  readable ICCID ('Card equipped but its ICCID is not readable' hint)
- profiler rows wrap so the longer button cannot break the layout;
  help EN/RU updated; SW cache simple-v202
2026-09-20 01:40:39 +03:00
catarrh 97bc8f929d ui: header preset indicators — ADM key glyph, SCP80/SCP81 completeness (v2.6.1)
- the ADM badge gains a trailing key glyph (ADM ✓ ⚿ / ADM ✗ ⚿) when the
  preset matching the equipped card's ICCID carries an ADM key; the four
  tooltip states cover key/no-key x verified/not-verified
- new gray SCP80/SCP81 markers after ADM, shown only when that preset has
  all SCP80 fields (KIc/KID, SPI1/SPI2, counter, KIc/KID keys) or the SCP81
  PSK pair filled in; hidden without a card session, a matching preset or
  the fields, never color-coded
- cardsScp80Complete/cardsScp81Complete/cardsAdmPresent/cardsMatchedPreset
  helpers; cardsRender reuses the SCP81 predicate
- tests: ADM four-state badge, marker show/hide, predicate whitespace
  handling, header markup order; help EN/RU updated; SW cache simple-v201
2026-09-20 01:08:44 +03:00
catarrh ccabef883e ui: print the equipped card's ICCID in the header indicator (v2.5.2)
- new #state-indicator-iccid span between the card image and the ADM badge;
  shows the EF.ICCID digits of the equipped card (hidden without a card
  session or when the ICCID is unreadable, cleared when the server is lost)
- pysimUpdateIccidIndicator() mirrors the ADM badge pattern (no rewrite when
  the value is unchanged); wired into pysimCardStateUpdate() and
  pysimSetServerAvailable()
- indicator/card_state tests for show/hide and markup order;
  SW cache simple-v197
2026-09-19 23:40:08 +03:00
catarrh ce7d91cfe0 cards: From card button + normalized duplicate ICCID refusal (v2.2.18)
- The card create/edit form gets a From card button next to the ICCID
  field: it fills the field with the equipped card's EF.ICCID. It uses the
  availability model through a new 'card-iccid' requirement - enabled only
  while /api/status reports a connected card with a readable iccid; with a
  card but no readable ICCID the tooltip says so, otherwise the usual
  'insert and equip' hint applies. The last status ICCID is kept in
  _pysimCardIccid (cleared on disconnect) so the click needs no round-trip.
- Duplicate ICCID refusal now compares normalized values via
  cardsNormIccid/cardsFindDuplicateIccid (digits, spaced digits and raw EF
  hex all identify the same card), skips the row being edited, ignores an
  empty field, and names the conflicting preset in the alert (translated).
- i18n RU: From card -> 'С карты', duplicate/unreadable alerts.
- Tests: cardsFindDuplicateIccid across formats and edit-skip,
  cardsIccidFromCard fill + alert path, form wiring guards, _pysimCardIccid
  tracking in the card-state harness, card-iccid availability gating in the
  indicator harness. 261 Python + 400 frontend tests green.
- Docs: help EN+RU Cards field table, READMEs, AGENTS. SW otaman-v185.
2026-09-18 23:57:05 +03:00
catarrh f16e24ba11 ui: enlarge the header sim/nosim icon to 30px
- the SVG artwork occupies only ~46% x 63% of its 183x183 canvas, so
  the 18px render showed ~8x11px of ink; 30px roughly doubles the
  visible glyph while staying under the 32px h1 line-height, so the
  header row height is unchanged
- guard test asserts the inline size stays within the 24-32px budget;
  SW cache v112 -> v113.
2026-09-12 20:03:03 +03:00
catarrh 56c0e60462 ui: tooltip on the status dot shows the server state
- the dot carries its own title (Connecting... / No server connection),
  matching the wrapper tooltip; it is cleared when the sim icons replace
  the dot
- tests assert the dot title in both server states and its removal once
  the server is up; SW cache v110 -> v111.
2026-09-12 19:55:14 +03:00
catarrh 68aa37f093 ui: header indicator shows sim/nosim icons once the server is up
- #state-indicator is now a wrapper with a dot plus an 18px dark:invert
  image; no new compiled Tailwind classes (h-4/w-5 are not in the
  prebuilt CSS), so sizing uses an inline style and the header height
  is unchanged
- gray dot while probing, red dot when the server is unreachable;
  server up -> nosim.svg, animated sim_anim.svg while equipping, and
  sim.svg when the card is equipped (`_pysimEquipping` tracked from
  status.equipping, refreshed on every 2s poll)
- i18n reuses existing strings; tests for all five states, dot color
  transitions and the markup; SW cache v109 -> v110.
2026-09-12 19:53:29 +03:00