neels has uploaded this change for review. ( https://gerrit.osmocom.org/c/pysim/+/40199?usp=email )
Change subject: personalization: allow reading back multiple values from PES ...................................................................... personalization: allow reading back multiple values from PES Change-Id: Iecb68af7c216c6b9dc3add469564416b6f37f7b2 --- M pySim/esim/saip/personalization.py 1 file changed, 26 insertions(+), 18 deletions(-) git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/99/40199/1 diff --git a/pySim/esim/saip/personalization.py b/pySim/esim/saip/personalization.py index ca37e3a..34d7df9 100644 --- a/pySim/esim/saip/personalization.py +++ b/pySim/esim/saip/personalization.py @@ -216,26 +216,24 @@ @classmethod def get_values_from_pes(cls, pes: ProfileElementSequence) -> Generator: - '''This is what subclasses implement: yield all values from a decoded profile package. + """This is what subclasses implement: yield all values from a decoded profile package. Find all values in the pes, and yield them decoded to a valid cls.input_value format. Should be a generator function, i.e. use 'yield' instead of 'return'. - Usage example: + Yielded value must be a dict(). Usually, an implementation will return only one key, like - cls = esim.saip.personalization.Iccid - # use a set() to get a list of unique values from all results - vals = set( cls.get_values_from_pes(pes) ) - if len(vals) != 1: - raise ValueError(f'{cls.name}: need exactly one value, got {vals}') - # the set contains a single value, return it - return vals.pop() + { "ICCID": "1234567890123456789" } + + Some implementations have more than one value to return, like + + { "IMSI": "00101012345678", "IMSI-ACC" : "5" } Implementation example: for pe in pes: if my_condition(pe): - yield b2h(my_bin_value_from(pe)) - ''' + yield { cls.name: b2h(my_bin_value_from(pe)) } + """ pass @classmethod @@ -364,12 +362,12 @@ def get_values_from_pes(cls, pes: ProfileElementSequence): padded = b2h(pes.get_pe_for_type('header').decoded['iccid']) iccid = unrpad(padded) - yield iccid + yield { cls.name: iccid } for pe in pes.get_pes_for_type('mf'): iccid_pe = pe.decoded.get('ef-iccid', None) if iccid_pe: - yield dec_iccid(b2h(file_tuples_content_as_bytes(iccid_pe))) + yield { cls.name: dec_iccid(b2h(file_tuples_content_as_bytes(iccid_pe))) } class Imsi(DecimalParam): """Configurable IMSI. Expects value to be a string of digits. Automatically sets the ACC to @@ -396,8 +394,13 @@ def get_values_from_pes(cls, pes: ProfileElementSequence): for pe in pes.get_pes_for_type('usim'): imsi_pe = pe.decoded.get('ef-imsi', None) + acc_pe = pe.decoded.get('ef-acc', None) + y = {} if imsi_pe: - yield dec_imsi(b2h(file_tuples_content_as_bytes(imsi_pe))) + y[cls.name] = dec_imsi(b2h(file_tuples_content_as_bytes(imsi_pe))) + if acc_pe: + y[cls.name + '-ACC'] = b2h(file_tuples_content_as_bytes(acc_pe)) + yield y class SdKey(BinaryParam): @@ -438,7 +441,7 @@ for key in pe.decoded['keyList']: if key['keyIdentifier'][0] == cls.key_id and key['keyVersionNumber'][0] == cls.kvn: if len(key['keyComponents']) >= 1: - yield b2h(key['keyComponents'][0]['keyData']) + yield { cls.name: b2h(key['keyComponents'][0]['keyData']) } class SdKeyScp80_01(SdKey): kvn = 0x01 @@ -582,7 +585,7 @@ for pukCodes in obtain_all_pe_from_pelist(mf_pes, 'pukCodes'): for pukCode in pukCodes.decoded['pukCodes']: if pukCode['keyReference'] == cls.keyReference: - yield cls.decimal_hex_to_str(pukCode['pukValue']) + yield { cls.name: cls.decimal_hex_to_str(pukCode['pukValue']) } class Puk1(Puk): is_abstract = False @@ -623,13 +626,14 @@ @classmethod def _read_all_pinvalues_from_pe(cls, pe: ProfileElement): + "This is a separate function because subclasses may feed different pe arguments." for pinCodes in obtain_all_pe_from_pelist(pe, 'pinCodes'): if pinCodes.decoded['pinCodes'][0] != 'pinconfig': continue for pinCode in pinCodes.decoded['pinCodes'][1]: if pinCode['keyReference'] == cls.keyReference: - yield cls.decimal_hex_to_str(pinCode['pinValue']) + yield { cls.name: cls.decimal_hex_to_str(pinCode['pinValue']) } @classmethod def get_values_from_pes(cls, pes: ProfileElementSequence): @@ -698,7 +702,11 @@ algoConfiguration = pe.decoded['algoConfiguration'] if algoConfiguration[0] != 'algoParameter': continue - yield algoConfiguration[1][cls.algo_config_key] + val = algoConfiguration[1][cls.algo_config_key] + if isinstance(val, bytes): + val = b2h(val) + # if it is an int (algorithmID), just pass thru as int + yield { cls.name: val } class AlgorithmID(DecimalParam, AlgoConfig): -- To view, visit https://gerrit.osmocom.org/c/pysim/+/40199?usp=email To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings?usp=email Gerrit-MessageType: newchange Gerrit-Project: pysim Gerrit-Branch: master Gerrit-Change-Id: Iecb68af7c216c6b9dc3add469564416b6f37f7b2 Gerrit-Change-Number: 40199 Gerrit-PatchSet: 1 Gerrit-Owner: neels <nhofm...@sysmocom.de>