aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSupreeth Herle <herlesupreeth@gmail.com>2019-12-22 09:00:59 +0100
committerVadim Yanitskiy <axilirator@gmail.com>2020-02-15 04:22:53 +0700
commit4b1c7633954697eda687fb122a73166446fa1f83 (patch)
treed24712f16bbfb75d163dec85924abde1b9e247e8
parentd24f1635135f72743345c0296dd469ec037eff5b (diff)
pySim-read.py: fix reading and parsing of EF.MSISDN
This change implements parsing of EF.MSISDN (and thus EF.ADN) as per 3GPP TS 31.102, sections 4.2.26 and 4.4.2.3. Example (commercial SIM card from 401/02): EF.MSISDN: ffffffffffffffffffffffffffff07917787028982f7ffffffffffff Decoded (NPI=1 ToN=1): +77782098287 Note that sysmoUSIM-SJS1 in the test setup has malformed EF.MSISDN, so that's why the test output is changed. Change-Id: Ie914ae83d787e3f1a90f9f305bffd45053b8c863
-rwxr-xr-xpySim-read.py8
-rw-r--r--pySim/utils.py41
-rw-r--r--pysim-testdata/sysmoISIM-SJA2.ok2
-rw-r--r--pysim-testdata/sysmoUSIM-SJS1.ok2
4 files changed, 48 insertions, 5 deletions
diff --git a/pySim-read.py b/pySim-read.py
index d753c8b..ce5f8a5 100755
--- a/pySim-read.py
+++ b/pySim-read.py
@@ -37,7 +37,7 @@ except ImportError:
import simplejson as json
from pySim.commands import SimCardCommands
-from pySim.utils import h2b, swap_nibbles, rpad, dec_imsi, dec_iccid, format_xplmn_w_act, dec_spn
+from pySim.utils import h2b, swap_nibbles, rpad, dec_imsi, dec_iccid, dec_msisdn, format_xplmn_w_act, dec_spn
def parse_options():
@@ -186,8 +186,10 @@ if __name__ == '__main__':
# print(scc.record_size(['3f00', '7f10', '6f40']))
(res, sw) = scc.read_record(['3f00', '7f10', '6f40'], 1)
if sw == '9000':
- if res[1] != 'f':
- print("MSISDN: %s" % (res,))
+ res_dec = dec_msisdn(res)
+ if res_dec is not None:
+ # (npi, ton, msisdn) = res_dec
+ print("MSISDN (NPI=%d ToN=%d): %s" % res_dec)
else:
print("MSISDN: Not available")
else:
diff --git a/pySim/utils.py b/pySim/utils.py
index af4a491..12f66b9 100644
--- a/pySim/utils.py
+++ b/pySim/utils.py
@@ -258,3 +258,44 @@ def derive_mnc(digit1, digit2, digit3=0x0f):
mnc += digit2
return mnc
+
+def dec_msisdn(ef_msisdn):
+ """
+ Decode MSISDN from EF.MSISDN or EF.ADN (same structure).
+ See 3GPP TS 31.102, section 4.2.26 and 4.4.2.3.
+ """
+
+ # Convert from str to (kind of) 'bytes'
+ ef_msisdn = h2b(ef_msisdn)
+
+ # Make sure mandatory fields are present
+ if len(ef_msisdn) < 14:
+ raise ValueError("EF.MSISDN is too short")
+
+ # Skip optional Alpha Identifier
+ xlen = len(ef_msisdn) - 14
+ msisdn_lhv = ef_msisdn[xlen:]
+
+ # Parse the length (in bytes) of the BCD encoded number
+ bcd_len = ord(msisdn_lhv[0])
+ # BCD length = length of dial num (max. 10 bytes) + 1 byte ToN and NPI
+ if bcd_len == 0xff:
+ return None
+ elif bcd_len > 11 or bcd_len < 1:
+ raise ValueError("Length of MSISDN (%d bytes) is out of range" % bcd_len)
+
+ # Parse ToN / NPI
+ ton = (ord(msisdn_lhv[1]) >> 4) & 0x07
+ npi = ord(msisdn_lhv[1]) & 0x0f
+ bcd_len -= 1
+
+ # No MSISDN?
+ if not bcd_len:
+ return (npi, ton, None)
+
+ msisdn = swap_nibbles(b2h(msisdn_lhv[2:][:bcd_len])).rstrip('f')
+ # International number 10.5.118/3GPP TS 24.008
+ if (ton & 0x01) == 0x01:
+ msisdn = '+' + msisdn
+
+ return (npi, ton, msisdn)
diff --git a/pysim-testdata/sysmoISIM-SJA2.ok b/pysim-testdata/sysmoISIM-SJA2.ok
index a64aa8b..bfef882 100644
--- a/pysim-testdata/sysmoISIM-SJA2.ok
+++ b/pysim-testdata/sysmoISIM-SJA2.ok
@@ -50,7 +50,7 @@ HPLMNAcT:
ffffff0000 # unused
ACC: 0001
-MSISDN: Not available
+MSISDN (NPI=1 ToN=1): +1234
AD: 00000002
Done !
diff --git a/pysim-testdata/sysmoUSIM-SJS1.ok b/pysim-testdata/sysmoUSIM-SJS1.ok
index 8def4e3..6d85f38 100644
--- a/pysim-testdata/sysmoUSIM-SJS1.ok
+++ b/pysim-testdata/sysmoUSIM-SJS1.ok
@@ -50,7 +50,7 @@ HPLMNAcT:
ffffff0000 # unused
ACC: 0008
-MSISDN: Not available
+MSISDN: Can't read file -- Length of MSISDN (136 bytes) is out of range
AD: 00000002
Done !