blob: 43d52dd41005cd7b8c2ae8323260c8148b14a63e [file] [log] [blame]
Sylvain Munaut76504e02010-12-07 00:24:32 +01001#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4""" pySim: various utilities
5"""
6
7#
8# Copyright (C) 2009-2010 Sylvain Munaut <tnt@246tNt.com>
9#
10# This program is free software: you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation, either version 2 of the License, or
13# (at your option) any later version.
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with this program. If not, see <http://www.gnu.org/licenses/>.
22#
23
24
25def h2b(s):
26 return ''.join([chr((int(x,16)<<4)+int(y,16)) for x,y in zip(s[0::2], s[1::2])])
27
28def b2h(s):
29 return ''.join(['%02x'%ord(x) for x in s])
30
31def h2i(s):
32 return [(int(x,16)<<4)+int(y,16) for x,y in zip(s[0::2], s[1::2])]
33
34def i2h(s):
35 return ''.join(['%02x'%(x) for x in s])
36
Alexander Chemerisa5f0ea62017-07-18 16:48:47 +030037def h2s(s):
38 return ''.join([chr((int(x,16)<<4)+int(y,16)) for x,y in zip(s[0::2], s[1::2]) if not (x == 'f' and y == 'f') ])
39
40def s2h(s):
41 return b2h(s)
42
Sylvain Munaut76504e02010-12-07 00:24:32 +010043def swap_nibbles(s):
44 return ''.join([x+y for x,y in zip(s[1::2], s[0::2])])
45
46def rpad(s, l, c='f'):
47 return s + c * (l - len(s))
48
49def lpad(s, l, c='f'):
50 return c * (l - len(s)) + s
Alexander Chemeris5e96c3d2013-07-04 17:33:33 +040051
Alexander Chemeris7be92ff2013-07-10 11:18:06 +040052def enc_imsi(imsi):
53 """Converts a string imsi into the value of the EF"""
54 l = (len(imsi) + 1) // 2 # Required bytes
55 oe = len(imsi) & 1 # Odd (1) / Even (0)
56 ei = '%02x' % l + swap_nibbles(lpad('%01x%s' % ((oe<<3)|1, imsi), 16))
57 return ei
58
Alexander Chemeris5e96c3d2013-07-04 17:33:33 +040059def dec_imsi(ef):
60 """Converts an EF value to the imsi string representation"""
61 if len(ef) < 4:
62 return None
Pau Espin Pedrol665bd222017-12-29 20:30:35 +010063 l = int(ef[0:2], 16) * 2 # Length of the IMSI string
Alexander Chemeris5e96c3d2013-07-04 17:33:33 +040064 swapped = swap_nibbles(ef[2:])
65 oe = (int(swapped[0])>>3) & 1 # Odd (1) / Even (0)
66 if oe:
67 l = l-1
68 if l+1 > len(swapped):
69 return None
70 imsi = swapped[1:l+2]
71 return imsi
72
73def dec_iccid(ef):
74 return swap_nibbles(ef).strip('f')
Alexander Chemeris7be92ff2013-07-10 11:18:06 +040075
76def enc_iccid(iccid):
77 return swap_nibbles(rpad(iccid, 20))
78
79def enc_plmn(mcc, mnc):
Alexander Chemerisdddbf522017-07-18 16:49:59 +030080 """Converts integer MCC/MNC into 3 bytes for EF"""
Alexander Chemeris7be92ff2013-07-10 11:18:06 +040081 return swap_nibbles(lpad('%d' % mcc, 3) + lpad('%d' % mnc, 3))
Alexander Chemerisa5f0ea62017-07-18 16:48:47 +030082
83def dec_spn(ef):
84 byte1 = int(ef[0:2])
85 hplmn_disp = (byte1&0x01 == 0x01)
86 oplmn_disp = (byte1&0x02 == 0x02)
87 name = h2s(ef[2:])
88 return (name, hplmn_disp, oplmn_disp)
89
90def enc_spn(name, hplmn_disp=False, oplmn_disp=False):
91 byte1 = 0x00
92 if hplmn_disp: byte1 = byte1|0x01
93 if oplmn_disp: byte1 = byte1|0x02
94 return i2h([byte1])+s2h(name)