mirror of
https://gitea.osmocom.org/sim-card/pysim.git
synced 2026-06-24 21:30:28 +03:00
add test_configurable_parameters.py
Add ConfigurableParameterTest, which applies each parameter to a real UPP DER template and reads it back, comparing results against a stored expected-output snapshot (xo/test_configurable_parameters). Add TestValidateVal covering validate_val() for Iccid, Imsi, Pin1, Puk1 and K, testing both valid inputs and invalid ones expected to raise ValueError. Add TestEnumParam covering the EnumParam methods (validate_val, map_name_to_val, map_val_to_name, name_normalize, clean_name_str) using AlgorithmID as the concrete subclass, including fuzzy name matching. Also add get_value_from_pes() to ConfigurableParameter as a convenience wrapper around get_values_from_pes() that asserts all returned values are identical and returns the single result. Change-Id: Ia55f0d11f8197ca15a948a83a34b3488acf1a0b4 Co-authored-by: Vadim Yanitskiy <vyanitskiy@sysmocom.de> Jenkins: skip-card-test
This commit is contained in:
committed by
Vadim Yanitskiy
parent
a7c762eb2e
commit
3974e96933
Symlink
+1
@@ -0,0 +1 @@
|
||||
../../smdpp-data
|
||||
+444
@@ -0,0 +1,444 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# (C) 2025 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
|
||||
#
|
||||
# Author: Neels Hofmeyr
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import enum
|
||||
import io
|
||||
import sys
|
||||
import unittest
|
||||
from importlib import resources
|
||||
from osmocom.utils import hexstr
|
||||
from pySim.esim.saip import ProfileElementSequence
|
||||
import pySim.esim.saip.personalization as p13n
|
||||
import smdpp_data.upp
|
||||
|
||||
import xo
|
||||
update_expected_output = False
|
||||
|
||||
def valstr(val):
|
||||
if isinstance(val, io.BytesIO):
|
||||
val = val.getvalue()
|
||||
if isinstance(val, bytearray):
|
||||
val = bytes(val)
|
||||
return f'{val!r}'
|
||||
|
||||
def valtypestr(val):
|
||||
if isinstance(val, dict):
|
||||
types = []
|
||||
for v in val.values():
|
||||
types.append(f'{type(v).__name__}')
|
||||
|
||||
val_type = '{' + ', '.join(types) + '}'
|
||||
else:
|
||||
val_type = f'{type(val).__name__}'
|
||||
return f'{valstr(val)}:{val_type}'
|
||||
|
||||
class ConfigurableParameterTest(unittest.TestCase):
|
||||
|
||||
def test_parameters(self):
|
||||
|
||||
upp_fnames = (
|
||||
'TS48v5_SAIP2.1A_NoBERTLV.der',
|
||||
'TS48v5_SAIP2.3_BERTLV_SUCI.der',
|
||||
'TS48v5_SAIP2.1B_NoBERTLV.der',
|
||||
'TS48v5_SAIP2.3_NoBERTLV.der',
|
||||
)
|
||||
|
||||
class Paramtest:
|
||||
def __init__(self, param_cls, val, expect_val, expect_clean_val=None):
|
||||
self.param_cls = param_cls
|
||||
self.val = val
|
||||
self.expect_clean_val = expect_clean_val
|
||||
self.expect_val = expect_val
|
||||
|
||||
param_tests = [
|
||||
Paramtest(param_cls=p13n.Imsi, val='123456',
|
||||
expect_clean_val=str('123456'),
|
||||
expect_val={'IMSI': hexstr('123456'),
|
||||
'IMSI-ACC': '0040'}),
|
||||
Paramtest(param_cls=p13n.Imsi, val=int(123456),
|
||||
expect_val={'IMSI': hexstr('123456'),
|
||||
'IMSI-ACC': '0040'}),
|
||||
|
||||
Paramtest(param_cls=p13n.Imsi, val='123456789012345',
|
||||
expect_clean_val=str('123456789012345'),
|
||||
expect_val={'IMSI': hexstr('123456789012345'),
|
||||
'IMSI-ACC': '0020'}),
|
||||
Paramtest(param_cls=p13n.Imsi, val=int(123456789012345),
|
||||
expect_val={'IMSI': hexstr('123456789012345'),
|
||||
'IMSI-ACC': '0020'}),
|
||||
|
||||
Paramtest(param_cls=p13n.Puk1,
|
||||
val='12345678',
|
||||
expect_clean_val=b'12345678',
|
||||
expect_val='12345678'),
|
||||
|
||||
Paramtest(param_cls=p13n.Puk2,
|
||||
val='12345678',
|
||||
expect_clean_val=b'12345678',
|
||||
expect_val='12345678'),
|
||||
|
||||
Paramtest(param_cls=p13n.Pin1,
|
||||
val='1234',
|
||||
expect_clean_val=b'1234\xff\xff\xff\xff',
|
||||
expect_val='1234'),
|
||||
Paramtest(param_cls=p13n.Pin1,
|
||||
val='123456',
|
||||
expect_clean_val=b'123456\xff\xff',
|
||||
expect_val='123456'),
|
||||
Paramtest(param_cls=p13n.Pin1,
|
||||
val='12345678',
|
||||
expect_clean_val=b'12345678',
|
||||
expect_val='12345678'),
|
||||
|
||||
Paramtest(param_cls=p13n.Adm1,
|
||||
val='1234',
|
||||
expect_clean_val=b'1234\xff\xff\xff\xff',
|
||||
expect_val='1234'),
|
||||
Paramtest(param_cls=p13n.Adm1,
|
||||
val='123456',
|
||||
expect_clean_val=b'123456\xff\xff',
|
||||
expect_val='123456'),
|
||||
Paramtest(param_cls=p13n.Adm1,
|
||||
val='12345678',
|
||||
expect_clean_val=b'12345678',
|
||||
expect_val='12345678'),
|
||||
|
||||
Paramtest(param_cls=p13n.AlgorithmID,
|
||||
val='Milenage',
|
||||
expect_clean_val=1,
|
||||
expect_val='Milenage'),
|
||||
Paramtest(param_cls=p13n.AlgorithmID,
|
||||
val='TUAK',
|
||||
expect_clean_val=2,
|
||||
expect_val='TUAK'),
|
||||
Paramtest(param_cls=p13n.AlgorithmID,
|
||||
val='usim-test',
|
||||
expect_clean_val=3,
|
||||
expect_val='usim_test'),
|
||||
|
||||
Paramtest(param_cls=p13n.K,
|
||||
val='01020304050607080910111213141516',
|
||||
expect_clean_val=b'\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16',
|
||||
expect_val='01020304050607080910111213141516'),
|
||||
Paramtest(param_cls=p13n.K,
|
||||
val=b'\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16',
|
||||
expect_clean_val=b'\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16',
|
||||
expect_val='01020304050607080910111213141516'),
|
||||
Paramtest(param_cls=p13n.K,
|
||||
val=bytearray(b'\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16'),
|
||||
expect_clean_val=b'\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16',
|
||||
expect_val='01020304050607080910111213141516'),
|
||||
|
||||
Paramtest(param_cls=p13n.Opc,
|
||||
val='01020304050607080910111213141516',
|
||||
expect_clean_val=b'\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16',
|
||||
expect_val='01020304050607080910111213141516'),
|
||||
Paramtest(param_cls=p13n.Opc,
|
||||
val=b'\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16',
|
||||
expect_clean_val=b'\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16',
|
||||
expect_val='01020304050607080910111213141516'),
|
||||
Paramtest(param_cls=p13n.Opc,
|
||||
val=bytearray(b'\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16'),
|
||||
expect_clean_val=b'\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16',
|
||||
expect_val='01020304050607080910111213141516'),
|
||||
]
|
||||
|
||||
# SdKey classes don't make sense yet, will come in Ic92ddea6e1fad8167ea75baf78ffc3eb419838c4
|
||||
|
||||
outputs = []
|
||||
|
||||
for upp_fname in upp_fnames:
|
||||
test_idx = -1
|
||||
try:
|
||||
|
||||
der = resources.read_binary(smdpp_data.upp, upp_fname)
|
||||
|
||||
for t in param_tests:
|
||||
test_idx += 1
|
||||
logloc = f'{upp_fname} {t.param_cls.__name__}(val={valtypestr(t.val)})'
|
||||
|
||||
param = None
|
||||
try:
|
||||
param = t.param_cls()
|
||||
param.input_value = t.val
|
||||
param.validate()
|
||||
except ValueError as e:
|
||||
raise ValueError(f'{logloc}: {e}') from e
|
||||
|
||||
clean_val = param.value
|
||||
logloc = f'{logloc} clean_val={valtypestr(clean_val)}'
|
||||
if t.expect_clean_val is not None and t.expect_clean_val != clean_val:
|
||||
raise ValueError(f'{logloc}: expected'
|
||||
f' expect_clean_val={valtypestr(t.expect_clean_val)}')
|
||||
|
||||
# on my laptop, deepcopy is about 30% slower than decoding the DER from scratch:
|
||||
# pes = copy.deepcopy(orig_pes)
|
||||
pes = ProfileElementSequence.from_der(der)
|
||||
try:
|
||||
param.apply(pes)
|
||||
except ValueError as e:
|
||||
raise ValueError(f'{logloc} apply_val(clean_val): {e}') from e
|
||||
|
||||
changed_der = pes.to_der()
|
||||
|
||||
pes2 = ProfileElementSequence.from_der(changed_der)
|
||||
|
||||
read_back_val = t.param_cls.get_value_from_pes(pes2)
|
||||
|
||||
# compose log string to show the precise type of dict values
|
||||
if isinstance(read_back_val, dict):
|
||||
types = set()
|
||||
for v in read_back_val.values():
|
||||
types.add(f'{type(v).__name__}')
|
||||
|
||||
read_back_val_type = '{' + ', '.join(types) + '}'
|
||||
else:
|
||||
read_back_val_type = f'{type(read_back_val).__name__}'
|
||||
|
||||
logloc = (f'{logloc} read_back_val={valtypestr(read_back_val)}')
|
||||
|
||||
if isinstance(read_back_val, dict) and not t.param_cls.get_name() in read_back_val.keys():
|
||||
raise ValueError(f'{logloc}: expected to find name {t.param_cls.get_name()!r} in read_back_val')
|
||||
|
||||
expect_val = t.expect_val
|
||||
if not isinstance(expect_val, dict):
|
||||
expect_val = { t.param_cls.get_name(): expect_val }
|
||||
if read_back_val != expect_val:
|
||||
raise ValueError(f'{logloc}: expected {expect_val=!r}:{type(t.expect_val).__name__}')
|
||||
|
||||
ok = logloc.replace(' clean_val', '\n\tclean_val'
|
||||
).replace(' read_back_val', '\n\tread_back_val'
|
||||
).replace('=', '=\t'
|
||||
)
|
||||
output = f'\nok: {ok}'
|
||||
outputs.append(output)
|
||||
print(output)
|
||||
|
||||
except Exception as e:
|
||||
raise RuntimeError(f'Error while testing UPP {upp_fname} {test_idx=}: {e}') from e
|
||||
|
||||
output = '\n'.join(outputs) + '\n'
|
||||
xo_name = 'test_configurable_parameters'
|
||||
if update_expected_output:
|
||||
with resources.path(xo, xo_name) as xo_path:
|
||||
with open(xo_path, 'w', encoding='utf-8') as f:
|
||||
f.write(output)
|
||||
else:
|
||||
xo_str = resources.read_text(xo, xo_name)
|
||||
if xo_str != output:
|
||||
at = 0
|
||||
while at < len(output):
|
||||
if output[at] == xo_str[at]:
|
||||
at += 1
|
||||
continue
|
||||
break
|
||||
|
||||
raise RuntimeError(f'output differs from expected output at position {at}: "{output[at:at+20]}" != "{xo_str[at:at+20]}"')
|
||||
|
||||
|
||||
class TestValidateVal(unittest.TestCase):
|
||||
"""validate_val() tests for various ConfigurableParameter subclasses."""
|
||||
|
||||
def _ok(self, cls, val, expected=None):
|
||||
result = cls.validate_val(val)
|
||||
if expected is not None:
|
||||
self.assertEqual(result, expected)
|
||||
return result
|
||||
|
||||
def _err(self, cls, val):
|
||||
with self.assertRaises(ValueError):
|
||||
cls.validate_val(val)
|
||||
|
||||
# --- Iccid ---
|
||||
|
||||
def test_iccid_18digits_adds_luhn(self):
|
||||
result = self._ok(p13n.Iccid, '998877665544332211')
|
||||
self.assertIsInstance(result, str)
|
||||
self.assertEqual(len(result), 19)
|
||||
self.assertTrue(result.isdecimal())
|
||||
|
||||
def test_iccid_19digits_passthrough(self):
|
||||
result = self._ok(p13n.Iccid, '9988776655443322110')
|
||||
self.assertIsInstance(result, str)
|
||||
self.assertEqual(len(result), 19)
|
||||
|
||||
def test_iccid_too_short(self):
|
||||
self._err(p13n.Iccid, '12345678901234567') # 17 digits
|
||||
|
||||
def test_iccid_too_long(self):
|
||||
self._err(p13n.Iccid, '1' * 21)
|
||||
|
||||
def test_iccid_non_digits(self):
|
||||
self._err(p13n.Iccid, '99887766554433221X')
|
||||
|
||||
# --- Imsi ---
|
||||
|
||||
def test_imsi_valid_short(self):
|
||||
self._ok(p13n.Imsi, '001010', '001010')
|
||||
|
||||
def test_imsi_valid_long(self):
|
||||
self._ok(p13n.Imsi, '001010123456789', '001010123456789')
|
||||
|
||||
def test_imsi_too_short(self):
|
||||
self._err(p13n.Imsi, '12345') # 5 digits, min is 6
|
||||
|
||||
def test_imsi_too_long(self):
|
||||
self._err(p13n.Imsi, '1' * 16)
|
||||
|
||||
def test_imsi_non_digits(self):
|
||||
self._err(p13n.Imsi, '00101A123456789')
|
||||
|
||||
# --- Pin1 ---
|
||||
|
||||
def test_pin1_4digits(self):
|
||||
# DecimalHexParam encodes each digit as its ASCII byte, then rpad to 8 bytes with 0xff
|
||||
self._ok(p13n.Pin1, '1234', b'1234\xff\xff\xff\xff')
|
||||
|
||||
def test_pin1_8digits(self):
|
||||
self._ok(p13n.Pin1, '12345678', b'12345678')
|
||||
|
||||
def test_pin1_too_short(self):
|
||||
self._err(p13n.Pin1, '123')
|
||||
|
||||
def test_pin1_too_long(self):
|
||||
self._err(p13n.Pin1, '123456789')
|
||||
|
||||
def test_pin1_non_digits(self):
|
||||
self._err(p13n.Pin1, '123A')
|
||||
|
||||
# --- Puk1 ---
|
||||
|
||||
def test_puk1_8digits(self):
|
||||
self._ok(p13n.Puk1, '12345678', b'12345678')
|
||||
|
||||
def test_puk1_wrong_length(self):
|
||||
self._err(p13n.Puk1, '1234567') # 7 digits
|
||||
self._err(p13n.Puk1, '123456789') # 9 digits
|
||||
|
||||
def test_puk1_non_digits(self):
|
||||
self._err(p13n.Puk1, '1234567X')
|
||||
|
||||
# --- K (BinaryParam) ---
|
||||
|
||||
def test_k_valid_hex_str(self):
|
||||
self._ok(p13n.K, '000102030405060708090a0b0c0d0e0f',
|
||||
b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f')
|
||||
|
||||
def test_k_valid_bytes(self):
|
||||
raw = bytes(range(16))
|
||||
self._ok(p13n.K, raw, raw)
|
||||
|
||||
def test_k_wrong_length(self):
|
||||
self._err(p13n.K, '00' * 15) # 15 bytes, allow_len requires 16 or 32
|
||||
|
||||
def test_k_non_hex(self):
|
||||
self._err(p13n.K, 'gg' * 16)
|
||||
|
||||
def test_k_odd_hex_digits(self):
|
||||
self._err(p13n.K, '0' * 31) # odd number of hex digits
|
||||
|
||||
|
||||
class TestEnumParam(unittest.TestCase):
|
||||
"""Tests for the EnumParam machinery, using AlgorithmID as the concrete subclass."""
|
||||
|
||||
# --- validate_val ---
|
||||
|
||||
def test_validate_by_name_exact(self):
|
||||
self.assertEqual(p13n.AlgorithmID.validate_val('Milenage'), 1)
|
||||
self.assertEqual(p13n.AlgorithmID.validate_val('TUAK'), 2)
|
||||
self.assertEqual(p13n.AlgorithmID.validate_val('usim_test'), 3)
|
||||
|
||||
def test_validate_by_int(self):
|
||||
self.assertEqual(p13n.AlgorithmID.validate_val(1), 1)
|
||||
self.assertEqual(p13n.AlgorithmID.validate_val(2), 2)
|
||||
self.assertEqual(p13n.AlgorithmID.validate_val(3), 3)
|
||||
|
||||
def test_validate_fuzzy_case(self):
|
||||
self.assertEqual(p13n.AlgorithmID.validate_val('milenage'), 1)
|
||||
self.assertEqual(p13n.AlgorithmID.validate_val('MILENAGE'), 1)
|
||||
self.assertEqual(p13n.AlgorithmID.validate_val('tuak'), 2)
|
||||
|
||||
def test_validate_fuzzy_hyphen_underscore(self):
|
||||
# 'usim-test' has a hyphen; enum member is 'usim_test' — must fuzzy-match
|
||||
self.assertEqual(p13n.AlgorithmID.validate_val('usim-test'), 3)
|
||||
|
||||
def test_validate_invalid_name(self):
|
||||
with self.assertRaises(ValueError):
|
||||
p13n.AlgorithmID.validate_val('unknown')
|
||||
|
||||
def test_validate_invalid_int(self):
|
||||
with self.assertRaises(ValueError):
|
||||
p13n.AlgorithmID.validate_val(99)
|
||||
|
||||
def test_validate_returns_int(self):
|
||||
result = p13n.AlgorithmID.validate_val('Milenage')
|
||||
self.assertIsInstance(result, int)
|
||||
self.assertNotIsInstance(result, enum.Enum)
|
||||
|
||||
# --- map_name_to_val ---
|
||||
|
||||
def test_map_name_exact(self):
|
||||
self.assertEqual(p13n.AlgorithmID.map_name_to_val('Milenage'), 1)
|
||||
|
||||
def test_map_name_fuzzy(self):
|
||||
self.assertEqual(p13n.AlgorithmID.map_name_to_val('milenage'), 1)
|
||||
self.assertEqual(p13n.AlgorithmID.map_name_to_val('usim-test'), 3)
|
||||
|
||||
def test_map_name_strict_raises(self):
|
||||
with self.assertRaises(ValueError):
|
||||
p13n.AlgorithmID.map_name_to_val('unknown', strict=True)
|
||||
|
||||
def test_map_name_nonstrict_returns_none(self):
|
||||
self.assertIsNone(p13n.AlgorithmID.map_name_to_val('unknown', strict=False))
|
||||
|
||||
# --- map_val_to_name ---
|
||||
|
||||
def test_map_val_known(self):
|
||||
self.assertEqual(p13n.AlgorithmID.map_val_to_name(1), 'Milenage')
|
||||
self.assertEqual(p13n.AlgorithmID.map_val_to_name(2), 'TUAK')
|
||||
self.assertEqual(p13n.AlgorithmID.map_val_to_name(3), 'usim_test')
|
||||
|
||||
def test_map_val_unknown_nonstrict(self):
|
||||
self.assertIsNone(p13n.AlgorithmID.map_val_to_name(99))
|
||||
|
||||
def test_map_val_unknown_strict(self):
|
||||
with self.assertRaises(ValueError):
|
||||
p13n.AlgorithmID.map_val_to_name(99, strict=True)
|
||||
|
||||
# --- name_normalize ---
|
||||
|
||||
def test_name_normalize(self):
|
||||
self.assertEqual(p13n.AlgorithmID.name_normalize('Milenage'), 'Milenage')
|
||||
self.assertEqual(p13n.AlgorithmID.name_normalize('milenage'), 'Milenage')
|
||||
self.assertEqual(p13n.AlgorithmID.name_normalize('usim-test'), 'usim_test')
|
||||
|
||||
# --- clean_name_str ---
|
||||
|
||||
def test_clean_name_str(self):
|
||||
self.assertEqual(p13n.AlgorithmID.clean_name_str('usim-test'), 'usimtest')
|
||||
self.assertEqual(p13n.AlgorithmID.clean_name_str('usim_test'), 'usimtest')
|
||||
self.assertEqual(p13n.AlgorithmID.clean_name_str('Milenage'), 'milenage')
|
||||
self.assertEqual(p13n.AlgorithmID.clean_name_str('foo bar!'), 'foobar')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if '-u' in sys.argv:
|
||||
update_expected_output = True
|
||||
sys.argv.remove('-u')
|
||||
unittest.main()
|
||||
@@ -0,0 +1,336 @@
|
||||
|
||||
ok: TS48v5_SAIP2.1A_NoBERTLV.der Imsi(val= '123456':str)
|
||||
clean_val= '123456':str
|
||||
read_back_val= {'IMSI': '123456', 'IMSI-ACC': '0040'}:{str, hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.1A_NoBERTLV.der Imsi(val= 123456:int)
|
||||
clean_val= '123456':str
|
||||
read_back_val= {'IMSI': '123456', 'IMSI-ACC': '0040'}:{str, hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.1A_NoBERTLV.der Imsi(val= '123456789012345':str)
|
||||
clean_val= '123456789012345':str
|
||||
read_back_val= {'IMSI': '123456789012345', 'IMSI-ACC': '0020'}:{str, hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.1A_NoBERTLV.der Imsi(val= 123456789012345:int)
|
||||
clean_val= '123456789012345':str
|
||||
read_back_val= {'IMSI': '123456789012345', 'IMSI-ACC': '0020'}:{str, hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.1A_NoBERTLV.der Puk1(val= '12345678':str)
|
||||
clean_val= b'12345678':bytearray
|
||||
read_back_val= {'PUK1': '12345678'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.1A_NoBERTLV.der Puk2(val= '12345678':str)
|
||||
clean_val= b'12345678':bytearray
|
||||
read_back_val= {'PUK2': '12345678'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.1A_NoBERTLV.der Pin1(val= '1234':str)
|
||||
clean_val= b'1234\xff\xff\xff\xff':bytearray
|
||||
read_back_val= {'PIN1': '1234'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.1A_NoBERTLV.der Pin1(val= '123456':str)
|
||||
clean_val= b'123456\xff\xff':bytearray
|
||||
read_back_val= {'PIN1': '123456'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.1A_NoBERTLV.der Pin1(val= '12345678':str)
|
||||
clean_val= b'12345678':bytearray
|
||||
read_back_val= {'PIN1': '12345678'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.1A_NoBERTLV.der Adm1(val= '1234':str)
|
||||
clean_val= b'1234\xff\xff\xff\xff':bytearray
|
||||
read_back_val= {'ADM1': '1234'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.1A_NoBERTLV.der Adm1(val= '123456':str)
|
||||
clean_val= b'123456\xff\xff':bytearray
|
||||
read_back_val= {'ADM1': '123456'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.1A_NoBERTLV.der Adm1(val= '12345678':str)
|
||||
clean_val= b'12345678':bytearray
|
||||
read_back_val= {'ADM1': '12345678'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.1A_NoBERTLV.der AlgorithmID(val= 'Milenage':str)
|
||||
clean_val= 1:int
|
||||
read_back_val= {'Algorithm': 'Milenage'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.1A_NoBERTLV.der AlgorithmID(val= 'TUAK':str)
|
||||
clean_val= 2:int
|
||||
read_back_val= {'Algorithm': 'TUAK'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.1A_NoBERTLV.der AlgorithmID(val= 'usim-test':str)
|
||||
clean_val= 3:int
|
||||
read_back_val= {'Algorithm': 'usim_test'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.1A_NoBERTLV.der K(val= '01020304050607080910111213141516':str)
|
||||
clean_val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytes
|
||||
read_back_val= {'K': '01020304050607080910111213141516'}:{hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.1A_NoBERTLV.der K(val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytes)
|
||||
clean_val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytes
|
||||
read_back_val= {'K': '01020304050607080910111213141516'}:{hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.1A_NoBERTLV.der K(val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytearray)
|
||||
clean_val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytes
|
||||
read_back_val= {'K': '01020304050607080910111213141516'}:{hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.1A_NoBERTLV.der Opc(val= '01020304050607080910111213141516':str)
|
||||
clean_val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytes
|
||||
read_back_val= {'OPc': '01020304050607080910111213141516'}:{hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.1A_NoBERTLV.der Opc(val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytes)
|
||||
clean_val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytes
|
||||
read_back_val= {'OPc': '01020304050607080910111213141516'}:{hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.1A_NoBERTLV.der Opc(val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytearray)
|
||||
clean_val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytes
|
||||
read_back_val= {'OPc': '01020304050607080910111213141516'}:{hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.3_BERTLV_SUCI.der Imsi(val= '123456':str)
|
||||
clean_val= '123456':str
|
||||
read_back_val= {'IMSI': '123456', 'IMSI-ACC': '0040'}:{str, hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.3_BERTLV_SUCI.der Imsi(val= 123456:int)
|
||||
clean_val= '123456':str
|
||||
read_back_val= {'IMSI': '123456', 'IMSI-ACC': '0040'}:{str, hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.3_BERTLV_SUCI.der Imsi(val= '123456789012345':str)
|
||||
clean_val= '123456789012345':str
|
||||
read_back_val= {'IMSI': '123456789012345', 'IMSI-ACC': '0020'}:{str, hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.3_BERTLV_SUCI.der Imsi(val= 123456789012345:int)
|
||||
clean_val= '123456789012345':str
|
||||
read_back_val= {'IMSI': '123456789012345', 'IMSI-ACC': '0020'}:{str, hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.3_BERTLV_SUCI.der Puk1(val= '12345678':str)
|
||||
clean_val= b'12345678':bytearray
|
||||
read_back_val= {'PUK1': '12345678'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.3_BERTLV_SUCI.der Puk2(val= '12345678':str)
|
||||
clean_val= b'12345678':bytearray
|
||||
read_back_val= {'PUK2': '12345678'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.3_BERTLV_SUCI.der Pin1(val= '1234':str)
|
||||
clean_val= b'1234\xff\xff\xff\xff':bytearray
|
||||
read_back_val= {'PIN1': '1234'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.3_BERTLV_SUCI.der Pin1(val= '123456':str)
|
||||
clean_val= b'123456\xff\xff':bytearray
|
||||
read_back_val= {'PIN1': '123456'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.3_BERTLV_SUCI.der Pin1(val= '12345678':str)
|
||||
clean_val= b'12345678':bytearray
|
||||
read_back_val= {'PIN1': '12345678'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.3_BERTLV_SUCI.der Adm1(val= '1234':str)
|
||||
clean_val= b'1234\xff\xff\xff\xff':bytearray
|
||||
read_back_val= {'ADM1': '1234'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.3_BERTLV_SUCI.der Adm1(val= '123456':str)
|
||||
clean_val= b'123456\xff\xff':bytearray
|
||||
read_back_val= {'ADM1': '123456'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.3_BERTLV_SUCI.der Adm1(val= '12345678':str)
|
||||
clean_val= b'12345678':bytearray
|
||||
read_back_val= {'ADM1': '12345678'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.3_BERTLV_SUCI.der AlgorithmID(val= 'Milenage':str)
|
||||
clean_val= 1:int
|
||||
read_back_val= {'Algorithm': 'Milenage'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.3_BERTLV_SUCI.der AlgorithmID(val= 'TUAK':str)
|
||||
clean_val= 2:int
|
||||
read_back_val= {'Algorithm': 'TUAK'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.3_BERTLV_SUCI.der AlgorithmID(val= 'usim-test':str)
|
||||
clean_val= 3:int
|
||||
read_back_val= {'Algorithm': 'usim_test'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.3_BERTLV_SUCI.der K(val= '01020304050607080910111213141516':str)
|
||||
clean_val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytes
|
||||
read_back_val= {'K': '01020304050607080910111213141516'}:{hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.3_BERTLV_SUCI.der K(val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytes)
|
||||
clean_val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytes
|
||||
read_back_val= {'K': '01020304050607080910111213141516'}:{hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.3_BERTLV_SUCI.der K(val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytearray)
|
||||
clean_val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytes
|
||||
read_back_val= {'K': '01020304050607080910111213141516'}:{hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.3_BERTLV_SUCI.der Opc(val= '01020304050607080910111213141516':str)
|
||||
clean_val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytes
|
||||
read_back_val= {'OPc': '01020304050607080910111213141516'}:{hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.3_BERTLV_SUCI.der Opc(val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytes)
|
||||
clean_val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytes
|
||||
read_back_val= {'OPc': '01020304050607080910111213141516'}:{hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.3_BERTLV_SUCI.der Opc(val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytearray)
|
||||
clean_val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytes
|
||||
read_back_val= {'OPc': '01020304050607080910111213141516'}:{hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.1B_NoBERTLV.der Imsi(val= '123456':str)
|
||||
clean_val= '123456':str
|
||||
read_back_val= {'IMSI': '123456', 'IMSI-ACC': '0040'}:{str, hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.1B_NoBERTLV.der Imsi(val= 123456:int)
|
||||
clean_val= '123456':str
|
||||
read_back_val= {'IMSI': '123456', 'IMSI-ACC': '0040'}:{str, hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.1B_NoBERTLV.der Imsi(val= '123456789012345':str)
|
||||
clean_val= '123456789012345':str
|
||||
read_back_val= {'IMSI': '123456789012345', 'IMSI-ACC': '0020'}:{str, hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.1B_NoBERTLV.der Imsi(val= 123456789012345:int)
|
||||
clean_val= '123456789012345':str
|
||||
read_back_val= {'IMSI': '123456789012345', 'IMSI-ACC': '0020'}:{str, hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.1B_NoBERTLV.der Puk1(val= '12345678':str)
|
||||
clean_val= b'12345678':bytearray
|
||||
read_back_val= {'PUK1': '12345678'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.1B_NoBERTLV.der Puk2(val= '12345678':str)
|
||||
clean_val= b'12345678':bytearray
|
||||
read_back_val= {'PUK2': '12345678'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.1B_NoBERTLV.der Pin1(val= '1234':str)
|
||||
clean_val= b'1234\xff\xff\xff\xff':bytearray
|
||||
read_back_val= {'PIN1': '1234'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.1B_NoBERTLV.der Pin1(val= '123456':str)
|
||||
clean_val= b'123456\xff\xff':bytearray
|
||||
read_back_val= {'PIN1': '123456'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.1B_NoBERTLV.der Pin1(val= '12345678':str)
|
||||
clean_val= b'12345678':bytearray
|
||||
read_back_val= {'PIN1': '12345678'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.1B_NoBERTLV.der Adm1(val= '1234':str)
|
||||
clean_val= b'1234\xff\xff\xff\xff':bytearray
|
||||
read_back_val= {'ADM1': '1234'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.1B_NoBERTLV.der Adm1(val= '123456':str)
|
||||
clean_val= b'123456\xff\xff':bytearray
|
||||
read_back_val= {'ADM1': '123456'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.1B_NoBERTLV.der Adm1(val= '12345678':str)
|
||||
clean_val= b'12345678':bytearray
|
||||
read_back_val= {'ADM1': '12345678'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.1B_NoBERTLV.der AlgorithmID(val= 'Milenage':str)
|
||||
clean_val= 1:int
|
||||
read_back_val= {'Algorithm': 'Milenage'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.1B_NoBERTLV.der AlgorithmID(val= 'TUAK':str)
|
||||
clean_val= 2:int
|
||||
read_back_val= {'Algorithm': 'TUAK'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.1B_NoBERTLV.der AlgorithmID(val= 'usim-test':str)
|
||||
clean_val= 3:int
|
||||
read_back_val= {'Algorithm': 'usim_test'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.1B_NoBERTLV.der K(val= '01020304050607080910111213141516':str)
|
||||
clean_val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytes
|
||||
read_back_val= {'K': '01020304050607080910111213141516'}:{hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.1B_NoBERTLV.der K(val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytes)
|
||||
clean_val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytes
|
||||
read_back_val= {'K': '01020304050607080910111213141516'}:{hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.1B_NoBERTLV.der K(val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytearray)
|
||||
clean_val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytes
|
||||
read_back_val= {'K': '01020304050607080910111213141516'}:{hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.1B_NoBERTLV.der Opc(val= '01020304050607080910111213141516':str)
|
||||
clean_val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytes
|
||||
read_back_val= {'OPc': '01020304050607080910111213141516'}:{hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.1B_NoBERTLV.der Opc(val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytes)
|
||||
clean_val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytes
|
||||
read_back_val= {'OPc': '01020304050607080910111213141516'}:{hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.1B_NoBERTLV.der Opc(val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytearray)
|
||||
clean_val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytes
|
||||
read_back_val= {'OPc': '01020304050607080910111213141516'}:{hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.3_NoBERTLV.der Imsi(val= '123456':str)
|
||||
clean_val= '123456':str
|
||||
read_back_val= {'IMSI': '123456', 'IMSI-ACC': '0040'}:{str, hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.3_NoBERTLV.der Imsi(val= 123456:int)
|
||||
clean_val= '123456':str
|
||||
read_back_val= {'IMSI': '123456', 'IMSI-ACC': '0040'}:{str, hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.3_NoBERTLV.der Imsi(val= '123456789012345':str)
|
||||
clean_val= '123456789012345':str
|
||||
read_back_val= {'IMSI': '123456789012345', 'IMSI-ACC': '0020'}:{str, hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.3_NoBERTLV.der Imsi(val= 123456789012345:int)
|
||||
clean_val= '123456789012345':str
|
||||
read_back_val= {'IMSI': '123456789012345', 'IMSI-ACC': '0020'}:{str, hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.3_NoBERTLV.der Puk1(val= '12345678':str)
|
||||
clean_val= b'12345678':bytearray
|
||||
read_back_val= {'PUK1': '12345678'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.3_NoBERTLV.der Puk2(val= '12345678':str)
|
||||
clean_val= b'12345678':bytearray
|
||||
read_back_val= {'PUK2': '12345678'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.3_NoBERTLV.der Pin1(val= '1234':str)
|
||||
clean_val= b'1234\xff\xff\xff\xff':bytearray
|
||||
read_back_val= {'PIN1': '1234'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.3_NoBERTLV.der Pin1(val= '123456':str)
|
||||
clean_val= b'123456\xff\xff':bytearray
|
||||
read_back_val= {'PIN1': '123456'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.3_NoBERTLV.der Pin1(val= '12345678':str)
|
||||
clean_val= b'12345678':bytearray
|
||||
read_back_val= {'PIN1': '12345678'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.3_NoBERTLV.der Adm1(val= '1234':str)
|
||||
clean_val= b'1234\xff\xff\xff\xff':bytearray
|
||||
read_back_val= {'ADM1': '1234'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.3_NoBERTLV.der Adm1(val= '123456':str)
|
||||
clean_val= b'123456\xff\xff':bytearray
|
||||
read_back_val= {'ADM1': '123456'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.3_NoBERTLV.der Adm1(val= '12345678':str)
|
||||
clean_val= b'12345678':bytearray
|
||||
read_back_val= {'ADM1': '12345678'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.3_NoBERTLV.der AlgorithmID(val= 'Milenage':str)
|
||||
clean_val= 1:int
|
||||
read_back_val= {'Algorithm': 'Milenage'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.3_NoBERTLV.der AlgorithmID(val= 'TUAK':str)
|
||||
clean_val= 2:int
|
||||
read_back_val= {'Algorithm': 'TUAK'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.3_NoBERTLV.der AlgorithmID(val= 'usim-test':str)
|
||||
clean_val= 3:int
|
||||
read_back_val= {'Algorithm': 'usim_test'}:{str}
|
||||
|
||||
ok: TS48v5_SAIP2.3_NoBERTLV.der K(val= '01020304050607080910111213141516':str)
|
||||
clean_val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytes
|
||||
read_back_val= {'K': '01020304050607080910111213141516'}:{hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.3_NoBERTLV.der K(val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytes)
|
||||
clean_val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytes
|
||||
read_back_val= {'K': '01020304050607080910111213141516'}:{hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.3_NoBERTLV.der K(val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytearray)
|
||||
clean_val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytes
|
||||
read_back_val= {'K': '01020304050607080910111213141516'}:{hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.3_NoBERTLV.der Opc(val= '01020304050607080910111213141516':str)
|
||||
clean_val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytes
|
||||
read_back_val= {'OPc': '01020304050607080910111213141516'}:{hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.3_NoBERTLV.der Opc(val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytes)
|
||||
clean_val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytes
|
||||
read_back_val= {'OPc': '01020304050607080910111213141516'}:{hexstr}
|
||||
|
||||
ok: TS48v5_SAIP2.3_NoBERTLV.der Opc(val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytearray)
|
||||
clean_val= b'\x01\x02\x03\x04\x05\x06\x07\x08\t\x10\x11\x12\x13\x14\x15\x16':bytes
|
||||
read_back_val= {'OPc': '01020304050607080910111213141516'}:{hexstr}
|
||||
Reference in New Issue
Block a user