Files view: name the phonebook files from the card's EF_PBR (v2.7.7)

- EF_PBR (TS 31.102 §4.4.2.1) is the card's declaration of its phonebook:
  the constructed tags A8/A9/AA announce the type-1/2/3 groups and each nested
  primitive tag C0…CC names the file kind plus its FID — and, in a three-byte
  object, its SFI (length 2 = FID only).  pySim has no parser for it (its
  EF_PBR class still carries a "# TODO: a80ac0034f3a…" stub), so the decoder
  follows the spec: new simtrace_analyser/pbr.py
- the tracker decodes every EF_PBR record it observes (a READ RECORD's data
  or an UPDATE RECORD's body) and uses it for the DF it belongs to: the
  phonebook files get their symbolic names (4FA1 = EF_PBC, 4F3A = EF_ADN,
  4F01 = EF_IAP, 4F4A = EF_EXT1, 4F3D = EF_CCP1, 4F61 = EF_EMAIL, …), an
  earlier placeholder name is upgraded when the PBR arrives later, and the
  declared SFIs feed the DF's SFI→FID map (so SFI-addressed reads resolve
  without waiting for an FCP)
- verified on the live sessions 47/193:
  DF_TELECOM/DF_PHONEBOOK/EF_PBC (4FA1) and the SFI map
  {2→4F3A, 4→4FA1, 6→4F4A, 7→4F4F}
- also fixed: the "SFI = FID's five low bits" fallback (TS 102 221
  §11.1.1.4.8) no longer applies to a DF/ADF's FCP, which has no SFI
- tests: tests/test_pbr.py (the two real records, SFI-less objects, padding,
  truncation, merging, the shape check) and tracker cases (names, path,
  SFI map, the later-PBR upgrade); 537 Python + 76 Node tests
- README/README_RUS document the PBR naming; PWA_VERSION/pyproject/
  version.py 2.7.7, SW cache simtrace-analyser-v87
This commit is contained in:
catarrh committed 2026-10-18 01:18:26 +03:00
1 parent 5dea6bceb8
commit ac424e67e3
13 files changed
+283 -9

No files matched your search

+31
View File
@@ -560,6 +560,37 @@ class TestDfChain(TrackerCase):
self.assertEqual(entry['n_records'], 100)
class TestPbrNames(TrackerCase):
def test_pbr_names_the_phonebook_files(self):
# The card's EF_PBR declares the phonebook files' FIDs, roles and SFIs
# (TS 31.102 §4.4.2.1): 4FA1 = EF_PBC with SFI 4.
pbr_rec = 'a80ac0034f3a02c5034fa104aa0ac2034f4a06cb034f4f07'
data = self.track(
sel_path('7f105f3a'), gr(fcp('5f3a')),
sel_fid('4f30'), gr(fcp('4f30', rec_len=24, n_rec=1)),
read_record(1, pbr_rec),
sel_fid('4fa1'), gr(fcp('4fa1', rec_len=44, n_rec=100)),
)
entry = data['files']['5f3a/4fa1']
self.assertEqual(entry['name'], 'EF_PBC')
self.assertEqual(entry['path'],
'DF_TELECOM/DF_PHONEBOOK/EF_PBC (4FA1)')
# The PBR's SFI feeds the DF's SFI relation map.
self.assertEqual(data['sfi_relations'].get('5f3a', {}).get('4'), '4fa1')
def test_pbr_name_upgrades_an_earlier_placeholder(self):
# A file seen before its PBR record is named once the record arrives.
pbr_rec = 'a80ac0034f3a02c5034fa104aa0ac2034f4a06cb034f4f07'
data = self.track(
sel_path('7f105f3a'), gr(fcp('5f3a')),
sel_fid('4fa1'), gr(fcp('4fa1', rec_len=44, n_rec=100)),
sel_fid('4f30'), gr(fcp('4f30', rec_len=24, n_rec=1)),
read_record(1, pbr_rec),
)
entry = data['files']['5f3a/4fa1']
self.assertEqual(entry['name'], 'EF_PBC')
class TestFilePath(unittest.TestCase):
def test_paths(self):
from simtrace_analyser.filetrack import _file_path