feat: CAP memory estimation with a confirm step before install (v3.5.8)
Selecting a .cap in the RAM installer or the SCP81 "Install from .cap" template now runs a read-only analysis (POST /api/cap-info) before any APDU is built: the archive is validated structurally (a corrupt or wrong-format file fails here) and the bundled capmem analyzer estimates the code size and the persistent (NVRAM) / volatile (RAM) requirements, with the tool's suggested C6/C7/C8 quotas shown as information. The form's action button (Execute / Generate) stays disabled until the analysis succeeds - pressing it is the user's confirmation to continue. - pysim_simple_server/capmem.py: bundled analyzer (component parsers + JCVM opcode table + method-bytecode allocation scan), adapted to take the CAP archive as bytes and return report/memory dicts; output verified byte-identical to the workspace tool on 21 real CAPs. - _cap_info_body + POST /api/cap-info (read-only; the install endpoints stay unchanged and self-sufficient). - PWA: shared capAnalyzeFile/capMemHtml/capGateOk helpers, estimate box under both CAP inputs (reusing the idle #ram-cap-info div, new #scripts-cap-info), data-cap-gate gating in pysimApplyAvailability, stale-response guard, Retry, EN/RU strings. - Tests: tests/test_cap_memory.py (synthetic CAPs: new/newarray/ makeTransientByteArray/static fields/unknown-opcode warnings/corrupt input), frontend capmem.test.js (renderer, gate, analyze flow). - help EN/RU, docs/api.md, AGENTS; version 3.5.8; sw cache simple-v261. 567 frontend / 429 Python green.
This commit is contained in:
+43
@@ -38,6 +38,7 @@ a 3.x PWA).
|
||||
| `/api/help` | POST | pySim help for a given command |
|
||||
| `/api/send-ota` | POST | SCP80 OTA secured packet delivery |
|
||||
| `/api/ram-install` | POST | Install a Java Card `.cap` file via SCP80 (INSTALL[for load] → LOAD ×N → INSTALL[for install]) |
|
||||
| `/api/cap-info` | POST | Validate a `.cap` archive and estimate its code/NVRAM/RAM requirements (read-only) |
|
||||
| `/api/sp-verify` | POST | Verify secured packet against pySim reference |
|
||||
| `/api/menu` | GET | Current STK menu (title + items + active) |
|
||||
| `/api/menu-select` | POST | ENVELOPE(Menu Selection) with item_id |
|
||||
@@ -319,6 +320,48 @@ same `por` structure if decoding succeeds.
|
||||
|
||||
The SPI2 `por_in_submit` bit (0x20) selects submit-mode PoR.
|
||||
|
||||
### `POST /api/cap-info`
|
||||
|
||||
Validate a Java Card `.cap` archive and estimate its memory requirements.
|
||||
Read-only: it runs the same structural parse as the install paths (so a
|
||||
corrupt or wrong-format file fails here first) plus the bundled CAP analyzer
|
||||
(`pysim_simple_server/capmem.py` — component parsers and a method-bytecode
|
||||
allocation scan). It never touches the card, the SCP81 listener or the
|
||||
scripts; the install endpoints stay self-sufficient and the estimate is not
|
||||
used for installation.
|
||||
|
||||
```json
|
||||
{"cap_hex": "504B0304..."}
|
||||
```
|
||||
|
||||
**Response (ok):**
|
||||
|
||||
```json
|
||||
{
|
||||
"ok": true,
|
||||
"load_file_aid": "AA1902BC226001", "module_aid": "AA1902BC226001",
|
||||
"load_file_bytes": 1234,
|
||||
"memory": {
|
||||
"package_aid": "AA1902BC226001",
|
||||
"applet_count": 1, "applets": ["AA1902BC226001"],
|
||||
"class_count": 3, "method_count": 12,
|
||||
"code": {"method_component": 850},
|
||||
"nvram": {"static_image": 12, "array_init": 4, "install_objects": 100,
|
||||
"header_overhead": 24, "ref_storage": 8, "total": 148, "runtime": 0},
|
||||
"ram": {"transient_arrays": 16, "runtime_transient": 0, "peak_frame": 8, "total": 24},
|
||||
"suggested": {"c6": 850, "c7": 272, "c8": 148},
|
||||
"warnings": []
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Errors** (HTTP 200 with `ok: false`, like `/api/scp81/gen-install`):
|
||||
`{"ok": false, "error": "cap parse failed: File is not a zip file"}` for a
|
||||
corrupt/wrong archive, or `cap analysis failed: …` when a component passes
|
||||
the structural parse but not the analyzer. The numbers are an estimate:
|
||||
the model assumes 2-byte references, a 6-byte object header and NVM cell
|
||||
rounding, and does not include applet-created runtime objects/arrays.
|
||||
|
||||
### `POST /api/ram-install`
|
||||
|
||||
Install a Java Card `.cap` file on the card via GlobalPlatform commands (INSTALL[for load] → LOAD ×N → INSTALL[for install (+ make selectable)]) wrapped in SCP80 secured packets. Each step is sent via ENVELOPE and its PoR is checked; the sequence aborts on the first PoR error. The `.cap` archive (a ZIP of nested components) is parsed server-side in `_cap_parse`; no external tooling is required.
|
||||
|
||||
Reference in New Issue
Block a user