uicc_files: supplement optional files missing from pySim's model
Add a supplement to the cardless registry generator for the 13 files the Services editor's FS check references but pySim does not emit (optional, service-gated): EF.LRPLMNSI/IAL/IPD/3GPPPSDATAOFF/TVCONFIG, DF.MExE + EF.MExE-ST/ORPK/ARPK/TPRPK, DF.SoLSA + EF.SAI/EF.SLL, DF.BCAST, DF.ACDC + EF.ACDC_LIST, DF.TV, and DF.A2X + EF.AST/EF.A2X_CONFIG (under DF.TELECOM). Emitted with distinct (name, path) so same-FID files in other DFs (EF.SAI vs EF.PBR, EF.AST) stay separate; ADF.USIM rows are mirrored to ADF.USIM-NON-IMSI. 490 -> 527 entries. Regenerated the asset; test_uicc_files.py pins the 20 new paths, the FID-collision cases and (name, root) uniqueness. 1091 Python tests.
This commit is contained in:
1 parent
12ff552df8
commit
a1892094f4
3 files changed
+414
-1
No files matched your search
+297
-1
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"generated": "2026-09-23",
|
"generated": "2026-10-25",
|
||||||
"files": [
|
"files": [
|
||||||
{
|
{
|
||||||
"path": "MF/2F00",
|
"path": "MF/2F00",
|
||||||
@@ -161,6 +161,30 @@
|
|||||||
"kind": "ef",
|
"kind": "ef",
|
||||||
"root": "MF"
|
"root": "MF"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "MF/7F10/5F3F",
|
||||||
|
"name": "DF.A2X",
|
||||||
|
"sym": "MF/DF.TELECOM/DF.A2X",
|
||||||
|
"fid": "5F3F",
|
||||||
|
"kind": "df",
|
||||||
|
"root": "MF"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "MF/7F10/5F3F/4F01",
|
||||||
|
"name": "EF.AST",
|
||||||
|
"sym": "MF/DF.TELECOM/DF.A2X/EF.AST",
|
||||||
|
"fid": "4F01",
|
||||||
|
"kind": "ef",
|
||||||
|
"root": "MF"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "MF/7F10/5F3F/4F02",
|
||||||
|
"name": "EF.A2X_CONFIG",
|
||||||
|
"sym": "MF/DF.TELECOM/DF.A2X/EF.A2X_CONFIG",
|
||||||
|
"fid": "4F02",
|
||||||
|
"kind": "ef",
|
||||||
|
"root": "MF"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "MF/7F10/6F3A",
|
"path": "MF/7F10/6F3A",
|
||||||
"name": "EF.ADN",
|
"name": "EF.ADN",
|
||||||
@@ -1030,6 +1054,46 @@
|
|||||||
"kind": "ef",
|
"kind": "ef",
|
||||||
"root": "ADF.USIM"
|
"root": "ADF.USIM"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "ADF.USIM/5F3C",
|
||||||
|
"name": "DF.MExE",
|
||||||
|
"sym": "ADF.USIM/DF.MExE",
|
||||||
|
"fid": "5F3C",
|
||||||
|
"kind": "df",
|
||||||
|
"root": "ADF.USIM"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "ADF.USIM/5F3C/4F40",
|
||||||
|
"name": "EF.MExE-ST",
|
||||||
|
"sym": "ADF.USIM/DF.MExE/EF.MExE-ST",
|
||||||
|
"fid": "4F40",
|
||||||
|
"kind": "ef",
|
||||||
|
"root": "ADF.USIM"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "ADF.USIM/5F3C/4F41",
|
||||||
|
"name": "EF.ORPK",
|
||||||
|
"sym": "ADF.USIM/DF.MExE/EF.ORPK",
|
||||||
|
"fid": "4F41",
|
||||||
|
"kind": "ef",
|
||||||
|
"root": "ADF.USIM"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "ADF.USIM/5F3C/4F42",
|
||||||
|
"name": "EF.ARPK",
|
||||||
|
"sym": "ADF.USIM/DF.MExE/EF.ARPK",
|
||||||
|
"fid": "4F42",
|
||||||
|
"kind": "ef",
|
||||||
|
"root": "ADF.USIM"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "ADF.USIM/5F3C/4F43",
|
||||||
|
"name": "EF.TPRPK",
|
||||||
|
"sym": "ADF.USIM/DF.MExE/EF.TPRPK",
|
||||||
|
"fid": "4F43",
|
||||||
|
"kind": "ef",
|
||||||
|
"root": "ADF.USIM"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "ADF.USIM/5F40",
|
"path": "ADF.USIM/5F40",
|
||||||
"name": "DF.WLAN",
|
"name": "DF.WLAN",
|
||||||
@@ -1182,6 +1246,38 @@
|
|||||||
"kind": "ef",
|
"kind": "ef",
|
||||||
"root": "ADF.USIM"
|
"root": "ADF.USIM"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "ADF.USIM/5F70",
|
||||||
|
"name": "DF.SoLSA",
|
||||||
|
"sym": "ADF.USIM/DF.SoLSA",
|
||||||
|
"fid": "5F70",
|
||||||
|
"kind": "df",
|
||||||
|
"root": "ADF.USIM"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "ADF.USIM/5F70/4F30",
|
||||||
|
"name": "EF.SAI",
|
||||||
|
"sym": "ADF.USIM/DF.SoLSA/EF.SAI",
|
||||||
|
"fid": "4F30",
|
||||||
|
"kind": "ef",
|
||||||
|
"root": "ADF.USIM"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "ADF.USIM/5F70/4F31",
|
||||||
|
"name": "EF.SLL",
|
||||||
|
"sym": "ADF.USIM/DF.SoLSA/EF.SLL",
|
||||||
|
"fid": "4F31",
|
||||||
|
"kind": "ef",
|
||||||
|
"root": "ADF.USIM"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "ADF.USIM/5F80",
|
||||||
|
"name": "DF.BCAST",
|
||||||
|
"sym": "ADF.USIM/DF.BCAST",
|
||||||
|
"fid": "5F80",
|
||||||
|
"kind": "df",
|
||||||
|
"root": "ADF.USIM"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "ADF.USIM/5F90",
|
"path": "ADF.USIM/5F90",
|
||||||
"name": "DF.ProSe",
|
"name": "DF.ProSe",
|
||||||
@@ -1302,6 +1398,30 @@
|
|||||||
"kind": "ef",
|
"kind": "ef",
|
||||||
"root": "ADF.USIM"
|
"root": "ADF.USIM"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "ADF.USIM/5FA0",
|
||||||
|
"name": "DF.ACDC",
|
||||||
|
"sym": "ADF.USIM/DF.ACDC",
|
||||||
|
"fid": "5FA0",
|
||||||
|
"kind": "df",
|
||||||
|
"root": "ADF.USIM"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "ADF.USIM/5FA0/4F01",
|
||||||
|
"name": "EF.ACDC_LIST",
|
||||||
|
"sym": "ADF.USIM/DF.ACDC/EF.ACDC_LIST",
|
||||||
|
"fid": "4F01",
|
||||||
|
"kind": "ef",
|
||||||
|
"root": "ADF.USIM"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "ADF.USIM/5FB0",
|
||||||
|
"name": "DF.TV",
|
||||||
|
"sym": "ADF.USIM/DF.TV",
|
||||||
|
"fid": "5FB0",
|
||||||
|
"kind": "df",
|
||||||
|
"root": "ADF.USIM"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "ADF.USIM/5FC0",
|
"path": "ADF.USIM/5FC0",
|
||||||
"name": "DF.5GS",
|
"name": "DF.5GS",
|
||||||
@@ -2262,6 +2382,14 @@
|
|||||||
"kind": "ef",
|
"kind": "ef",
|
||||||
"root": "ADF.USIM"
|
"root": "ADF.USIM"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "ADF.USIM/6FDC",
|
||||||
|
"name": "EF.LRPLMNSI",
|
||||||
|
"sym": "ADF.USIM/EF.LRPLMNSI",
|
||||||
|
"fid": "6FDC",
|
||||||
|
"kind": "ef",
|
||||||
|
"root": "ADF.USIM"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "ADF.USIM/6FDD",
|
"path": "ADF.USIM/6FDD",
|
||||||
"name": "EF.NAFKCA",
|
"name": "EF.NAFKCA",
|
||||||
@@ -2358,6 +2486,14 @@
|
|||||||
"kind": "ef",
|
"kind": "ef",
|
||||||
"root": "ADF.USIM"
|
"root": "ADF.USIM"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "ADF.USIM/6FF0",
|
||||||
|
"name": "EF.IAL",
|
||||||
|
"sym": "ADF.USIM/EF.IAL",
|
||||||
|
"fid": "6FF0",
|
||||||
|
"kind": "ef",
|
||||||
|
"root": "ADF.USIM"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "ADF.USIM/6FF1",
|
"path": "ADF.USIM/6FF1",
|
||||||
"name": "EF.IPS",
|
"name": "EF.IPS",
|
||||||
@@ -2366,6 +2502,14 @@
|
|||||||
"kind": "ef",
|
"kind": "ef",
|
||||||
"root": "ADF.USIM"
|
"root": "ADF.USIM"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "ADF.USIM/6FF2",
|
||||||
|
"name": "EF.IPD",
|
||||||
|
"sym": "ADF.USIM/EF.IPD",
|
||||||
|
"fid": "6FF2",
|
||||||
|
"kind": "ef",
|
||||||
|
"root": "ADF.USIM"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "ADF.USIM/6FF3",
|
"path": "ADF.USIM/6FF3",
|
||||||
"name": "EF.ePDGId",
|
"name": "EF.ePDGId",
|
||||||
@@ -2414,6 +2558,22 @@
|
|||||||
"kind": "ef",
|
"kind": "ef",
|
||||||
"root": "ADF.USIM"
|
"root": "ADF.USIM"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "ADF.USIM/6FF9",
|
||||||
|
"name": "EF.3GPPPSDATAOFF",
|
||||||
|
"sym": "ADF.USIM/EF.3GPPPSDATAOFF",
|
||||||
|
"fid": "6FF9",
|
||||||
|
"kind": "ef",
|
||||||
|
"root": "ADF.USIM"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "ADF.USIM/6FFB",
|
||||||
|
"name": "EF.TVCONFIG",
|
||||||
|
"sym": "ADF.USIM/EF.TVCONFIG",
|
||||||
|
"fid": "6FFB",
|
||||||
|
"kind": "ef",
|
||||||
|
"root": "ADF.USIM"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "ADF.USIM/6FFC",
|
"path": "ADF.USIM/6FFC",
|
||||||
"name": "EF.XCAPConfigData",
|
"name": "EF.XCAPConfigData",
|
||||||
@@ -2527,6 +2687,46 @@
|
|||||||
"kind": "ef",
|
"kind": "ef",
|
||||||
"root": "ADF.USIM-NON-IMSI"
|
"root": "ADF.USIM-NON-IMSI"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "ADF.USIM-NON-IMSI/5F3C",
|
||||||
|
"name": "DF.MExE",
|
||||||
|
"sym": "ADF.USIM-non-IMSI/DF.MExE",
|
||||||
|
"fid": "5F3C",
|
||||||
|
"kind": "df",
|
||||||
|
"root": "ADF.USIM-NON-IMSI"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "ADF.USIM-NON-IMSI/5F3C/4F40",
|
||||||
|
"name": "EF.MExE-ST",
|
||||||
|
"sym": "ADF.USIM-non-IMSI/DF.MExE/EF.MExE-ST",
|
||||||
|
"fid": "4F40",
|
||||||
|
"kind": "ef",
|
||||||
|
"root": "ADF.USIM-NON-IMSI"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "ADF.USIM-NON-IMSI/5F3C/4F41",
|
||||||
|
"name": "EF.ORPK",
|
||||||
|
"sym": "ADF.USIM-non-IMSI/DF.MExE/EF.ORPK",
|
||||||
|
"fid": "4F41",
|
||||||
|
"kind": "ef",
|
||||||
|
"root": "ADF.USIM-NON-IMSI"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "ADF.USIM-NON-IMSI/5F3C/4F42",
|
||||||
|
"name": "EF.ARPK",
|
||||||
|
"sym": "ADF.USIM-non-IMSI/DF.MExE/EF.ARPK",
|
||||||
|
"fid": "4F42",
|
||||||
|
"kind": "ef",
|
||||||
|
"root": "ADF.USIM-NON-IMSI"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "ADF.USIM-NON-IMSI/5F3C/4F43",
|
||||||
|
"name": "EF.TPRPK",
|
||||||
|
"sym": "ADF.USIM-non-IMSI/DF.MExE/EF.TPRPK",
|
||||||
|
"fid": "4F43",
|
||||||
|
"kind": "ef",
|
||||||
|
"root": "ADF.USIM-NON-IMSI"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "ADF.USIM-NON-IMSI/5F40",
|
"path": "ADF.USIM-NON-IMSI/5F40",
|
||||||
"name": "DF.WLAN",
|
"name": "DF.WLAN",
|
||||||
@@ -2679,6 +2879,38 @@
|
|||||||
"kind": "ef",
|
"kind": "ef",
|
||||||
"root": "ADF.USIM-NON-IMSI"
|
"root": "ADF.USIM-NON-IMSI"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "ADF.USIM-NON-IMSI/5F70",
|
||||||
|
"name": "DF.SoLSA",
|
||||||
|
"sym": "ADF.USIM-non-IMSI/DF.SoLSA",
|
||||||
|
"fid": "5F70",
|
||||||
|
"kind": "df",
|
||||||
|
"root": "ADF.USIM-NON-IMSI"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "ADF.USIM-NON-IMSI/5F70/4F30",
|
||||||
|
"name": "EF.SAI",
|
||||||
|
"sym": "ADF.USIM-non-IMSI/DF.SoLSA/EF.SAI",
|
||||||
|
"fid": "4F30",
|
||||||
|
"kind": "ef",
|
||||||
|
"root": "ADF.USIM-NON-IMSI"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "ADF.USIM-NON-IMSI/5F70/4F31",
|
||||||
|
"name": "EF.SLL",
|
||||||
|
"sym": "ADF.USIM-non-IMSI/DF.SoLSA/EF.SLL",
|
||||||
|
"fid": "4F31",
|
||||||
|
"kind": "ef",
|
||||||
|
"root": "ADF.USIM-NON-IMSI"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "ADF.USIM-NON-IMSI/5F80",
|
||||||
|
"name": "DF.BCAST",
|
||||||
|
"sym": "ADF.USIM-non-IMSI/DF.BCAST",
|
||||||
|
"fid": "5F80",
|
||||||
|
"kind": "df",
|
||||||
|
"root": "ADF.USIM-NON-IMSI"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "ADF.USIM-NON-IMSI/5F90",
|
"path": "ADF.USIM-NON-IMSI/5F90",
|
||||||
"name": "DF.ProSe",
|
"name": "DF.ProSe",
|
||||||
@@ -2799,6 +3031,30 @@
|
|||||||
"kind": "ef",
|
"kind": "ef",
|
||||||
"root": "ADF.USIM-NON-IMSI"
|
"root": "ADF.USIM-NON-IMSI"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "ADF.USIM-NON-IMSI/5FA0",
|
||||||
|
"name": "DF.ACDC",
|
||||||
|
"sym": "ADF.USIM-non-IMSI/DF.ACDC",
|
||||||
|
"fid": "5FA0",
|
||||||
|
"kind": "df",
|
||||||
|
"root": "ADF.USIM-NON-IMSI"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "ADF.USIM-NON-IMSI/5FA0/4F01",
|
||||||
|
"name": "EF.ACDC_LIST",
|
||||||
|
"sym": "ADF.USIM-non-IMSI/DF.ACDC/EF.ACDC_LIST",
|
||||||
|
"fid": "4F01",
|
||||||
|
"kind": "ef",
|
||||||
|
"root": "ADF.USIM-NON-IMSI"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "ADF.USIM-NON-IMSI/5FB0",
|
||||||
|
"name": "DF.TV",
|
||||||
|
"sym": "ADF.USIM-non-IMSI/DF.TV",
|
||||||
|
"fid": "5FB0",
|
||||||
|
"kind": "df",
|
||||||
|
"root": "ADF.USIM-NON-IMSI"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "ADF.USIM-NON-IMSI/5FC0",
|
"path": "ADF.USIM-NON-IMSI/5FC0",
|
||||||
"name": "DF.5GS",
|
"name": "DF.5GS",
|
||||||
@@ -3751,6 +4007,14 @@
|
|||||||
"kind": "ef",
|
"kind": "ef",
|
||||||
"root": "ADF.USIM-NON-IMSI"
|
"root": "ADF.USIM-NON-IMSI"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "ADF.USIM-NON-IMSI/6FDC",
|
||||||
|
"name": "EF.LRPLMNSI",
|
||||||
|
"sym": "ADF.USIM-non-IMSI/EF.LRPLMNSI",
|
||||||
|
"fid": "6FDC",
|
||||||
|
"kind": "ef",
|
||||||
|
"root": "ADF.USIM-NON-IMSI"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "ADF.USIM-NON-IMSI/6FDD",
|
"path": "ADF.USIM-NON-IMSI/6FDD",
|
||||||
"name": "EF.NAFKCA",
|
"name": "EF.NAFKCA",
|
||||||
@@ -3847,6 +4111,14 @@
|
|||||||
"kind": "ef",
|
"kind": "ef",
|
||||||
"root": "ADF.USIM-NON-IMSI"
|
"root": "ADF.USIM-NON-IMSI"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "ADF.USIM-NON-IMSI/6FF0",
|
||||||
|
"name": "EF.IAL",
|
||||||
|
"sym": "ADF.USIM-non-IMSI/EF.IAL",
|
||||||
|
"fid": "6FF0",
|
||||||
|
"kind": "ef",
|
||||||
|
"root": "ADF.USIM-NON-IMSI"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "ADF.USIM-NON-IMSI/6FF1",
|
"path": "ADF.USIM-NON-IMSI/6FF1",
|
||||||
"name": "EF.IPS",
|
"name": "EF.IPS",
|
||||||
@@ -3855,6 +4127,14 @@
|
|||||||
"kind": "ef",
|
"kind": "ef",
|
||||||
"root": "ADF.USIM-NON-IMSI"
|
"root": "ADF.USIM-NON-IMSI"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "ADF.USIM-NON-IMSI/6FF2",
|
||||||
|
"name": "EF.IPD",
|
||||||
|
"sym": "ADF.USIM-non-IMSI/EF.IPD",
|
||||||
|
"fid": "6FF2",
|
||||||
|
"kind": "ef",
|
||||||
|
"root": "ADF.USIM-NON-IMSI"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "ADF.USIM-NON-IMSI/6FF3",
|
"path": "ADF.USIM-NON-IMSI/6FF3",
|
||||||
"name": "EF.ePDGId",
|
"name": "EF.ePDGId",
|
||||||
@@ -3903,6 +4183,22 @@
|
|||||||
"kind": "ef",
|
"kind": "ef",
|
||||||
"root": "ADF.USIM-NON-IMSI"
|
"root": "ADF.USIM-NON-IMSI"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "ADF.USIM-NON-IMSI/6FF9",
|
||||||
|
"name": "EF.3GPPPSDATAOFF",
|
||||||
|
"sym": "ADF.USIM-non-IMSI/EF.3GPPPSDATAOFF",
|
||||||
|
"fid": "6FF9",
|
||||||
|
"kind": "ef",
|
||||||
|
"root": "ADF.USIM-NON-IMSI"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "ADF.USIM-NON-IMSI/6FFB",
|
||||||
|
"name": "EF.TVCONFIG",
|
||||||
|
"sym": "ADF.USIM-non-IMSI/EF.TVCONFIG",
|
||||||
|
"fid": "6FFB",
|
||||||
|
"kind": "ef",
|
||||||
|
"root": "ADF.USIM-NON-IMSI"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "ADF.USIM-NON-IMSI/6FFC",
|
"path": "ADF.USIM-NON-IMSI/6FFC",
|
||||||
"name": "EF.XCAPConfigData",
|
"name": "EF.XCAPConfigData",
|
||||||
|
|||||||
@@ -11,6 +11,11 @@ classes - the same model pySim assembles at equip time:
|
|||||||
It ships as ``frontend/uicc_files.json`` so the SIM/USIM RFM SELECT picker has
|
It ships as ``frontend/uicc_files.json`` so the SIM/USIM RFM SELECT picker has
|
||||||
a file list offline (no card, no server); when a card is equipped the picker
|
a file list offline (no card, no server); when a card is equipped the picker
|
||||||
merges the live tree over it and hides probed-absent files.
|
merges the live tree over it and hides probed-absent files.
|
||||||
|
The optional / service-gated files pySim's model does not carry (the SoLSA,
|
||||||
|
MExE, BCAST, ACDC, TV and A2X DFs, EF.LRPLMNSI, EF.IAL, EF.IPD, EF.TVCONFIG,
|
||||||
|
EF.3GPPPSDATAOFF) are appended from ``SUPPLEMENT`` with their spec locations -
|
||||||
|
the decoded-editing filesystem check resolves a file by its (name, root), so a
|
||||||
|
same-FID file under another DF must stay a distinct entry.
|
||||||
``tests/test_uicc_files.py`` regenerates the list and fails when pySim adds or
|
``tests/test_uicc_files.py`` regenerates the list and fails when pySim adds or
|
||||||
renames files, so the asset cannot silently drift.
|
renames files, so the asset cannot silently drift.
|
||||||
|
|
||||||
@@ -55,6 +60,62 @@ def _entry(fid_path, sym_path, name, fid, kind, root, aid=None):
|
|||||||
return out
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
# Files the pySim model does not carry (optional / service-gated), with their
|
||||||
|
# spec locations: TS 31.102 4.2.86 (EF.LRPLMNSI), 4.2.100 (EF.IAL), 4.2.102
|
||||||
|
# (EF.IPD), 4.2.108 (EF.TVCONFIG), 4.2.109 (EF.3GPPPSDATAOFF), 4.4.1
|
||||||
|
# (DF.SoLSA), 4.4.4 (DF.MExE), 4.4.7 (DF.BCAST - its files are OMA BCAST, so
|
||||||
|
# the DF is listed alone), 4.4.9 (DF.ACDC), 4.4.10 (DF.TV - EF.TVUSD is a
|
||||||
|
# variable 4Fxx, omitted) and 4.6.6 (DF.A2X); the FID map is
|
||||||
|
# docs/uicc/UICC_FILES.md 4.13. Entries are (root, parent FID chain, fid,
|
||||||
|
# name); a DF is a 'DF.' name and precedes its children so the symbolic chain
|
||||||
|
# can be resolved.
|
||||||
|
SUPPLEMENT = (
|
||||||
|
('ADF.USIM', (), '6FDC', 'EF.LRPLMNSI'),
|
||||||
|
('ADF.USIM', (), '6FF0', 'EF.IAL'),
|
||||||
|
('ADF.USIM', (), '6FF2', 'EF.IPD'),
|
||||||
|
('ADF.USIM', (), '6FF9', 'EF.3GPPPSDATAOFF'),
|
||||||
|
('ADF.USIM', (), '6FFB', 'EF.TVCONFIG'),
|
||||||
|
('ADF.USIM', (), '5F3C', 'DF.MExE'),
|
||||||
|
('ADF.USIM', ('5F3C',), '4F40', 'EF.MExE-ST'),
|
||||||
|
('ADF.USIM', ('5F3C',), '4F41', 'EF.ORPK'),
|
||||||
|
('ADF.USIM', ('5F3C',), '4F42', 'EF.ARPK'),
|
||||||
|
('ADF.USIM', ('5F3C',), '4F43', 'EF.TPRPK'),
|
||||||
|
('ADF.USIM', (), '5F70', 'DF.SoLSA'),
|
||||||
|
('ADF.USIM', ('5F70',), '4F30', 'EF.SAI'),
|
||||||
|
('ADF.USIM', ('5F70',), '4F31', 'EF.SLL'),
|
||||||
|
('ADF.USIM', (), '5F80', 'DF.BCAST'),
|
||||||
|
('ADF.USIM', (), '5FA0', 'DF.ACDC'),
|
||||||
|
('ADF.USIM', ('5FA0',), '4F01', 'EF.ACDC_LIST'),
|
||||||
|
('ADF.USIM', (), '5FB0', 'DF.TV'),
|
||||||
|
('MF', ('7F10',), '5F3F', 'DF.A2X'),
|
||||||
|
('MF', ('7F10', '5F3F'), '4F01', 'EF.AST'),
|
||||||
|
('MF', ('7F10', '5F3F'), '4F02', 'EF.A2X_CONFIG'),
|
||||||
|
)
|
||||||
|
|
||||||
|
# The non-IMSI USIM application repeats the ADF.USIM files under its own root
|
||||||
|
# (the walk emits it as a separate ADF with the same file set).
|
||||||
|
USIM_ROOT = 'ADF.USIM'
|
||||||
|
USIM_MIRROR = 'ADF.USIM-NON-IMSI'
|
||||||
|
|
||||||
|
|
||||||
|
def _add_supplement(out, seen, sym_by_path):
|
||||||
|
"""Append SUPPLEMENT, mirroring the ADF.USIM files under the non-IMSI root."""
|
||||||
|
for root, parents, fid, name in SUPPLEMENT:
|
||||||
|
roots = [root]
|
||||||
|
if root == USIM_ROOT and USIM_MIRROR in seen:
|
||||||
|
roots.append(USIM_MIRROR)
|
||||||
|
for target in roots:
|
||||||
|
key = '/'.join((target,) + tuple(parents) + (fid,)).upper()
|
||||||
|
if key in seen:
|
||||||
|
continue
|
||||||
|
parent_key = '/'.join((target,) + tuple(parents)).upper()
|
||||||
|
sym = '%s/%s' % (sym_by_path.get(parent_key, parent_key), name)
|
||||||
|
seen.add(key)
|
||||||
|
out.append(_entry(key, sym, name, fid,
|
||||||
|
'df' if name.startswith('DF.') else 'ef', target))
|
||||||
|
sym_by_path[key] = sym
|
||||||
|
|
||||||
|
|
||||||
def _walk(node, fid_path, sym_path, root, out, seen):
|
def _walk(node, fid_path, sym_path, root, out, seen):
|
||||||
"""Depth-first walk of a DF/ADF subtree (children is a fid -> CardFile dict)."""
|
"""Depth-first walk of a DF/ADF subtree (children is a fid -> CardFile dict)."""
|
||||||
for fid, child in sorted(node.children.items()):
|
for fid, child in sorted(node.children.items()):
|
||||||
@@ -116,6 +177,8 @@ def build():
|
|||||||
seen.add(key)
|
seen.add(key)
|
||||||
out.append(_entry(key, adf.name, adf.name, '', 'adf', adf.name, app.aid))
|
out.append(_entry(key, adf.name, adf.name, '', 'adf', adf.name, app.aid))
|
||||||
_walk(adf, key, adf.name, adf.name, out, seen)
|
_walk(adf, key, adf.name, adf.name, out, seen)
|
||||||
|
# The optional / service-gated files pySim's model does not carry.
|
||||||
|
_add_supplement(out, seen, {e['path']: e['sym'] for e in out})
|
||||||
# Stable order: MF first, then the ADFs alphabetically; DFs before their EFs
|
# Stable order: MF first, then the ADFs alphabetically; DFs before their EFs
|
||||||
# is implicit in the walk, paths sort consistently inside a root.
|
# is implicit in the walk, paths sort consistently inside a root.
|
||||||
out.sort(key=lambda e: (0 if e['root'] == 'MF' else 1, e['root'], e['path']))
|
out.sort(key=lambda e: (0 if e['root'] == 'MF' else 1, e['root'], e['path']))
|
||||||
|
|||||||
@@ -72,6 +72,60 @@ class TestUiccFilesAsset(unittest.TestCase):
|
|||||||
self.assertRegex(f['fid'], r'^[0-9A-F]{4}$')
|
self.assertRegex(f['fid'], r'^[0-9A-F]{4}$')
|
||||||
self.assertTrue(f['name'].startswith(('EF.', 'DF.')))
|
self.assertTrue(f['name'].startswith(('EF.', 'DF.')))
|
||||||
|
|
||||||
|
def test_optional_files_missing_from_the_pysim_model(self):
|
||||||
|
"""The service-gated files pySim does not model (the SUPPLEMENT)."""
|
||||||
|
files = _load()['files']
|
||||||
|
by_path = {f['path']: f for f in files}
|
||||||
|
expected = {
|
||||||
|
# TS 31.102 4.2.86 / 4.2.100 / 4.2.102 / 4.2.108 / 4.2.109
|
||||||
|
'ADF.USIM/6FDC': 'EF.LRPLMNSI',
|
||||||
|
'ADF.USIM/6FF0': 'EF.IAL',
|
||||||
|
'ADF.USIM/6FF2': 'EF.IPD',
|
||||||
|
'ADF.USIM/6FF9': 'EF.3GPPPSDATAOFF',
|
||||||
|
'ADF.USIM/6FFB': 'EF.TVCONFIG',
|
||||||
|
# 4.4.4 DF.MExE
|
||||||
|
'ADF.USIM/5F3C': 'DF.MExE',
|
||||||
|
'ADF.USIM/5F3C/4F40': 'EF.MExE-ST',
|
||||||
|
'ADF.USIM/5F3C/4F41': 'EF.ORPK',
|
||||||
|
'ADF.USIM/5F3C/4F42': 'EF.ARPK',
|
||||||
|
'ADF.USIM/5F3C/4F43': 'EF.TPRPK',
|
||||||
|
# 4.4.1 DF.SoLSA
|
||||||
|
'ADF.USIM/5F70': 'DF.SoLSA',
|
||||||
|
'ADF.USIM/5F70/4F30': 'EF.SAI',
|
||||||
|
'ADF.USIM/5F70/4F31': 'EF.SLL',
|
||||||
|
# 4.4.7 / 4.4.9 / 4.4.10
|
||||||
|
'ADF.USIM/5F80': 'DF.BCAST',
|
||||||
|
'ADF.USIM/5FA0': 'DF.ACDC',
|
||||||
|
'ADF.USIM/5FA0/4F01': 'EF.ACDC_LIST',
|
||||||
|
'ADF.USIM/5FB0': 'DF.TV',
|
||||||
|
# 4.6.6 DF.A2X (DF.TELECOM)
|
||||||
|
'MF/7F10/5F3F': 'DF.A2X',
|
||||||
|
'MF/7F10/5F3F/4F01': 'EF.AST',
|
||||||
|
'MF/7F10/5F3F/4F02': 'EF.A2X_CONFIG',
|
||||||
|
}
|
||||||
|
for path, name in expected.items():
|
||||||
|
self.assertIn(path, by_path)
|
||||||
|
self.assertEqual(by_path[path]['name'], name)
|
||||||
|
self.assertEqual(by_path[path]['root'], path.split('/')[0])
|
||||||
|
self.assertEqual(by_path[path]['kind'],
|
||||||
|
'df' if name.startswith('DF.') else 'ef')
|
||||||
|
# The same FID under another DF stays a distinct entry (name, path).
|
||||||
|
self.assertEqual(by_path['ADF.USIM/5F3A/4F30']['name'], 'EF.PBR')
|
||||||
|
self.assertEqual(by_path['MF/7F10/5F3A/4F30']['name'], 'EF.PBR')
|
||||||
|
# The ADF.USIM files are mirrored under the non-IMSI USIM root.
|
||||||
|
for path, name in expected.items():
|
||||||
|
if not path.startswith('ADF.USIM/'):
|
||||||
|
continue
|
||||||
|
mirror = 'ADF.USIM-NON-IMSI' + path[len('ADF.USIM'):]
|
||||||
|
self.assertIn(mirror, by_path)
|
||||||
|
self.assertEqual(by_path[mirror]['name'], name)
|
||||||
|
self.assertEqual(by_path[mirror]['root'], 'ADF.USIM-NON-IMSI')
|
||||||
|
# (name, root) resolves each SUPPLEMENT file to exactly one path.
|
||||||
|
for path, name in expected.items():
|
||||||
|
root = path.split('/')[0]
|
||||||
|
self.assertEqual([f['path'] for f in files
|
||||||
|
if f['name'] == name and f['root'] == root], [path])
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
Reference in new issue
Block a user