blob: 8464197626158cab616412e02adffc577dcfcae5 [file] [log] [blame]
Harald Welte2a33ad22021-10-20 10:14:18 +02001# -*- coding: utf-8 -*-
2
3# without this, pylint will fail when inner classes are used
4# within the 'nested' kwarg of our TlvMeta metaclass on python 3.7 :(
5# pylint: disable=undefined-variable
6
7"""
8The File (and its derived classes) uses the classes of pySim.filesystem in
9order to describe the files specified in UIC Reference P38 T 9001 5.0 "FFFIS for GSM-R SIM Cards"
10"""
11
12#
13# Copyright (C) 2021 Harald Welte <laforge@osmocom.org>
14#
15# This program is free software: you can redistribute it and/or modify
16# it under the terms of the GNU General Public License as published by
17# the Free Software Foundation, either version 2 of the License, or
18# (at your option) any later version.
19#
20# This program is distributed in the hope that it will be useful,
21# but WITHOUT ANY WARRANTY; without even the implied warranty of
22# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23# GNU General Public License for more details.
24#
25# You should have received a copy of the GNU General Public License
26# along with this program. If not, see <http://www.gnu.org/licenses/>.
27#
28
29
30from pySim.utils import *
31#from pySim.tlv import *
32from struct import pack, unpack
33from construct import *
34from construct import Optional as COptional
35from pySim.construct import *
36import enum
37
38from pySim.filesystem import *
39import pySim.ts_102_221
40import pySim.ts_51_011
41
42######################################################################
43# DF.EIRENE (FFFIS for GSM-R SIM Cards)
44######################################################################
45
Harald Weltec91085e2022-02-10 18:05:45 +010046
Harald Welte2a33ad22021-10-20 10:14:18 +020047class FuncNTypeAdapter(Adapter):
48 def _decode(self, obj, context, path):
49 bcd = swap_nibbles(b2h(obj))
50 last_digit = bcd[-1]
51 return {'functional_number': bcd[:-1],
52 'presentation_of_only_this_fn': last_digit & 4,
Harald Weltec91085e2022-02-10 18:05:45 +010053 'permanent_fn': last_digit & 8}
54
Harald Welte2a33ad22021-10-20 10:14:18 +020055 def _encode(self, obj, context, path):
56 return 'FIXME'
57
Harald Weltec91085e2022-02-10 18:05:45 +010058
Harald Welte2a33ad22021-10-20 10:14:18 +020059class EF_FN(LinFixedEF):
60 """Section 7.2"""
Harald Weltec91085e2022-02-10 18:05:45 +010061
Harald Welte2a33ad22021-10-20 10:14:18 +020062 def __init__(self):
Harald Weltec91085e2022-02-10 18:05:45 +010063 super().__init__(fid='6ff1', sfid=None, name='EF.EN',
Harald Welte99e4cc02022-07-21 15:25:47 +020064 desc='Functional numbers', rec_len=(9, 9))
Harald Welte2a33ad22021-10-20 10:14:18 +020065 self._construct = Struct('functional_number_and_type'/FuncNTypeAdapter(Bytes(8)),
66 'list_number'/Int8ub)
67
68
69class PlConfAdapter(Adapter):
70 """Section 7.4.3"""
Harald Weltec91085e2022-02-10 18:05:45 +010071
Harald Welte2a33ad22021-10-20 10:14:18 +020072 def _decode(self, obj, context, path):
73 num = int(obj) & 0x7
74 if num == 0:
75 return 'None'
76 elif num == 1:
77 return 4
78 elif num == 2:
79 return 3
80 elif num == 3:
81 return 2
82 elif num == 4:
83 return 1
84 elif num == 5:
85 return 0
Harald Weltec91085e2022-02-10 18:05:45 +010086
Harald Welte2a33ad22021-10-20 10:14:18 +020087 def _encode(self, obj, context, path):
88 if obj == 'None':
89 return 0
90 obj = int(obj)
91 if obj == 4:
92 return 1
93 elif obj == 3:
94 return 2
95 elif obj == 2:
96 return 3
97 elif obj == 1:
98 return 4
99 elif obj == 0:
100 return 5
101
Harald Weltec91085e2022-02-10 18:05:45 +0100102
Harald Welte2a33ad22021-10-20 10:14:18 +0200103class PlCallAdapter(Adapter):
104 """Section 7.4.12"""
Harald Weltec91085e2022-02-10 18:05:45 +0100105
Harald Welte2a33ad22021-10-20 10:14:18 +0200106 def _decode(self, obj, context, path):
107 num = int(obj) & 0x7
108 if num == 0:
109 return 'None'
110 elif num == 1:
111 return 4
112 elif num == 2:
113 return 3
114 elif num == 3:
115 return 2
116 elif num == 4:
117 return 1
118 elif num == 5:
119 return 0
120 elif num == 6:
121 return 'B'
122 elif num == 7:
123 return 'A'
Harald Weltec91085e2022-02-10 18:05:45 +0100124
Harald Welte2a33ad22021-10-20 10:14:18 +0200125 def _encode(self, obj, context, path):
126 if obj == 'None':
127 return 0
128 if obj == 4:
129 return 1
130 elif obj == 3:
131 return 2
132 elif obj == 2:
133 return 3
134 elif obj == 1:
135 return 4
136 elif obj == 0:
137 return 5
138 elif obj == 'B':
139 return 6
140 elif obj == 'A':
141 return 7
142
Harald Weltec91085e2022-02-10 18:05:45 +0100143
144NextTableType = Enum(Byte, decision=0xf0, predefined=0xf1,
145 num_dial_digits=0xf2, ic=0xf3, empty=0xff)
146
Harald Welte2a33ad22021-10-20 10:14:18 +0200147
148class EF_CallconfC(TransparentEF):
149 """Section 7.3"""
Harald Weltec91085e2022-02-10 18:05:45 +0100150
Harald Welte2a33ad22021-10-20 10:14:18 +0200151 def __init__(self):
Harald Welte13edf302022-07-21 15:19:23 +0200152 super().__init__(fid='6ff2', sfid=None, name='EF.CallconfC', size=(24, 24),
Harald Welte2a33ad22021-10-20 10:14:18 +0200153 desc='Call Configuration of emergency calls Configuration')
154 self._construct = Struct('pl_conf'/PlConfAdapter(Int8ub),
155 'conf_nr'/BcdAdapter(Bytes(8)),
156 'max_rand'/Int8ub,
157 'n_ack_max'/Int16ub,
158 'pl_ack'/PlCallAdapter(Int8ub),
159 'n_nested_max'/Int8ub,
160 'train_emergency_gid'/Int8ub,
161 'shunting_emergency_gid'/Int8ub,
162 'imei'/BcdAdapter(Bytes(8)))
163
Harald Weltec91085e2022-02-10 18:05:45 +0100164
Harald Welte2a33ad22021-10-20 10:14:18 +0200165class EF_CallconfI(LinFixedEF):
166 """Section 7.5"""
Harald Weltec91085e2022-02-10 18:05:45 +0100167
Harald Welte2a33ad22021-10-20 10:14:18 +0200168 def __init__(self):
Harald Welte99e4cc02022-07-21 15:25:47 +0200169 super().__init__(fid='6ff3', sfid=None, name='EF.CallconfI', rec_len=(21, 21),
Harald Welte2a33ad22021-10-20 10:14:18 +0200170 desc='Call Configuration of emergency calls Information')
171 self._construct = Struct('t_dur'/Int24ub,
172 't_relcalc'/Int32ub,
173 'pl_call'/PlCallAdapter(Int8ub),
Harald Weltec91085e2022-02-10 18:05:45 +0100174 'cause' /
175 FlagsEnum(Int8ub, powered_off=1,
176 radio_link_error=2, user_command=5),
Harald Welte2a33ad22021-10-20 10:14:18 +0200177 'gcr'/BcdAdapter(Bytes(4)),
178 'fnr'/BcdAdapter(Bytes(8)))
179
Harald Weltec91085e2022-02-10 18:05:45 +0100180
Harald Welte2a33ad22021-10-20 10:14:18 +0200181class EF_Shunting(TransparentEF):
182 """Section 7.6"""
Harald Weltec91085e2022-02-10 18:05:45 +0100183
Harald Welte2a33ad22021-10-20 10:14:18 +0200184 def __init__(self):
Harald Weltec91085e2022-02-10 18:05:45 +0100185 super().__init__(fid='6ff4', sfid=None,
Harald Welte13edf302022-07-21 15:19:23 +0200186 name='EF.Shunting', desc='Shunting', size=(8, 8))
Harald Welte2a33ad22021-10-20 10:14:18 +0200187 self._construct = Struct('common_gid'/Int8ub,
Harald Welte3c98d5e2022-07-20 07:40:05 +0200188 'shunting_gid'/HexAdapter(Bytes(7)))
Harald Welte2a33ad22021-10-20 10:14:18 +0200189
Harald Weltec91085e2022-02-10 18:05:45 +0100190
Harald Welte2a33ad22021-10-20 10:14:18 +0200191class EF_GsmrPLMN(LinFixedEF):
192 """Section 7.7"""
Harald Weltec91085e2022-02-10 18:05:45 +0100193
Harald Welte2a33ad22021-10-20 10:14:18 +0200194 def __init__(self):
Harald Weltec91085e2022-02-10 18:05:45 +0100195 super().__init__(fid='6ff5', sfid=None, name='EF.GsmrPLMN',
Harald Welte99e4cc02022-07-21 15:25:47 +0200196 desc='GSM-R network selection', rec_len=(9, 9))
Harald Welte2a33ad22021-10-20 10:14:18 +0200197 self._construct = Struct('plmn'/BcdAdapter(Bytes(3)),
198 'class_of_network'/BitStruct('supported'/FlagsEnum(BitsInteger(5), vbs=1, vgcs=2, emlpp=4, fn=8, eirene=16),
199 'preference'/BitsInteger(3)),
200 'ic_incoming_ref_tbl'/HexAdapter(Bytes(2)),
201 'outgoing_ref_tbl'/HexAdapter(Bytes(2)),
202 'ic_table_ref'/HexAdapter(Bytes(1)))
203
Harald Weltec91085e2022-02-10 18:05:45 +0100204
Harald Welte2a33ad22021-10-20 10:14:18 +0200205class EF_IC(LinFixedEF):
206 """Section 7.8"""
Harald Weltec91085e2022-02-10 18:05:45 +0100207
Harald Welte2a33ad22021-10-20 10:14:18 +0200208 def __init__(self):
Harald Weltec91085e2022-02-10 18:05:45 +0100209 super().__init__(fid='6f8d', sfid=None, name='EF.IC',
Harald Welte99e4cc02022-07-21 15:25:47 +0200210 desc='International Code', rec_len=(7, 7))
Harald Welte2a33ad22021-10-20 10:14:18 +0200211 self._construct = Struct('next_table_type'/NextTableType,
212 'id_of_next_table'/HexAdapter(Bytes(2)),
213 'ic_decision_value'/BcdAdapter(Bytes(2)),
214 'network_string_table_index'/Int8ub)
215
Harald Weltec91085e2022-02-10 18:05:45 +0100216
Harald Welte2a33ad22021-10-20 10:14:18 +0200217class EF_NW(LinFixedEF):
218 """Section 7.9"""
Harald Weltec91085e2022-02-10 18:05:45 +0100219
Harald Welte2a33ad22021-10-20 10:14:18 +0200220 def __init__(self):
Harald Weltec91085e2022-02-10 18:05:45 +0100221 super().__init__(fid='6f80', sfid=None, name='EF.NW',
Harald Welte99e4cc02022-07-21 15:25:47 +0200222 desc='Network Name', rec_len=(8, 8))
Harald Welte2a33ad22021-10-20 10:14:18 +0200223 self._construct = GsmString(8)
224
Harald Weltec91085e2022-02-10 18:05:45 +0100225
Harald Welte2a33ad22021-10-20 10:14:18 +0200226class EF_Switching(LinFixedEF):
227 """Section 8.4"""
Harald Weltec91085e2022-02-10 18:05:45 +0100228
Harald Welte2a33ad22021-10-20 10:14:18 +0200229 def __init__(self, fid, name, desc):
Harald Weltec91085e2022-02-10 18:05:45 +0100230 super().__init__(fid=fid, sfid=None,
Harald Welte99e4cc02022-07-21 15:25:47 +0200231 name=name, desc=desc, rec_len=(6, 6))
Harald Welte2a33ad22021-10-20 10:14:18 +0200232 self._construct = Struct('next_table_type'/NextTableType,
233 'id_of_next_table'/HexAdapter(Bytes(2)),
234 'decision_value'/BcdAdapter(Bytes(2)),
235 'string_table_index'/Int8ub)
236
Harald Weltec91085e2022-02-10 18:05:45 +0100237
Harald Welte2a33ad22021-10-20 10:14:18 +0200238class EF_Predefined(LinFixedEF):
239 """Section 8.5"""
Harald Weltec91085e2022-02-10 18:05:45 +0100240
Harald Welte2a33ad22021-10-20 10:14:18 +0200241 def __init__(self, fid, name, desc):
Harald Weltec91085e2022-02-10 18:05:45 +0100242 super().__init__(fid=fid, sfid=None,
Harald Welte99e4cc02022-07-21 15:25:47 +0200243 name=name, desc=desc, rec_len=(3, 3))
Harald Welte2a33ad22021-10-20 10:14:18 +0200244 # header and other records have different structure. WTF !?!
245 self._construct = Struct('next_table_type'/NextTableType,
246 'id_of_next_table'/HexAdapter(Bytes(2)),
247 'predefined_value1'/HexAdapter(Bytes(2)),
248 'string_table_index1'/Int8ub)
249 # TODO: predefined value n, ...
250
Harald Weltec91085e2022-02-10 18:05:45 +0100251
Harald Welte2a33ad22021-10-20 10:14:18 +0200252class EF_DialledVals(TransparentEF):
253 """Section 8.6"""
Harald Weltec91085e2022-02-10 18:05:45 +0100254
Harald Welte2a33ad22021-10-20 10:14:18 +0200255 def __init__(self, fid, name, desc):
Harald Welte13edf302022-07-21 15:19:23 +0200256 super().__init__(fid=fid, sfid=None, name=name, desc=desc, size=(4, 4))
Harald Welte2a33ad22021-10-20 10:14:18 +0200257 self._construct = Struct('next_table_type'/NextTableType,
258 'id_of_next_table'/HexAdapter(Bytes(2)),
259 'dialed_digits'/BcdAdapter(Bytes(1)))
260
261
262class DF_EIRENE(CardDF):
263 def __init__(self, fid='7fe0', name='DF.EIRENE', desc='GSM-R EIRENE'):
264 super().__init__(fid=fid, name=name, desc=desc)
265 files = [
266 # Section 7.1.6 / Table 10 EIRENE GSM EFs
267 EF_FN(),
268 EF_CallconfC(),
269 EF_CallconfI(),
270 EF_Shunting(),
271 EF_GsmrPLMN(),
272 EF_IC(),
273 EF_NW(),
274
275 # support of the numbering plan
276 EF_Switching(fid='6f8e', name='EF.CT', desc='Call Type'),
277 EF_Switching(fid='6f8f', name='EF.SC', desc='Short Code'),
278 EF_Predefined(fid='6f88', name='EF.FC', desc='Function Code'),
Harald Weltec91085e2022-02-10 18:05:45 +0100279 EF_Predefined(fid='6f89', name='EF.Service',
280 desc='VGCS/VBS Service Code'),
281 EF_Predefined(fid='6f8a', name='EF.Call',
282 desc='First digit of the group ID'),
283 EF_Predefined(fid='6f8b', name='EF.FctTeam',
284 desc='Call Type 6 Team Type + Team member function'),
285 EF_Predefined(fid='6f92', name='EF.Controller',
286 desc='Call Type 7 Controller function code'),
287 EF_Predefined(fid='6f8c', name='EF.Gateway',
288 desc='Access to external networks'),
289 EF_DialledVals(fid='6f81', name='EF.5to8digits',
290 desc='Call Type 2 User Identity Number length'),
291 EF_DialledVals(fid='6f82', name='EF.2digits',
292 desc='2 digits input'),
293 EF_DialledVals(fid='6f83', name='EF.8digits',
294 desc='8 digits input'),
295 EF_DialledVals(fid='6f84', name='EF.9digits',
296 desc='9 digits input'),
297 EF_DialledVals(fid='6f85', name='EF.SSSSS',
298 desc='Group call area input'),
299 EF_DialledVals(fid='6f86', name='EF.LLLLL',
300 desc='Location number Call Type 6'),
301 EF_DialledVals(fid='6f91', name='EF.Location',
302 desc='Location number Call Type 7'),
303 EF_DialledVals(fid='6f87', name='EF.FreeNumber',
304 desc='Free Number Call Type 0 and 8'),
305 ]
Harald Welte2a33ad22021-10-20 10:14:18 +0200306 self.add_files(files)