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.
This commit is contained in:
2026-10-02 08:28:46 +03:00
parent f059d05040
commit 6360dc5bae
19 changed files with 1187 additions and 269 deletions
+25 -6
View File
@@ -672,8 +672,8 @@ video {
z-index: 50;
}
.col-span-2 {
grid-column: span 2 / span 2;
.col-span-3 {
grid-column: span 3 / span 3;
}
.col-span-4 {
@@ -843,6 +843,10 @@ video {
max-height: 14rem;
}
.max-h-64 {
max-height: 16rem;
}
.max-h-\[30vh\] {
max-height: 30vh;
}
@@ -996,10 +1000,6 @@ video {
max-width: 80rem;
}
.max-w-lg {
max-width: 32rem;
}
.max-w-md {
max-width: 28rem;
}
@@ -1386,6 +1386,11 @@ video {
background-color: rgb(209 250 229 / var(--tw-bg-opacity, 1));
}
.bg-emerald-50 {
--tw-bg-opacity: 1;
background-color: rgb(236 253 245 / var(--tw-bg-opacity, 1));
}
.bg-emerald-600 {
--tw-bg-opacity: 1;
background-color: rgb(5 150 105 / var(--tw-bg-opacity, 1));
@@ -1900,6 +1905,11 @@ video {
background-color: rgb(55 65 81 / var(--tw-bg-opacity, 1));
}
.hover\:bg-red-100:hover {
--tw-bg-opacity: 1;
background-color: rgb(254 226 226 / var(--tw-bg-opacity, 1));
}
.hover\:bg-red-200:hover {
--tw-bg-opacity: 1;
background-color: rgb(254 202 202 / var(--tw-bg-opacity, 1));
@@ -1981,6 +1991,11 @@ video {
border-color: rgb(30 64 175 / var(--tw-border-opacity, 1));
}
.dark\:border-red-700:is(.dark *) {
--tw-border-opacity: 1;
border-color: rgb(185 28 28 / var(--tw-border-opacity, 1));
}
.dark\:border-red-800:is(.dark *) {
--tw-border-opacity: 1;
border-color: rgb(153 27 27 / var(--tw-border-opacity, 1));
@@ -2162,6 +2177,10 @@ video {
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
}
.dark\:hover\:bg-red-900\/40:hover:is(.dark *) {
background-color: rgb(127 29 29 / 0.4);
}
.dark\:hover\:bg-red-900\/50:hover:is(.dark *) {
background-color: rgb(127 29 29 / 0.5);
}