aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilipp Maier <pmaier@sysmocom.de>2021-04-23 21:19:36 +0200
committerdexter <pmaier@sysmocom.de>2021-05-03 15:07:50 +0000
commit6c5cd8031de9428d0e77384a47da6532acf61457 (patch)
treedcb3588de38eb90504dad7fa1cfaca98df019b61
parente6f8d683e1c0efa0bd93378192c2a25e4a872a46 (diff)
utils: fix mcc/mnc encoding in dec_plmn (EF_PLMNsel)
The dec_plmn function takes an hexstring and returns the decoded MCC and MNC as integer values. The result is then used by the json encoder in EF_PLMNsel, which means the json output will contrary to the input, use integer values instead of strings. This is not correct since there may be leading zeros (e.g. mnc 01 and 001 both exist are different) which must be retained in order to know the correct length of the MNC. Related: OS#4963 Change-Id: I393e04836814d992d2a6d0a4e4e01850976d6e81
-rw-r--r--pySim/utils.py45
-rwxr-xr-xtests/test_utils.py15
2 files changed, 55 insertions, 5 deletions
diff --git a/pySim/utils.py b/pySim/utils.py
index fc803de..9694bfa 100644
--- a/pySim/utils.py
+++ b/pySim/utils.py
@@ -136,14 +136,35 @@ def enc_iccid(iccid:str) -> Hexstr:
def enc_plmn(mcc:Hexstr, mnc:Hexstr) -> Hexstr:
"""Converts integer MCC/MNC into 3 bytes for EF"""
- if len(mnc) == 2:
- mnc += "F" # pad to 3 digits if needed
+
+ # Make sure there are no excess whitespaces in the input
+ # parameters
+ mcc = mcc.strip()
+ mnc = mnc.strip()
+
+ # Make sure that MCC/MNC are correctly padded with leading
+ # zeros or 'F', depending on the length.
+ if len(mnc) == 0:
+ mnc = "FFF"
+ elif len(mnc) == 1:
+ mnc = "F0" + mnc
+ elif len(mnc) == 2:
+ mnc += "F"
+
+ if len(mcc) == 0:
+ mcc = "FFF"
+ elif len(mcc) == 1:
+ mcc = "00" + mcc
+ elif len(mcc) == 2:
+ mcc = "0" + mcc
+
return (mcc[1] + mcc[0]) + (mnc[2] + mcc[2]) + (mnc[1] + mnc[0])
def dec_plmn(threehexbytes:Hexstr) -> dict:
- res = {'mcc': 0, 'mnc': 0 }
- res['mcc'] = dec_mcc_from_plmn(threehexbytes)
- res['mnc'] = dec_mnc_from_plmn(threehexbytes)
+ res = {'mcc': "0", 'mnc': "0" }
+ dec_mcc_from_plmn_str(threehexbytes)
+ res['mcc'] = dec_mcc_from_plmn_str(threehexbytes)
+ res['mnc'] = dec_mnc_from_plmn_str(threehexbytes)
return res
def dec_spn(ef):
@@ -172,6 +193,13 @@ def dec_mcc_from_plmn(plmn:Hexstr) -> int:
return 0xFFF # 4095
return derive_mcc(digit1, digit2, digit3)
+def dec_mcc_from_plmn_str(plmn:Hexstr) -> str:
+ digit1 = plmn[1] # 1st byte, LSB
+ digit2 = plmn[0] # 1st byte, MSB
+ digit3 = plmn[3] # 2nd byte, LSB
+ res = digit1 + digit2 + digit3
+ return res.upper().strip("F")
+
def dec_mnc_from_plmn(plmn:Hexstr) -> int:
ia = h2i(plmn)
digit1 = ia[2] & 0x0F # 3rd byte, LSB
@@ -181,6 +209,13 @@ def dec_mnc_from_plmn(plmn:Hexstr) -> int:
return 0xFFF # 4095
return derive_mnc(digit1, digit2, digit3)
+def dec_mnc_from_plmn_str(plmn:Hexstr) -> str:
+ digit1 = plmn[5] # 3rd byte, LSB
+ digit2 = plmn[4] # 3rd byte, MSB
+ digit3 = plmn[2] # 2nd byte, MSB
+ res = digit1 + digit2 + digit3
+ return res.upper().strip("F")
+
def dec_act(twohexbytes:Hexstr) -> List[str]:
act_list = [
{'bit': 15, 'name': "UTRAN"},
diff --git a/tests/test_utils.py b/tests/test_utils.py
index 71c0eb0..b70b17b 100755
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -37,6 +37,12 @@ class DecTestCase(unittest.TestCase):
def testDecMCCfromPLMN_unused(self):
self.assertEqual(utils.dec_mcc_from_plmn("ff0f00"), 4095)
+ def testDecMCCfromPLMN_str(self):
+ self.assertEqual(utils.dec_mcc_from_plmn_str("92f501"), "295")
+
+ def testDecMCCfromPLMN_unused_str(self):
+ self.assertEqual(utils.dec_mcc_from_plmn_str("ff0f00"), "")
+
def testDecMNCfromPLMN_twoDigitMNC(self):
self.assertEqual(utils.dec_mnc_from_plmn("92f501"), 10)
@@ -46,6 +52,15 @@ class DecTestCase(unittest.TestCase):
def testDecMNCfromPLMN_unused(self):
self.assertEqual(utils.dec_mnc_from_plmn("00f0ff"), 4095)
+ def testDecMNCfromPLMN_twoDigitMNC_str(self):
+ self.assertEqual(utils.dec_mnc_from_plmn_str("92f501"), "10")
+
+ def testDecMNCfromPLMN_threeDigitMNC_str(self):
+ self.assertEqual(utils.dec_mnc_from_plmn_str("031263"), "361")
+
+ def testDecMNCfromPLMN_unused_str(self):
+ self.assertEqual(utils.dec_mnc_from_plmn_str("00f0ff"), "")
+
def test_enc_plmn(self):
with self.subTest("2-digit MCC"):
self.assertEqual(utils.enc_plmn("001", "01F"), "00F110")