Change in pysim[master]: utils: add EF [H|O]PLMNwAcT decoding.

Harald Welte gerrit-no-reply at lists.osmocom.org
Fri May 10 15:05:45 UTC 2019


Harald Welte has submitted this change and it was merged. ( https://gerrit.osmocom.org/12123 )

Change subject: utils: add EF [H|O]PLMNwAcT decoding.
......................................................................

utils: add EF [H|O]PLMNwAcT decoding.

Allow decoding and pretty printing of PLMNwAcT, HPLMNwAcT and OPLMNwAct.

Includes unit tests for the added functions.

Change-Id: I9b8ca6ffd98f665690b84239d9a228e2c72c6ff9
---
M pySim-read.py
M pySim/utils.py
A pySim/utils_test.py
M pysim-testdata/sysmoUSIM-SJS1.ok
4 files changed, 195 insertions(+), 7 deletions(-)

Approvals:
  Jenkins Builder: Verified
  Harald Welte: Looks good to me, approved



diff --git a/pySim-read.py b/pySim-read.py
index bcdbca6..16607cf 100755
--- a/pySim-read.py
+++ b/pySim-read.py
@@ -37,7 +37,7 @@
 	import simplejson as json
 
 from pySim.commands import SimCardCommands
-from pySim.utils import h2b, swap_nibbles, rpad, dec_imsi, dec_iccid
+from pySim.utils import h2b, swap_nibbles, rpad, dec_imsi, dec_iccid, format_xplmn_w_act
 
 
 def parse_options():
@@ -129,7 +129,7 @@
         try:
 	        (res, sw) = scc.read_binary(EF['PLMNwAcT'])
 	        if sw == '9000':
-		        print("PLMNwAcT: %s" % (res))
+		        print("PLMNwAcT:\n%s" % (format_xplmn_w_act(res)))
 	        else:
 		        print("PLMNwAcT: Can't read, response code = %s" % (sw,))
 	except Exception as e:
@@ -139,7 +139,7 @@
         try:
 	        (res, sw) = scc.read_binary(EF['OPLMNwAcT'])
 	        if sw == '9000':
-		        print("OPLMNwAcT: %s" % (res))
+		        print("OPLMNwAcT:\n%s" % (format_xplmn_w_act(res)))
 	        else:
 		        print("OPLMNwAcT: Can't read, response code = %s" % (sw,))
 	except Exception as e:
@@ -149,7 +149,7 @@
         try:
 	        (res, sw) = scc.read_binary(EF['HPLMNAcT'])
 	        if sw == '9000':
-		        print("HPLMNAcT: %s" % (res))
+		        print("HPLMNAcT:\n%s" % (format_xplmn_w_act(res)))
 	        else:
 		        print("HPLMNAcT: Can't read, response code = %s" % (sw,))
 	except Exception as e:
diff --git a/pySim/utils.py b/pySim/utils.py
index ba94702..65f10c5 100644
--- a/pySim/utils.py
+++ b/pySim/utils.py
@@ -113,6 +113,79 @@
 	if oplmn_disp: byte1 = byte1|0x02
 	return i2h([byte1])+s2h(name)
 
+def hexstr_to_fivebytearr(s):
+	return [s[i:i+10] for i in range(0, len(s), 10) ]
+
+# Accepts hex string representing three bytes
+def dec_mcc_from_plmn(plmn):
+	ia = h2i(plmn)
+	digit1 = ia[0] & 0x0F		# 1st byte, LSB
+	digit2 = (ia[0] & 0xF0) >> 4	# 1st byte, MSB
+	digit3 = ia[1] & 0x0F		# 2nd byte, LSB
+	if digit3 == 0xF and digit2 == 0xF and digit1 == 0xF:
+		return 0xFFF # 4095
+	mcc = digit1 * 100
+	mcc += digit2 * 10
+	mcc += digit3
+	return mcc
+
+def dec_mnc_from_plmn(plmn):
+	ia = h2i(plmn)
+	digit1 = ia[2] & 0x0F		# 3rd byte, LSB
+	digit2 = (ia[2] & 0xF0) >> 4	# 3rd byte, MSB
+	digit3 = (ia[1] & 0xF0) >> 4	# 2nd byte, MSB
+	if digit3 == 0xF and digit2 == 0xF and digit1 == 0xF:
+		return 0xFFF # 4095
+	mnc = 0
+	# signifies two digit MNC
+	if digit3 == 0xF:
+		mnc += digit1 * 10
+		mnc += digit2
+	else:
+		mnc += digit1 * 100
+		mnc += digit2 * 10
+		mnc += digit3
+	return mnc
+
+def dec_act(twohexbytes):
+	act_list = [
+		{'bit': 15, 'name': "UTRAN"},
+		{'bit': 14, 'name': "E-UTRAN"},
+		{'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 = []
+	for a in act_list:
+		if u16t & (1 << a['bit']):
+			sel.append(a['name'])
+	return sel
+
+def dec_xplmn_w_act(fivehexbytes):
+	res = {'mcc': 0, 'mnc': 0, 'act': []}
+	plmn_chars = 6
+	act_chars = 4
+	plmn_str = fivehexbytes[:plmn_chars]				# first three bytes (six ascii hex chars)
+	act_str = fivehexbytes[plmn_chars:plmn_chars + act_chars]	# two bytes after first three bytes
+	res['mcc'] = dec_mcc_from_plmn(plmn_str)
+	res['mnc'] = dec_mnc_from_plmn(plmn_str)
+	res['act'] = dec_act(act_str)
+	return res
+
+def format_xplmn_w_act(hexstr):
+	s = ""
+	for rec_data in hexstr_to_fivebytearr(hexstr):
+		rec_info = dec_xplmn_w_act(rec_data)
+		if rec_info['mcc'] == 0xFFF and rec_info['mnc'] == 0xFFF:
+			rec_str = "unused"
+		else:
+			rec_str = "MCC: %3s MNC: %3s AcT: %s" % (rec_info['mcc'], rec_info['mnc'], ", ".join(rec_info['act']))
+		s += "\t%s # %s\n" % (rec_data, rec_str)
+	return s
+
 def derive_milenage_opc(ki_hex, op_hex):
 	"""
 	Run the milenage algorithm to calculate OPC from Ki and OP
diff --git a/pySim/utils_test.py b/pySim/utils_test.py
new file mode 100644
index 0000000..ff028da
--- /dev/null
+++ b/pySim/utils_test.py
@@ -0,0 +1,76 @@
+#!/usr/bin/pyton
+
+import unittest
+import utils 
+
+class DecTestCase(unittest.TestCase):
+
+	def testSplitHexStringToListOf5ByteEntries(self):
+		input_str = "ffffff0003ffffff0002ffffff0001"
+		expected = [
+			"ffffff0003",
+			"ffffff0002",
+			"ffffff0001",
+		]
+		self.assertEqual(utils.hexstr_to_fivebytearr(input_str), expected)
+
+	def testDecMCCfromPLMN(self):
+		self.assertEqual(utils.dec_mcc_from_plmn("92f501"), 295)
+
+	def testDecMCCfromPLMN_unused(self):
+		self.assertEqual(utils.dec_mcc_from_plmn("ff0f00"), 4095)
+
+	def testDecMNCfromPLMN_twoDigitMNC(self):
+		self.assertEqual(utils.dec_mnc_from_plmn("92f501"), 10)
+
+	def testDecMNCfromPLMN_threeDigitMNC(self):
+		self.assertEqual(utils.dec_mnc_from_plmn("031263"), 361)
+
+	def testDecMNCfromPLMN_unused(self):
+		self.assertEqual(utils.dec_mnc_from_plmn("00f0ff"), 4095)
+
+	def testDecAct_noneSet(self):
+		self.assertEqual(utils.dec_act("0000"), [])
+
+	def testDecAct_onlyUtran(self):
+		self.assertEqual(utils.dec_act("8000"), ["UTRAN"])
+
+	def testDecAct_onlyEUtran(self):
+		self.assertEqual(utils.dec_act("4000"), ["E-UTRAN"])
+
+	def testDecAct_onlyGsm(self):
+		self.assertEqual(utils.dec_act("0080"), ["GSM"])
+
+	def testDecAct_onlyGsmCompact(self):
+		self.assertEqual(utils.dec_act("0040"), ["GSM COMPACT"])
+
+	def testDecAct_onlyCdma2000HRPD(self):
+		self.assertEqual(utils.dec_act("0020"), ["cdma2000 HRPD"])
+
+	def testDecAct_onlyCdma20001xRTT(self):
+		self.assertEqual(utils.dec_act("0010"), ["cdma2000 1xRTT"])
+
+	def testDecAct_allSet(self):
+		self.assertEqual(utils.dec_act("ffff"), ["UTRAN", "E-UTRAN", "GSM", "GSM COMPACT", "cdma2000 HRPD", "cdma2000 1xRTT"])
+
+	def testDecxPlmn_w_act(self):
+		expected = {'mcc': 295, 'mnc': 10, 'act': ["UTRAN"]}
+		self.assertEqual(utils.dec_xplmn_w_act("92f5018000"), expected)
+
+	def testFormatxPlmn_w_act(self):
+		input_str = "92f501800092f5508000ffffff0000ffffff0000ffffff0000ffffff0000ffffff0000ffffff0000ffffff0000ffffff0000"
+		expected = '''92f5018000 # MCC: 295 MNC:  10 AcT: UTRAN
+92f5508000 # MCC: 295 MNC:   5 AcT: UTRAN
+ffffff0000 # unused
+ffffff0000 # unused
+ffffff0000 # unused
+ffffff0000 # unused
+ffffff0000 # unused
+ffffff0000 # unused
+ffffff0000 # unused
+ffffff0000 # unused
+'''
+		self.assertEqual(utils.format_xplmn_w_act(input_str), expected)
+
+if __name__ == "__main__":
+	unittest.main()
diff --git a/pysim-testdata/sysmoUSIM-SJS1.ok b/pysim-testdata/sysmoUSIM-SJS1.ok
index 0b79934..275e79e 100644
--- a/pysim-testdata/sysmoUSIM-SJS1.ok
+++ b/pysim-testdata/sysmoUSIM-SJS1.ok
@@ -3,9 +3,48 @@
 IMSI: 001010000000102
 SMSP: ffffffffffffffffffffffffffffffffffffffffffffffffe1ffffffffffffffffffffffff0581005155f5ffffffffffff000000
 PLMNsel: fff11fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-PLMNwAcT: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-OPLMNwAcT: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-HPLMNAcT: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
+PLMNwAcT:
+	fff11fffff # MCC: 1651 MNC: 151 AcT: UTRAN, E-UTRAN, GSM, GSM COMPACT, cdma2000 HRPD, cdma2000 1xRTT
+	ffffff0000 # unused
+	ffffff0000 # unused
+	ffffff0000 # unused
+	ffffff0000 # unused
+	ffffff0000 # unused
+	ffffff0000 # unused
+	ffffff0000 # unused
+	ffffff0000 # unused
+	ffffff0000 # unused
+	ffffff0000 # unused
+	ffffff0000 # unused
+
+OPLMNwAcT:
+	fff11fffff # MCC: 1651 MNC: 151 AcT: UTRAN, E-UTRAN, GSM, GSM COMPACT, cdma2000 HRPD, cdma2000 1xRTT
+	ffffff0000 # unused
+	ffffff0000 # unused
+	ffffff0000 # unused
+	ffffff0000 # unused
+	ffffff0000 # unused
+	ffffff0000 # unused
+	ffffff0000 # unused
+	ffffff0000 # unused
+	ffffff0000 # unused
+	ffffff0000 # unused
+	ffffff0000 # unused
+
+HPLMNAcT:
+	ffffffffff # unused
+	ffffffffff # unused
+	ffffffffff # unused
+	ffffffffff # unused
+	ffffffffff # unused
+	ffffffffff # unused
+	ffffffffff # unused
+	ffffffffff # unused
+	ffffffffff # unused
+	ffffffffff # unused
+	ffffffffff # unused
+	ffffffffff # unused
+
 ACC: 0008
 MSISDN: Not available
 AD: 00000002

-- 
To view, visit https://gerrit.osmocom.org/12123
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-MessageType: merged
Gerrit-Change-Id: I9b8ca6ffd98f665690b84239d9a228e2c72c6ff9
Gerrit-Change-Number: 12123
Gerrit-PatchSet: 7
Gerrit-Owner: lazlo <dlsitzer at gmail.com>
Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Jenkins Builder (1000002)
Gerrit-Reviewer: dexter <pmaier at sysmocom.de>
Gerrit-CC: Neels Hofmeyr <nhofmeyr at sysmocom.de>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20190510/136557b4/attachment.html>


More information about the gerrit-log mailing list