Commit Graph

22 Commits

Author SHA1 Message Date
catarrh 17863001f3 v3.23.3: the low-counter notice polish
The two buttons under a cntr_low verdict shared the red warning style, and
the notice only ever rendered in the RAM pill: an SCP80 send wrote it into
the hidden RAM container, so the plain-send view showed the verdict text
but offered no way to act on it.

- The counter probe button is amber and the preset jump green (the warning
  text stays red).
- The probe renders the inline throbber the RAM operations use
  (animate-spin, no modal) while it runs; its result replaces it in the
  same box.
- Each pill carries its own notice box (#ram-cntr-low / #sp-cntr-low):
  ramShowCntrLow/ramSyncCounter target the originating view's box and
  clear the other, the SCP80 send passes 'sp' explicitly (it used to rely
  on the keyset-view heuristic), and a new send attempt clears the stale
  verdict (ramClearResults clears both boxes).
- The prebuilt Tailwind output was regenerated (npm run build):
  border-amber-300/-700 and border-emerald-300/-700 were absent from
  style.css (the stale-style trap).

Tests: the button classes, the spinner and the box targeting pinned in
ram.test.js.  846 frontend + 830 Python; sw cache simple-v416.
2026-10-07 10:28:42 +03:00
catarrh bcd9fb9a4c v3.22.0 (fix): an expanded run log stays open across the live report polls
The report view re-renders the member blocks on every poll while a suite runs
(innerHTML replacement), so an expanded Run log collapsed within 500 ms.  The
<details> now carries the stable member index (data-member) and
testRenderReport carries the open state across the re-render; the log content
keeps updating in place.

- frontend/tests/testsuites.test.js: the wiring pin (data-member emitted, the
  open state read and restored).
- sw cache simple-v400 (index.html changed); style.css rebuilt.

Tests: 837 frontend + 795 Python.
2026-10-06 00:50:24 +03:00
catarrh f71b8ab73f v3.11.0 editor polish: fixed TAR table layout, ADM placeholder
The TAR table used the default auto layout with w-full, so the browser
distributed the surplus width across all columns and TAR/MSL/description
looked evenly spread.  table-fixed with explicit column widths (TAR w-28,
MSL w-20, action w-12; the description column takes the remainder) and
w-full inputs keep the first two columns tight and left-packed.  The ADM
placeholder is just "ADM" now.  sw cache simple-v365.

Tests: 665 Python + 787 frontend green; the whole inline PWA script
syntax-checked.
2026-10-02 11:05:58 +03:00
catarrh 35eab8924a v3.11.0 editor layout: PIN/ADM + TAR side by side, codes as a vertical list
The PIN/ADM and TAR fieldsets now share one responsive row (side by side
from lg, stacked below): PIN/ADM is a fixed 224px column (lg:w-56) that
stretches to the TAR box's height, TAR takes the rest (flex-1 min-w-0).
The codes are a vertical list (label above each input) and the hint is
shortened to "All codes are optional" - the specifics stay in the input
placeholders and the help.  A structural guard pins the row and the short
hint; sw cache simple-v363.

Tests: 665 Python + 785 frontend green; the whole inline PWA script
syntax-checked.
2026-10-02 10:40:56 +03:00
catarrh 65c565e058 v3.11.0: Cards tab redesign (list + editor), preset PIN/PUK codes
The Cards tab now shows the preset list by default; "Add preset" / "Edit"
open a separate editor view (Save stores and returns to the list, Cancel
discards; ramGoToPreset opens it too).  The editor keeps the name/ICCID
header (with From card) and groups its fields into bordered blocks:
- PIN/ADM: the new optional card codes PIN1/PUK1/PIN2/PUK2 (plain text,
  4-8 decimal digits) plus ADM, moved out of the top row; nothing consumes
  the PIN/PUK codes yet.
- TAR: one uniform table (TAR, MSL, description); the first three rows are
  the fixed role entries with the immutable English descriptions "ISD
  compact format" / "UICC shared FS RFM compact format" / "ADF FS RFM
  compact format"; further rows are deletable with an optional description.
- SCP80 (keyset editor) and SCP81 (PSK pair) as before.

Store: PRESET_FIELDS gains pin1/puk1/pin2/puk2 (optional; whitespace
stripped; 4-8 decimal digits validated on save and import), SCHEMA_VERSION
4, docs/help/AGENTS updated.  TAR rows use unified ids (cards-tr-N-*), the
editor switches via cardsShowList/cardsShowEditor.

Tests: 665 Python + 783 frontend green; the whole inline PWA script
syntax-checked.  sw cache simple-v361.
2026-10-02 09:32:45 +03:00
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 0b7b6b8157 feat: RAM operations run behind a blocking modal (v3.6.34)
A CAP install is a long chain of LOAD commands whose progress and results
were only visible at the bottom of a large form - and an interrupted
install can leave a half-loaded package.

- Server: _RAM_PROGRESS (+ _ram_progress_begin/step/end) records the live
  step of the running RAM operation; /api/ram-install and
  /api/ram-install-app wrap their chains in it (total = steps + 1 for the
  format check) and /api/status carries it as ram_progress - lock-free, so
  the 2 s poll works while the request holds _CARD_LOCK.
- PWA: #ram-op-modal (the STK panel pattern) blocks everything while a RAM
  operation runs: title, spinner, status line, progress bar, per-step
  result lines, Close disabled until it finishes; a beforeunload guard
  protects the window during the run.  install-cap, install-app /
  make-selectable and Explore all use the shared helpers
  (ramOpModalBegin/Status/Finish); the install results stay in the form
  area as before once the modal is closed.  The status poll feeds the modal
  via ramOpProgress (headline from the pure ramOpProgressText).
- Tests: ramOpProgressText (JS) + the progress lifecycle (Python); the
  card-state and capmem suites stub the DOM-bound hooks.
- Stylesheet rebuilt; version 3.6.34; sw simple-v307.
2026-09-29 00:09:35 +03:00
catarrh e820a7ed41 feat: toolkit block emphasised + auto CA/EA from the CAP (v3.6.32)
The RAM install form's toolkit parameters are the make-or-break field for
toolkit applets, and CA vs EA is easy to get wrong (the earlier live 6A80s).

- "SIM/UICC Toolkit parameters" is now an accented bordered fieldset (blue
  border/legend, always visible in the cap / install / make-selectable
  modes) with the checkbox in the legend and the fields inside.
- ramCapToolkitMode(imports) maps the CAP's linked libraries to the install
  parameter family: sim.* (AID tree A0000000090003FFFFFFFF89...) -> SIM
  Toolkit (Tag CA), uicc.* / uicc.usim.* (A0000000090005FFFFFFFF89...,
  A0000000871005FFFFFFFF89...) -> UICC Toolkit (Tag EA) - family-based, so
  access-only applets get the right field too.  Applied when the block is
  enabled and when the CAP is swapped while it is on, with a "detected from
  the CAP" hint under the select; no CAP keeps the manual choice.
- Rebuilt style.css for the new accent classes; tests pin the fieldset and
  the family mapping.

663 frontend / 504 Python green; version 3.6.32; sw simple-v305.
2026-09-28 23:49:00 +03:00
catarrh c3117e90fa fix: rebuilt stylesheet + visible explorer rows (v3.6.30)
The compiled Tailwind stylesheet (frontend/style.css) had been stale since
2026-09-22: classes introduced later were missing from it, so the Install /
Make selectable chips had no background or text colour in light mode (dark
mode only looked green because an older dark:text-emerald-400 rule matched)
and the new w-28 action column did not apply.

- Rebuilt with `npm run build` (Tailwind + appended src/contrast.css);
  verified the previously missing classes (bg-emerald-100, text-emerald-700,
  hover:bg-emerald-200, bg-red-100, bg-blue-100, w-28, ...).
- Explorer rows are visible chips now: rounded bg-gray-50 dark:bg-slate-800/60
  with a hover:bg-gray-100 highlight and the colored left accent kept (module
  rows a subtler variant), so a right-column button is unambiguously tied to
  its row; ISD/app/ELF/module rows all use the same treatment.
- AGENTS working conventions: an index.html change that introduces new
  utility classes also requires `npm run build` in frontend/.

660 frontend / 504 Python green; version 3.6.30; sw simple-v303.
2026-09-28 23:38:06 +03:00
catarrh bed1852110 ui: lay the EUICCInfo2 chip fields out in two columns
The short EUICCInfo2 fields (versions, card resources, category, PPRs, …)
were one per row in the wide right-hand box, wasting half of it.

- esimChipValueWide(): a row needs the full width when its value is a
  list or a long token (>24 chars or ', '), so short scalars pair up.
- esimChipBox() gained a twoColumns mode: rows in a responsive
  grid-cols-1 sm:grid-cols-2 grid with long values spanning both columns;
  the other boxes keep their single-column rows.
- esimRenderChip() renders the EUICCInfo2 box with two columns.
- style.css rebuilt (sm:grid-cols-2, sm:col-span-2).
- tests: the wide/short rule, the two-column markup and the render call;
  help EN/RU and AGENTS note the layout; sw.js simple-v233.
2026-09-22 00:51:07 +03:00
catarrh a7ec67b19c ui: group the eSIM chip info into boxes and wrap values nicely
The chip view was one long flat list spread over the full height.

- esimRenderChip split into esimChipSectionRows (object or RAT rule list
  -> rows) and esimChipBox (titled box, skipped when empty); the boxes
  are laid out on a grid: EID, EUICCInfo1, Addresses and the rules
  authorisation table in the left column, the larger EUICCInfo2 in the
  wider right-hand box (single column on narrow screens).  Rows use a
  narrower label column (w-36).
- Values wrap with break-words + min-w-0 instead of break-all: text
  breaks at spaces first and long hex/AID tokens only when they cannot
  fit (same for the profile metadata rows).
- style.css rebuilt (grid-cols-1, lg:grid-cols-3, lg:col-span-1/2/3,
  break-words).
- tests: the new helpers, the grid/box layout and the wrapping check;
  help EN/RU note the grouping; sw.js simple-v232.
2026-09-22 00:27:31 +03:00
catarrh 0d92ea8f24 net-sim: network-condition simulation in the Phone tab (v2.5.0)
Server (pysim_simple_server/netsim.py + POST /api/net-sim):
- pure builders for the observed phone write vocabulary (UICC_NAA.md §13):
  EPSNSC (A0 TLV with KSI/KASME/counts/algo, padded to the card's FCP record
  size; invalidate-wipe and invalidate-keep-key), LOCI/PSLOCI/EPSLOCI real
  and dummy forms (PLMN kept, LAC FFFE, status 01/02), Kc/KcGPRS (9-byte
  USIM and 33-byte GSM forms, 07 invalidates), EF.SMSstatus counter bump
  (read-modify-write), CBMI/CBMIR, the Location status event (9B 01 <st>,
  with the optional 13 07 location info for normal service) and the
  AUTHENTICATE APDU (TS 31.102 7.1.2.1) with DB/DC response parsing
- scenario runner executes the recipes under _CARD_LOCK, picks the first
  existing candidate path (ADF.USIM vs DF.GSM/DF.TELECOM), reads FCP/current
  records where the format is card-specific, skips the event unless the card
  subscribed to Location status, honours the scenario toggles and returns a
  per-step log; only D6/DC, ENVELOPE and AUTHENTICATE are ever sent
- GET /api/mcc-mnc serves the optional worldwide operator list
  (--mcc-mnc-list, default <workspace>/samples/mcc-mnc-list.json): ?q=
  search and ?random=1&exclude= for roaming; the list stays out of the repo

PWA:
- Phone pill gains a 'Network simulation' fieldset: one button per scenario
  (cold boot, EPS/2G attach, service lost, limited service, roaming denied,
  churn, SMS received, CB reconfig, AUTHENTICATE), a collapsed Parameters
  block (operator search + random roaming, LAC/Cell ID/TAC/RAC, optional
  identities, toggles, churn count/delay) and a step log with SWs
- i18n EN/RU, help/README/api.md/AGENTS.md updated; version 2.5.0,
  SW cache simple-v193

Tests: tests/test_netsim.py (19), frontend/tests/netsim.test.js (3) and
html guards - 423 frontend / 280 Python, all passing
2026-09-19 22:24:57 +03:00
catarrh 158f1c676f ui: embedded labels (fieldset/legend) for the phone simulator and SCP81 containers
- Phone simulator: STK menu, STATUS and Polling, TERMINAL PROFILE and
  SET UP EVENT LIST become fieldsets with legends; 'Fetched proactive
  commands:' gains a bordered container
- SCP81 listener: the HTTP OTA listener label moves into the legend (the
  live state span stays next to it), Script results (R-APDUs) and HTTP OTA
  log become fieldsets (the log's Clear button moves to the body top-right)
- Options (applied at Start) stays a details/summary but its summary is
  styled as an embedded label (page-background patch over the top border,
  native triangle kept) so it expands/collapses from the legend
- html.test.js: card-fieldset test no longer assumes exactly two fieldsets;
  new guard test for the legends and the Options summary
- Tailwind rebuild of style.css; SW cache simple-v192 (version stays 2.4.0)
2026-09-19 21:51:03 +03:00
catarrh 74efc20bf5 theme: brighten normal dark-mode text above the muted gray level
After the gray text was raised to #cbd5e1 in dark mode, elements using
dark:text-slate-300 (inactive tabs, labels, list text) matched the muted
level. Map dark:text-slate-300 to #e2e8f0 (slate-200, the body's dark
text color) so normal text stays one step brighter than muted gray.
SW cache v96 -> v97.
2026-09-12 14:31:27 +03:00
catarrh d2bd2ed798 theme: brighten gray text and borders in dark mode
Elements using bare text-gray-300/400/500/600 (proactive log ids and
timestamps, expand markers, event codes, ...) kept the light-theme gray
values in dark mode, which made them hard to read on slate-800/900.

- dark .text-gray-*:not([class*='dark:text-']) rules map them to the same
  level as the other dark muted text (slate-300 #cbd5e1, slate-200/100 for
  gray-700/800)
- dark:text-gray-400/600 and dark:text-slate-500 normalized to #cbd5e1
- dark:border-slate-600/700/800 (+ /50) brightened one step
- light theme unchanged
- the whole contrast block moved to src/contrast.css, appended by the
  npm build scripts after Tailwind so it stays reproducible; SW cache
  v95 -> v96
2026-09-12 14:28:41 +03:00
catarrh 5c279147c1 theme: darker light-gray shades (light), lighter gray fonts (dark); larger profiler progress
- Light theme: darken bg-gray-50/100/200, border-gray-100/200/300,
  text-gray-300 and hover variants one step
- Dark theme: lighten dark:text-gray-400/600 gray fonts
- Profiler: bump 'Checking ..' progress line from text-xs to text-base

SW cache v42.
2026-09-09 22:37:30 +03:00
catarrh 330a1f0070 fonts: bump text-xs (extra small) to text-sm size
Redefine .text-xs to render at 0.875rem/1.25rem (text-sm), covering the PWA
and both help pages via the shared stylesheet. Explicit leading-* overrides
still apply.

SW cache v41.
2026-09-09 22:28:22 +03:00
catarrh 1daced1e18 theme: increase contrast of muted text, lighten red in dark mode
- Light theme: darken gray-400/500/600 muted text one step
- Dark theme: lighten slate-400/500 muted text one step
- Dark theme: lighten red-500/600/700 text (was too dark on dark bg)

SW cache v40.
2026-09-09 22:21:28 +03:00
catarrh b832372ac8 C-APDU Parser: indigo hex data color + rebuild CSS 2026-08-20 23:21:03 +03:00
catarrh 80a860549a v1.8.0: proactive log overhaul, Expanded Script rename, proactive view sizing
Server:
- Track all TERMINAL RESPONSEs (chain, TP, pySim auto-handler, menu-respond
  link to paused entry) with shared _build_tr/_record_tr
- Log entry ids + cmd_num; server-side decode of fetched commands and TRs
  (compact PLI port); Result CTLV extracted as tr_result/tr_result_name
- _LoggingApduTracer captures TR SW for pySim auto-handler responses
- _DefaultProactiveHandler answers PLI with editor data (no re-request)
- VERSION 1.8.0

Frontend:
- Expandable proactive log rows (click to expand, state survives re-render)
- Response section: Result name + hex, decoded fields, width-restrained
  readonly hex inputs; no SW display
- Rename Expanded Script tab/pill/button/docs; proactive UICC view font
  sizing increase; card reader pills text-sm
2026-08-19 18:04:08 +03:00
catarrh a916e8a255 PLI list: vertical layout, full descriptions, wider inputs, row separators
- Drop truncation: full qualifier descriptions (wrap)
- Raw hex input moves under the description, fills row width (flex-1)
- Subtle bottom-border separator between qualifiers
2026-08-16 00:47:06 +03:00
catarrh d2c292e5b8 Merge pysim-otaman-server into otaman (monorepo, v1.7.0)
- Move PWA into frontend/; server package at pysim_otaman_server/
- Server now serves the PWA (same origin -> no CORS/PNA): static file handler
  + --web-dir flag + injects window.PYSIM_EMBEDDED marker into index.html
- Frontend defaults to relative API base when embedded (pysimBase = '')
- Version 1.7.0 aligned: server.py VERSION, pyproject.toml, PWA header
- SW cache bump otaman-v7 -> otaman-v8
- Docs: combined README + docs/api.md endpoint reference; update links
- Fix stale package.json repository URL
2026-08-14 15:48:38 +03:00