From 465d1a07e049cb65ef206bb60ef6cfa4ffabf975 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sat, 3 Aug 2024 21:33:45 +0200 Subject: [PATCH] pySim.esim.saip.templates: Add SaipSpecVersion The SAIP specification version implicitly determines which filesystem templates (or versions thereof) are supported. So if a given eUICC states it implements SAIP version 2.3.0, then we have to translate this into which template versions that means. The new SaipSpecVersion and its derived classes do exactly that. Change-Id: I3a894c72c22e42bd2067e067be80a67197ad1bf2 --- pySim/esim/saip/templates.py | 83 ++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/pySim/esim/saip/templates.py b/pySim/esim/saip/templates.py index a35779d2..79afc918 100644 --- a/pySim/esim/saip/templates.py +++ b/pySim/esim/saip/templates.py @@ -17,6 +17,7 @@ from typing import * from copy import deepcopy +from pySim.utils import all_subclasses from pySim.filesystem import Path import pySim.esim.saip.oid as OID @@ -807,3 +808,85 @@ ARR_DEFINITION = { 13: ['800113A406830101950108', '800148A40683010A950108'], 14: ['80015EA40683010A950108'], } + +class SaipSpecVersionMeta(type): + def __getitem__(self, ver: str): + """Syntactic sugar so that SaipSpecVersion['2.3.0'] will work.""" + return SaipSpecVersion.for_version(ver) + +class SaipSpecVersion(object, metaclass=SaipSpecVersionMeta): + """Represents a specific version of the SIMalliance / TCA eUICC Profile Package: + Interoperable Format Technical Specification.""" + version = None + oids = [] + + @classmethod + def suports_template_OID(cls, OID: OID.OID) -> bool: + """Return if a given spec version supports a template of given OID.""" + return OID in cls.oids + + @classmethod + def version_match(cls, ver: str) -> bool: + """Check if the given version-string matches the classes version. trailing zeroes are ignored, + so that for example 2.2.0 will be considered equal to 2.2""" + def strip_trailing_zeroes(l: List): + while l[-1] == '0': + l.pop() + cls_ver_l = cls.version.split('.') + strip_trailing_zeroes(cls_ver_l) + ver_l = ver.split('.') + strip_trailing_zeroes(ver_l) + return cls_ver_l == ver_l + + @staticmethod + def for_version(req_version: str) -> Optional['SaipSpecVersion']: + """Return the subclass for the requested version number string.""" + for cls in all_subclasses(SaipSpecVersion): + if cls.version_match(req_version): + return cls + + +class SaipSpecVersion101(SaipSpecVersion): + version = '1.0.1' + oids = [OID.MF, OID.DF_CD, OID.DF_TELECOM, OID.ADF_USIM_by_default, OID.ADF_USIMopt_not_by_default, + OID.DF_PHONEBOOK_ADF_USIM, OID.DF_GSM_ACCESS_ADF_USIM, OID.ADF_ISIM_by_default, + OID.ADF_ISIMopt_not_by_default, OID.ADF_CSIM_by_default, OID.ADF_CSIMopt_not_by_default] + +class SaipSpecVersion20(SaipSpecVersion): + version = '2.0' + # no changes in filesystem teplates to previous 1.0.1 + oids = SaipSpecVersion101.oids + +class SaipSpecVersion21(SaipSpecVersion): + version = '2.1' + # no changes in filesystem teplates to previous 2.0 + oids = SaipSpecVersion20.oids + +class SaipSpecVersion22(SaipSpecVersion): + version = '2.2' + oids = SaipSpecVersion21.oids + [OID.DF_EAP] + +class SaipSpecVersion23(SaipSpecVersion): + version = '2.3' + oids = SaipSpecVersion22.oids + [OID.DF_5GS, OID.DF_SAIP] + +class SaipSpecVersion231(SaipSpecVersion): + version = '2.3.1' + # no changes in filesystem teplates to previous 2.3 + oids = SaipSpecVersion23.oids + +class SaipSpecVersion31(SaipSpecVersion): + version = '3.1' + oids = [OID.MF, OID.DF_CD, OID.DF_TELECOM_v2, OID.ADF_USIM_by_default_v2, OID.ADF_USIMopt_not_by_default_v2, + OID.DF_PHONEBOOK_ADF_USIM, OID.DF_GSM_ACCESS_ADF_USIM, OID.DF_5GS_v2, OID.DF_5GS_v3, OID.DF_SAIP, + OID.ADF_ISIM_by_default, OID.ADF_ISIMopt_not_by_default_v2, OID.ADF_CSIM_by_default_v2, + OID.ADF_CSIMopt_not_by_default_v2, OID.DF_EAP] + +class SaipSpecVersion32(SaipSpecVersion): + version = '3.2' + # no changes in filesystem teplates to previous 3.1 + oids = SaipSpecVersion31.oids + +class SaipSpecVersion331(SaipSpecVersion): + version = '3.3.1' + oids = SaipSpecVersion32.oids + [OID.ADF_USIMopt_not_by_default_v3, OID.DF_5GS_v4, OID.DF_SAIP, OID.DF_SNPN, OID.DF_5GProSe, OID.IoT_by_default, OID.IoTopt_not_by_default]