blob: 3fab55864a5a0837bc9c7a9bce75370ea9cb17ee [file] [log] [blame]
Vadim Yanitskiy87dd0202023-04-22 20:45:29 +07001# coding=utf-8
2"""R-UIM (Removable User Identity Module) card profile (see 3GPP2 C.S0023-D)
3
4(C) 2023 by Vadim Yanitskiy <fixeria@osmocom.org>
5
6This program is free software: you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation, either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program. If not, see <http://www.gnu.org/licenses/>.
18"""
19
20import enum
21
22from pySim.utils import *
23from pySim.filesystem import *
24from pySim.profile import match_ruim
25from pySim.profile import CardProfile
26from pySim.ts_51_011 import CardProfileSIM
27from pySim.ts_51_011 import DF_TELECOM, DF_GSM
28from pySim.ts_51_011 import EF_ServiceTable
29from pySim.construct import *
30from construct import *
31
32
33# Mapping between CDMA Service Number and its description
34EF_CST_map = {
35 1 : 'CHV disable function',
36 2 : 'Abbreviated Dialing Numbers (ADN)',
37 3 : 'Fixed Dialing Numbers (FDN)',
38 4 : 'Short Message Storage (SMS)',
39 5 : 'HRPD',
40 6 : 'Enhanced Phone Book',
41 7 : 'Multi Media Domain (MMD)',
42 8 : 'SF_EUIMID-based EUIMID',
43 9 : 'MEID Support',
44 10 : 'Extension1',
45 11 : 'Extension2',
46 12 : 'SMS Parameters',
47 13 : 'Last Number Dialled (LND)',
48 14 : 'Service Category Program for BC-SMS',
49 15 : 'Messaging and 3GPD Extensions',
50 16 : 'Root Certificates',
51 17 : 'CDMA Home Service Provider Name',
52 18 : 'Service Dialing Numbers (SDN)',
53 19 : 'Extension3',
54 20 : '3GPD-SIP',
55 21 : 'WAP Browser',
56 22 : 'Java',
57 23 : 'Reserved for CDG',
58 24 : 'Reserved for CDG',
59 25 : 'Data Download via SMS Broadcast',
60 26 : 'Data Download via SMS-PP',
61 27 : 'Menu Selection',
62 28 : 'Call Control',
63 29 : 'Proactive R-UIM',
64 30 : 'AKA',
65 31 : 'IPv6',
66 32 : 'RFU',
67 33 : 'RFU',
68 34 : 'RFU',
69 35 : 'RFU',
70 36 : 'RFU',
71 37 : 'RFU',
72 38 : '3GPD-MIP',
73 39 : 'BCMCS',
74 40 : 'Multimedia Messaging Service (MMS)',
75 41 : 'Extension 8',
76 42 : 'MMS User Connectivity Parameters',
77 43 : 'Application Authentication',
78 44 : 'Group Identifier Level 1',
79 45 : 'Group Identifier Level 2',
80 46 : 'De-Personalization Control Keys',
81 47 : 'Cooperative Network List',
82}
83
84
85######################################################################
86# DF.CDMA
87######################################################################
88
89class EF_SPN(TransparentEF):
90 '''3.4.31 CDMA Home Service Provider Name'''
91
92 _test_de_encode = [
93 ( "010801536b796c696e6b204e57ffffffffffffffffffffffffffffffffffffffffffff",
94 { 'rfu0' : 0, 'show_in_hsa' : True, 'rfu2' : 0,
95 'char_encoding' : 8, 'lang_ind' : 1, 'spn' : 'Skylink NW' } ),
96 ]
97
98 def __init__(self, fid='6f41', sfid=None, name='EF.SPN',
99 desc='Service Provider Name', size=(35, 35), **kwargs):
100 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
101 self._construct = BitStruct(
102 # Byte 1: Display Condition
103 'rfu1'/BitsRFU(7),
104 'show_in_hsa'/Flag,
105 # Byte 2: Character Encoding
106 'rfu2'/BitsRFU(3),
107 'char_encoding'/BitsInteger(5), # see C.R1001-G
108 # Byte 3: Language Indicator
109 'lang_ind'/BitsInteger(8), # see C.R1001-G
110 # Bytes 4-35: Service Provider Name
111 'spn'/Bytewise(GsmString(32))
112 )
113
114class EF_AD(TransparentEF):
115 '''3.4.33 Administrative Data'''
116
117 _test_de_encode = [
118 ( "000000", { 'ms_operation_mode' : 'normal', 'additional_info' : '0000', 'rfu' : '' } ),
119 ]
120
121 class OP_MODE(enum.IntEnum):
122 normal = 0x00
123 type_approval = 0x80
124 normal_and_specific_facilities = 0x01
125 type_approval_and_specific_facilities = 0x81
126 maintenance_off_line = 0x02
127 cell_test = 0x04
128
129 def __init__(self, fid='6f43', sfid=None, name='EF.AD',
130 desc='Service Provider Name', size=(3, None), **kwargs):
131 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
132 self._construct = Struct(
133 # Byte 1: Display Condition
134 'ms_operation_mode'/Enum(Byte, self.OP_MODE),
135 # Bytes 2-3: Additional information
136 'additional_info'/Bytes(2),
137 # Bytes 4..: RFU
138 'rfu'/GreedyBytesRFU,
139 )
140
141
142class EF_SMS(LinFixedEF):
143 '''3.4.27 Short Messages'''
144 def __init__(self, fid='6f3c', sfid=None, name='EF.SMS', desc='Short messages', **kwargs):
145 super().__init__(fid, sfid=sfid, name=name, desc=desc, rec_len=(2, 255), **kwargs)
146 self._construct = Struct(
147 # Byte 1: Status
148 'status'/BitStruct(
149 'rfu87'/BitsRFU(2),
150 'protection'/Flag,
151 'rfu54'/BitsRFU(2),
152 'status'/FlagsEnum(BitsInteger(2), read=0, to_be_read=1, sent=2, to_be_sent=3),
153 'used'/Flag,
154 ),
155 # Byte 2: Length
156 'length'/Int8ub,
157 # Bytes 3..: SMS Transport Layer Message
158 'tpdu'/Bytes(lambda ctx: ctx.length if ctx.status.used else 0),
159 )
160
161
162class DF_CDMA(CardDF):
163 def __init__(self):
164 super().__init__(fid='7f25', name='DF.CDMA',
165 desc='CDMA related files (3GPP2 C.S0023-D)')
166 files = [
167 # TODO: lots of other files
168 EF_ServiceTable('6f32', None, 'EF.CST',
169 'CDMA Service Table', table=EF_CST_map, size=(5, 16)),
170 EF_SPN(),
171 EF_AD(),
172 EF_SMS(),
173 ]
174 self.add_files(files)
175
176
177class CardProfileRUIM(CardProfile):
178 '''R-UIM card profile as per 3GPP2 C.S0023-D'''
179
180 ORDER = 2
181
182 def __init__(self):
183 super().__init__('R-UIM', desc='CDMA R-UIM Card', cla="a0",
184 sel_ctrl="0000", files_in_mf=[DF_TELECOM(), DF_GSM(), DF_CDMA()])
185
186 @staticmethod
187 def decode_select_response(resp_hex: str) -> object:
188 # TODO: Response parameters/data in case of DF_CDMA (section 2.6)
189 return CardProfileSIM.decode_select_response(resp_hex)
190
191 @staticmethod
192 def match_with_card(scc: SimCardCommands) -> bool:
193 return match_ruim(scc)