diff --git a/pySim/esim/saip/personalization.py b/pySim/esim/saip/personalization.py index b7831778..a0db88c3 100644 --- a/pySim/esim/saip/personalization.py +++ b/pySim/esim/saip/personalization.py @@ -646,6 +646,61 @@ class SmspTpScAddr(ConfigurableParameter): yield { cls.name: cls.tuple_to_str((international, digits)) } +class AdMncLen(ConfigurableParameter): + """MNC length. Must be either 2 or 3. Sets only the MNC length field in EF-AD (Administrative Data).""" + name = 'MNC-LEN' + allow_chars = '23' + strip_chars = ' \t\r\n' + numeric_base = 10 + max_len = 1 + min_len = 1 + example_input = '2' + default_source = param_source.ConstantSource + + @classmethod + def validate_val(cls, val): + val = super().validate_val(val) + val = int(val) + if val not in (2, 3): + raise ValueError(f"MNC-LEN must be either 2 or 3, not {val!r}") + return val + + @classmethod + def apply_val(cls, pes: ProfileElementSequence, val): + """val must be an int: either 2 or 3""" + for naa in ('usim', 'isim', 'csim'): + for pe in pes.get_pes_for_type(naa): + # decode existing values + f_ad = pe.files['ef-ad'] + ef_ad = EF_AD() + ef_ad_dec = ef_ad.decode_bin(f_ad.body) + # change mnc_len + ef_ad_dec['mnc_len'] = val + # re-encode into the File body + f_ad.body = ef_ad.encode_bin(ef_ad_dec) + pe.file2pe(f_ad) + + @classmethod + def get_values_from_pes(cls, pes: ProfileElementSequence): + for naa in ('usim', 'isim', 'csim'): + for pe in pes.get_pes_for_type(naa): + f_ad = pe.files.get('ef-ad', None) + if f_ad is None: + continue + + try: + ef_ad = EF_AD() + ef_ad_dec = ef_ad.decode_bin(f_ad.body) + except IndexError: + continue + + mnc_len = ef_ad_dec.get('mnc_len', None) + if mnc_len is None: + continue + + yield { cls.name: mnc_len } + + class SdKey(BinaryParam): """Configurable Security Domain (SD) Key. Value is presented as bytes. Non-abstract implementations are generated in SdKey.generate_sd_key_classes"""