feat: approximate NVRAM requirement from the CAP analysis (v3.5.15)

GlobalPlatform models this explicitly (GP Card Spec v2.3.1 Table 11-48,
load parameters): C6 = non-volatile code, C7 = volatile data, C8 =
non-volatile data, and 11.5.2.3.7 - when the card makes no code/data
distinction the required minimum is C6 + C8.  The analysis now reports it:

- capmem.memory_json() accepts the load file size (all CAP components -
  the package image the card stores) and returns code.load_file,
  nvram.requirement = load_file + persistent data, and sets the suggested
  C6 to the load file (the bytecode-only Method.cap figure stays in
  code.method_component); _cap_info_body passes the size it already
  computed.
- The CAP estimate box (both the RAM installer and the SCP81
  Install-from-.cap form) leads with "NVRAM requirement ≈ code image +
  data" plus the RAM estimate, keeps the bytecode/other-component split and
  the full data breakdown in Details, and carries the GP citation with the
  caveats (card memory management, allocation rounding and the registry
  entry are not included; the static field image appears in both parts).
- An older server response without code.load_file still renders (the
  bytecode size is used as the fallback).

Tests: Python +1 (load-file semantics) with extended cap-info assertions,
frontend +1 (renderer + fallback).  Help EN/RU, docs/api.md, AGENTS.

587 frontend / 472 Python green; version 3.5.15; sw simple-v268.
This commit is contained in:
2026-09-27 02:14:49 +03:00
parent 2d2a40a73c
commit 18e0db75a9
10 changed files with 112 additions and 28 deletions
+4 -2
View File
@@ -31,7 +31,7 @@ from osmocom.tlv import BER_TLV_IE
from osmocom.utils import rpad
VERSION = '3.5.14'
VERSION = '3.5.15'
MAX_ENVELOPE_SEGMENTS = 5 # max SMS segments for outgoing C-APDU in ENVELOPE
@@ -2564,7 +2564,9 @@ def _cap_info_body(body):
return {'ok': False, 'error': 'cap parse failed: %s' % e}
try:
report, memory = capmem.analyze_bytes(bytes.fromhex(cap_hex))
info = capmem.memory_json(report, memory)
# the load file (all components) is our proxy for the GP "non-volatile
# code" requirement, so the JSON can report the C6+C8-style total
info = capmem.memory_json(report, memory, load_file_bytes=len(loadfile_data) // 2)
except Exception as e:
return {'ok': False, 'error': 'cap analysis failed: %s' % e}
return {'ok': True, 'load_file_aid': loadfile_aid, 'module_aid': module_aid,