From 1f50f295467bfdcf876e2ff9a52ddb4b1c73e96c Mon Sep 17 00:00:00 2001 From: Neels Hofmeyr Date: Sun, 15 Mar 2026 21:16:19 +0100 Subject: [PATCH] personalization: indicate default ParamSource per ConfigurableParameter Add default_source class members pointing to ParamSource classes to all ConfigurableParameter subclasses. This is useful to automatically set up a default ParamSource for a given ConfigurableParameter subclass, during user interaction to produce a batch personalization. For example, if the user selects a Pin1 parameter, a calling program can implicitly set this to a RandomDigitSource, which will magically make it work the way that most users need. BTW, default_source and default_value can be combined to configure a matching ParamSource instance: my_source = MyParam.default_source.from_str( MyParam.default_value ) Change-Id: Ie58d13bce3fa1aa2547cf3cee918c2f5b30a8b32 --- pySim/esim/saip/personalization.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/pySim/esim/saip/personalization.py b/pySim/esim/saip/personalization.py index 6c9c35d7..a361e8de 100644 --- a/pySim/esim/saip/personalization.py +++ b/pySim/esim/saip/personalization.py @@ -24,6 +24,7 @@ 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.esim.saip import ProfileElement, ProfileElementSequence +from pySim.esim.saip import param_source from pySim.ts_51_011 import EF_SMSP def unrpad(s: hexstr, c='f') -> hexstr: @@ -122,6 +123,7 @@ class ConfigurableParameter(abc.ABC, metaclass=ClassVarMeta): max_len = None allow_len = None # a list of specific lengths example_input = None + default_source = None # a param_source.ParamSource subclass def __init__(self, input_value=None): self.input_value = input_value # the raw input value as given by caller @@ -331,6 +333,7 @@ class BinaryParam(ConfigurableParameter): allow_types = (str, io.BytesIO, bytes, bytearray) allow_chars = '0123456789abcdefABCDEF' strip_chars = ' \t\r\n' + default_source = param_source.RandomHexDigitSource @classmethod def validate_val(cls, val): @@ -357,6 +360,7 @@ class Iccid(DecimalParam): min_len = 18 max_len = 20 example_input = '998877665544332211' + default_source = param_source.IncDigitSource @classmethod def validate_val(cls, val): @@ -389,6 +393,7 @@ class Imsi(DecimalParam): min_len = 6 max_len = 15 example_input = '00101' + ('0' * 10) + default_source = param_source.IncDigitSource @classmethod def apply_val(cls, pes: ProfileElementSequence, val): @@ -424,6 +429,7 @@ class SmspTpScAddr(ConfigurableParameter): max_len = 21 # '+' and 20 digits min_len = 1 example_input = '+49301234567' + default_source = param_source.ConstantSource @classmethod def validate_val(cls, val): @@ -607,7 +613,8 @@ class Puk(DecimalHexParam): allow_len = 8 rpad = 16 keyReference = None - example_input = '0' * allow_len + example_input = f'0*{allow_len}' + default_source = param_source.RandomDigitSource @classmethod def apply_val(cls, pes: ProfileElementSequence, val): @@ -642,7 +649,8 @@ class Pin(DecimalHexParam): rpad = 16 min_len = 4 max_len = 8 - example_input = '0' * max_len + example_input = f'0*{max_len}' + default_source = param_source.RandomDigitSource keyReference = None @staticmethod @@ -681,7 +689,7 @@ class Pin(DecimalHexParam): class Pin1(Pin): name = 'PIN1' - example_input = '0' * 4 # PIN are usually 4 digits + example_input = '0*4' # PIN are usually 4 digits keyReference = 0x01 class Pin2(Pin1): @@ -755,6 +763,7 @@ class AlgorithmID(DecimalParam, AlgoConfig): algo_config_key = 'algorithmID' allow_len = 1 example_input = 1 # Milenage + default_source = param_source.ConstantSource @classmethod def validate_val(cls, val): @@ -770,7 +779,7 @@ class K(BinaryParam, AlgoConfig): name = 'K' algo_config_key = 'key' allow_len = (128 // 8, 256 // 8) # length in bytes (from BinaryParam); TUAK also allows 256 bit - example_input = '00' * allow_len[0] + example_input = f'00*{allow_len[0]}' class Opc(K): name = 'OPc' @@ -784,6 +793,7 @@ class MilenageRotationConstants(BinaryParam, AlgoConfig): algo_config_key = 'rotationConstants' allow_len = 5 # length in bytes (from BinaryParam) example_input = '40 00 20 40 60' + default_source = param_source.ConstantSource @classmethod def validate_val(cls, val): @@ -814,6 +824,7 @@ class MilenageXoringConstants(BinaryParam, AlgoConfig): ' 00000000000000000000000000000002' ' 00000000000000000000000000000004' ' 00000000000000000000000000000008') + default_source = param_source.ConstantSource class TuakNumberOfKeccak(IntegerParam, AlgoConfig): """Number of iterations of Keccak-f[1600] permutation as recomended by Section 7.2 of 3GPP TS 35.231""" @@ -822,3 +833,4 @@ class TuakNumberOfKeccak(IntegerParam, AlgoConfig): min_val = 1 max_val = 255 example_input = '1' + default_source = param_source.ConstantSource