laforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/pysim/+/35415?usp=email )
Change subject: fix encode/decode of xPLMNwAcT ......................................................................
fix encode/decode of xPLMNwAcT
There are some pretty intricate rules about how GSM and E-UTRAN are encoded, let's make sure we fully support both as per 3GPP TS 31.102 Release 17. As part of this, swithc from a list of access technologies to a set, as there is no order.
Change-Id: I398ac2a2527bd11e9c652e49fa46d6ca8d334b88 --- M pySim/ts_51_011.py M pySim/utils.py M tests/test_utils.py 3 files changed, 53 insertions(+), 35 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/15/35415/1
diff --git a/pySim/ts_51_011.py b/pySim/ts_51_011.py index 7413098..efec79d 100644 --- a/pySim/ts_51_011.py +++ b/pySim/ts_51_011.py @@ -728,8 +728,8 @@ # TS 51.011 Section 10.3.35..37 class EF_xPLMNwAcT(TransRecEF): _test_de_encode = [ - ( '62F2104000', { "mcc": "262", "mnc": "01", "act": [ "E-UTRAN" ] } ), - ( '62F2108000', { "mcc": "262", "mnc": "01", "act": [ "UTRAN" ] } ), + ( '62F2104000', { "mcc": "262", "mnc": "01", "act": set([ "E-UTRAN WB-S1", "E-UTRAN NB-S1" ]) } ), + ( '62F2108000', { "mcc": "262", "mnc": "01", "act": set([ "UTRAN" ]) } ), ] def __init__(self, fid='1234', sfid=None, name=None, desc=None, size=(40, None), rec_len=5, **kwargs): super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, rec_len=rec_len, **kwargs) @@ -763,18 +763,18 @@ if 'cdma2000 1xRTT' in in_list: u16 |= 0x0010 # E-UTRAN - if 'E-UTRAN' in in_list: + if 'E-UTRAN WB-S1' in in_list and 'E-UTRAN NB-S1' in in_list: u16 |= 0x4000 - if 'E-UTRAN WB-S1' in in_list: + elif 'E-UTRAN WB-S1' in in_list: u16 |= 0x6000 - if 'E-UTRAN NB-S1' in in_list: + elif 'E-UTRAN NB-S1' in in_list: u16 |= 0x5000 # GSM mess if 'GSM' in in_list and 'EC-GSM-IoT' in in_list: u16 |= 0x008C elif 'GSM' in in_list: u16 |= 0x0084 - elif 'EC-GSM-IuT' in in_list: + elif 'EC-GSM-IoT' in in_list: u16 |= 0x0088 return '%04X' % (u16)
diff --git a/pySim/utils.py b/pySim/utils.py index aac9877..62104cd 100644 --- a/pySim/utils.py +++ b/pySim/utils.py @@ -486,37 +486,41 @@ def dec_act(twohexbytes: Hexstr) -> List[str]: act_list = [ {'bit': 15, 'name': "UTRAN"}, - {'bit': 14, 'name': "E-UTRAN"}, {'bit': 11, 'name': "NG-RAN"}, - {'bit': 7, 'name': "GSM"}, {'bit': 6, 'name': "GSM COMPACT"}, {'bit': 5, 'name': "cdma2000 HRPD"}, {'bit': 4, 'name': "cdma2000 1xRTT"}, ] ia = h2i(twohexbytes) u16t = (ia[0] << 8) | ia[1] - sel = [] + sel = set() + # only the simple single-bit ones for a in act_list: if u16t & (1 << a['bit']): - if a['name'] == "E-UTRAN": - # The Access technology identifier of E-UTRAN - # allows a more detailed specification: - if u16t & (1 << 13) and u16t & (1 << 12): - sel.append("E-UTRAN WB-S1") - sel.append("E-UTRAN NB-S1") - elif u16t & (1 << 13): - sel.append("E-UTRAN WB-S1") - elif u16t & (1 << 12): - sel.append("E-UTRAN NB-S1") - else: - sel.append("E-UTRAN") - else: - sel.append(a['name']) + sel.add(a['name']) + # TS 31.102 Section 4.2.5 Table 4.2.5.1 + eutran_bits = u16t & 0x7000 + if eutran_bits == 0x4000 or eutran_bits == 0x7000: + sel.add("E-UTRAN WB-S1") + sel.add("E-UTRAN NB-S1") + elif eutran_bits == 0x5000: + sel.add("E-UTRAN NB-S1") + elif eutran_bits == 0x6000: + sel.add("E-UTRAN WB-S1") + # TS 31.102 Section 4.2.5 Table 4.2.5.2 + gsm_bits = u16t & 0x008C + if gsm_bits == 0x0080 or gsm_bits == 0x008C: + sel.add("GSM") + sel.add("EC-GSM-IoT") + elif u16t & 0x008C == 0x0084: + sel.add("GSM") + elif u16t & 0x008C == 0x0086: + sel.add("EC-GSM-IoT") return sel
def dec_xplmn_w_act(fivehexbytes: Hexstr) -> Dict[str, Any]: - res = {'mcc': "0", 'mnc': "0", 'act': []} + res = {'mcc': "0", 'mnc': "0", 'act': set()} plmn_chars = 6 act_chars = 4 # first three bytes (six ascii hex chars) @@ -530,7 +534,7 @@
def dec_xplmn(threehexbytes: Hexstr) -> dict: - res = {'mcc': 0, 'mnc': 0, 'act': []} + res = {'mcc': 0, 'mnc': 0, 'act': set()} plmn_chars = 6 # first three bytes (six ascii hex chars) plmn_str = threehexbytes[:plmn_chars] diff --git a/tests/test_utils.py b/tests/test_utils.py index 764cf71..a30b1ff 100755 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -89,34 +89,34 @@ self.assertEqual(utils.enc_plmn("302", "361"), "031263")
def testDecAct_noneSet(self): - self.assertEqual(utils.dec_act("0000"), []) + self.assertEqual(utils.dec_act("0000"), set([]))
def testDecAct_onlyUtran(self): - self.assertEqual(utils.dec_act("8000"), ["UTRAN"]) + self.assertEqual(utils.dec_act("8000"), set(["UTRAN"]))
def testDecAct_onlyEUtran(self): - self.assertEqual(utils.dec_act("4000"), ["E-UTRAN"]) + self.assertEqual(utils.dec_act("4000"), set(["E-UTRAN WB-S1", "E-UTRAN NB-S1"]))
def testDecAct_onlyNgRan(self): - self.assertEqual(utils.dec_act("0800"), ["NG-RAN"]) + self.assertEqual(utils.dec_act("0800"), set(["NG-RAN"]))
def testDecAct_onlyGsm(self): - self.assertEqual(utils.dec_act("0080"), ["GSM"]) + self.assertEqual(utils.dec_act("0084"), set(["GSM"]))
def testDecAct_onlyGsmCompact(self): - self.assertEqual(utils.dec_act("0040"), ["GSM COMPACT"]) + self.assertEqual(utils.dec_act("0040"), set(["GSM COMPACT"]))
def testDecAct_onlyCdma2000HRPD(self): - self.assertEqual(utils.dec_act("0020"), ["cdma2000 HRPD"]) + self.assertEqual(utils.dec_act("0020"), set(["cdma2000 HRPD"]))
def testDecAct_onlyCdma20001xRTT(self): - self.assertEqual(utils.dec_act("0010"), ["cdma2000 1xRTT"]) + self.assertEqual(utils.dec_act("0010"), set(["cdma2000 1xRTT"]))
def testDecAct_allSet(self): - self.assertEqual(utils.dec_act("ffff"), ["UTRAN", "E-UTRAN WB-S1", "E-UTRAN NB-S1", "NG-RAN", "GSM", "GSM COMPACT", "cdma2000 HRPD", "cdma2000 1xRTT"]) + self.assertEqual(utils.dec_act("ffff"), set(["UTRAN", "E-UTRAN WB-S1", "E-UTRAN NB-S1", "NG-RAN", "GSM", "GSM COMPACT", "EC-GSM-IoT", "cdma2000 HRPD", "cdma2000 1xRTT"]))
def testDecxPlmn_w_act(self): - expected = {'mcc': '295', 'mnc': '10', 'act': ["UTRAN"]} + expected = {'mcc': '295', 'mnc': '10', 'act': set(["UTRAN"])} self.assertEqual(utils.dec_xplmn_w_act("92f5018000"), expected)
def testFormatxPlmn_w_act(self):