From 651455742f598ffbca2c592f9a185687bf417542 Mon Sep 17 00:00:00 2001 From: Neels Hofmeyr Date: Tue, 10 Mar 2026 19:07:18 +0100 Subject: [PATCH] wip Change-Id: I0f44d0e90b26b152bcf414ec4497afb8182dd72d --- pySim/esim/saip/batch.py | 16 ++++++++++------ pySim/esim/saip/personalization.py | 29 ++++++++++++++++++++++------- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/pySim/esim/saip/batch.py b/pySim/esim/saip/batch.py index 6567eaf1..8d70e6ea 100644 --- a/pySim/esim/saip/batch.py +++ b/pySim/esim/saip/batch.py @@ -58,8 +58,8 @@ class BatchPersonalization: class ParamAndSrc: 'tie a ConfigurableParameter to a source of actual values' - def __init__(self, param: ConfigurableParameter, src: param_source.ParamSource): - self.param = param + def __init__(self, param_cls: ConfigurableParameter, src: param_source.ParamSource): + self.param_cls = param_cls self.src = src def __init__(self, @@ -85,7 +85,11 @@ class BatchPersonalization: self.csv_rows = csv_rows def add_param_and_src(self, param:ConfigurableParameter, src:param_source.ParamSource): - self.params.append(BatchPersonalization.ParamAndSrc(param=param, src=src)) + if isinstance(param, type): + param_cls = param + else: + param_cls = param.__class__ + self.params.append(BatchPersonalization.ParamAndSrc(param_cls=param_cls, src=src)) def generate_profiles(self): # get first row of CSV: column names @@ -112,10 +116,10 @@ class BatchPersonalization: try: input_value = p.src.get_next(csv_row=csv_row) assert input_value is not None - value = p.param.__class__.validate_val(input_value) - p.param.__class__.apply_val(pes, value) + value = p.param_cls.validate_val(input_value) + p.param_cls.apply_val(pes, value) except Exception as e: - raise ValueError(f'{p.param.name} fed by {p.src.name}: {e}') from e + raise ValueError(f'{p.param_cls.get_name()} fed by {p.src.name}: {e}') from e yield pes diff --git a/pySim/esim/saip/personalization.py b/pySim/esim/saip/personalization.py index a0db88c3..73c4f8c4 100644 --- a/pySim/esim/saip/personalization.py +++ b/pySim/esim/saip/personalization.py @@ -22,9 +22,11 @@ import re import pprint from typing import List, Tuple, Generator, Optional +from construct.core import StreamError from osmocom.tlv import camel_to_snake from osmocom.utils import hexstr from pySim.utils import enc_iccid, dec_iccid, enc_imsi, dec_imsi, h2b, b2h, rpad, sanitize_iccid +from pySim.ts_31_102 import EF_AD from pySim.ts_51_011 import EF_SMSP from pySim.esim.saip import param_source from pySim.esim.saip import ProfileElement, ProfileElementSD, ProfileElementSequence @@ -646,7 +648,7 @@ class SmspTpScAddr(ConfigurableParameter): yield { cls.name: cls.tuple_to_str((international, digits)) } -class AdMncLen(ConfigurableParameter): +class MncLen(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' @@ -670,10 +672,20 @@ class AdMncLen(ConfigurableParameter): """val must be an int: either 2 or 3""" for naa in ('usim', 'isim', 'csim'): for pe in pes.get_pes_for_type(naa): + if not hasattr(pe, 'files'): + continue # decode existing values f_ad = pe.files['ef-ad'] - ef_ad = EF_AD() - ef_ad_dec = ef_ad.decode_bin(f_ad.body) + print(f"XXXX {f_ad.body}") + if not f_ad.body: + continue + try: + ef_ad = EF_AD() + ef_ad_dec = ef_ad.decode_bin(f_ad.body) + except StreamError: + continue + if 'mnc_len' not in ef_ad_dec: + continue # change mnc_len ef_ad_dec['mnc_len'] = val # re-encode into the File body @@ -682,23 +694,26 @@ class AdMncLen(ConfigurableParameter): @classmethod def get_values_from_pes(cls, pes: ProfileElementSequence): - for naa in ('usim', 'isim', 'csim'): + for naa in ('isim',):# 'isim', 'csim'): for pe in pes.get_pes_for_type(naa): + if not hasattr(pe, 'files'): + continue f_ad = pe.files.get('ef-ad', None) if f_ad is None: continue + print(f"XXXX {f_ad.body}") try: ef_ad = EF_AD() ef_ad_dec = ef_ad.decode_bin(f_ad.body) - except IndexError: + except StreamError: continue mnc_len = ef_ad_dec.get('mnc_len', None) if mnc_len is None: continue - yield { cls.name: mnc_len } + yield { cls.name: str(mnc_len) } class SdKey(BinaryParam): @@ -1135,7 +1150,7 @@ class MilenageRotationConstants(BinaryParam, AlgoConfig): class MilenageXoringConstants(BinaryParam, AlgoConfig): """XOR-ing constants c1,c2,c3,c4,c5 of Milenage, 128bit each. See 3GPP TS 35.206 Sections 2.3 + 5.3. Provided as octet-string concatenation of all 5 constants. The default value by 3GPP is the concetenation - of:: + of: 00000000000000000000000000000000 00000000000000000000000000000001