blob: ad50e607e9726e76e402024afce7b774c0622918 [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
Harald Welte323a3502023-07-11 17:26:39 +020025from pySim.profile import CardProfile, CardProfileAddon
Vadim Yanitskiy87dd0202023-04-22 20:45:29 +070026from 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",
Harald Weltef9e2df12023-07-11 21:03:54 +020094 { 'rfu1' : 0, 'show_in_hsa' : True, 'rfu2' : 0,
Vadim Yanitskiy87dd0202023-04-22 20:45:29 +070095 '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 ]
Harald Weltece01f482023-12-28 09:41:35 +0100120 _test_no_pad = True
Vadim Yanitskiy87dd0202023-04-22 20:45:29 +0700121
122 class OP_MODE(enum.IntEnum):
123 normal = 0x00
124 type_approval = 0x80
125 normal_and_specific_facilities = 0x01
126 type_approval_and_specific_facilities = 0x81
127 maintenance_off_line = 0x02
128 cell_test = 0x04
129
130 def __init__(self, fid='6f43', sfid=None, name='EF.AD',
131 desc='Service Provider Name', size=(3, None), **kwargs):
132 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
133 self._construct = Struct(
134 # Byte 1: Display Condition
135 'ms_operation_mode'/Enum(Byte, self.OP_MODE),
136 # Bytes 2-3: Additional information
Harald Weltef9e2df12023-07-11 21:03:54 +0200137 'additional_info'/HexAdapter(Bytes(2)),
Vadim Yanitskiy87dd0202023-04-22 20:45:29 +0700138 # Bytes 4..: RFU
Harald Weltef9e2df12023-07-11 21:03:54 +0200139 'rfu'/HexAdapter(GreedyBytesRFU),
Vadim Yanitskiy87dd0202023-04-22 20:45:29 +0700140 )
141
142
143class EF_SMS(LinFixedEF):
144 '''3.4.27 Short Messages'''
145 def __init__(self, fid='6f3c', sfid=None, name='EF.SMS', desc='Short messages', **kwargs):
146 super().__init__(fid, sfid=sfid, name=name, desc=desc, rec_len=(2, 255), **kwargs)
147 self._construct = Struct(
148 # Byte 1: Status
149 'status'/BitStruct(
150 'rfu87'/BitsRFU(2),
151 'protection'/Flag,
152 'rfu54'/BitsRFU(2),
153 'status'/FlagsEnum(BitsInteger(2), read=0, to_be_read=1, sent=2, to_be_sent=3),
154 'used'/Flag,
155 ),
156 # Byte 2: Length
157 'length'/Int8ub,
158 # Bytes 3..: SMS Transport Layer Message
159 'tpdu'/Bytes(lambda ctx: ctx.length if ctx.status.used else 0),
160 )
161
162
163class DF_CDMA(CardDF):
164 def __init__(self):
165 super().__init__(fid='7f25', name='DF.CDMA',
166 desc='CDMA related files (3GPP2 C.S0023-D)')
167 files = [
168 # TODO: lots of other files
169 EF_ServiceTable('6f32', None, 'EF.CST',
170 'CDMA Service Table', table=EF_CST_map, size=(5, 16)),
171 EF_SPN(),
172 EF_AD(),
173 EF_SMS(),
174 ]
175 self.add_files(files)
176
177
178class CardProfileRUIM(CardProfile):
179 '''R-UIM card profile as per 3GPP2 C.S0023-D'''
180
181 ORDER = 2
182
183 def __init__(self):
184 super().__init__('R-UIM', desc='CDMA R-UIM Card', cla="a0",
185 sel_ctrl="0000", files_in_mf=[DF_TELECOM(), DF_GSM(), DF_CDMA()])
186
187 @staticmethod
188 def decode_select_response(resp_hex: str) -> object:
189 # TODO: Response parameters/data in case of DF_CDMA (section 2.6)
190 return CardProfileSIM.decode_select_response(resp_hex)
191
192 @staticmethod
193 def match_with_card(scc: SimCardCommands) -> bool:
194 return match_ruim(scc)
Harald Welte323a3502023-07-11 17:26:39 +0200195
196class AddonRUIM(CardProfileAddon):
197 """An Addon that can be found on on a combined SIM + RUIM or UICC + RUIM to support CDMA."""
198 def __init__(self):
199 files = [
200 DF_CDMA()
201 ]
202 super().__init__('RUIM', desc='CDMA RUIM', files_in_mf=files)
203
204 def probe(self, card: 'CardBase') -> bool:
205 return card.file_exists(self.files_in_mf[0].fid)