blob: b5faf0835b11ae40477abb23015f9b75e22fa51e [file] [log] [blame]
Supreeth Herle475dcaa2020-03-20 18:57:39 +01001# -*- coding: utf-8 -*-
2
Harald Weltef12979d2021-05-29 21:47:13 +02003# 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
Supreeth Herle475dcaa2020-03-20 18:57:39 +01007"""
Harald Weltefc67de22023-05-23 20:29:49 +02008Various constants from 3GPP TS 31.102 V17.9.0
Supreeth Herle475dcaa2020-03-20 18:57:39 +01009"""
10
11#
12# Copyright (C) 2020 Supreeth Herle <herlesupreeth@gmail.com>
Harald Weltefc67de22023-05-23 20:29:49 +020013# Copyright (C) 2021-2023 Harald Welte <laforge@osmocom.org>
Supreeth Herle475dcaa2020-03-20 18:57:39 +010014#
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# Mapping between USIM Service Number and its description
Harald Weltec91085e2022-02-10 18:05:45 +010030import pySim.ts_102_221
31from pySim.ts_51_011 import EF_ACMmax, EF_AAeM, EF_eMLPP, EF_CMI, EF_PNN
32from pySim.ts_51_011 import EF_MMSN, EF_MMSICP, EF_MMSUP, EF_MMSUCP, EF_VGCS, EF_VGCSS, EF_NIA
33from pySim.ts_51_011 import EF_SMSR, EF_DCK, EF_EXT, EF_CNL, EF_OPL, EF_MBI, EF_MWIS
Harald Welte53762512023-12-21 20:16:17 +010034from pySim.ts_51_011 import EF_CBMID, EF_CBMIR, EF_ADN, EF_CFIS, EF_SMS, EF_MSISDN, EF_SMSP, EF_SMSS
Harald Weltec91085e2022-02-10 18:05:45 +010035from pySim.ts_51_011 import EF_IMSI, EF_xPLMNwAcT, EF_SPN, EF_CBMI, EF_ACC, EF_PLMNsel
Harald Welted90ceb82022-07-17 22:10:58 +020036from pySim.ts_51_011 import EF_Kc, EF_CPBCCH, EF_InvScan
Harald Weltec91085e2022-02-10 18:05:45 +010037from pySim.ts_102_221 import EF_ARR
38from pySim.tlv import *
39from pySim.filesystem import *
Harald Welte6f8a8702022-07-17 21:50:31 +020040from pySim.ts_31_102_telecom import DF_PHONEBOOK, EF_UServiceTable
Harald Weltec91085e2022-02-10 18:05:45 +010041from pySim.construct import *
Harald Weltef56b6b22022-07-30 16:36:06 +020042from pySim.cat import SMS_TPDU, DeviceIdentities, SMSPPDownload
Harald Weltec91085e2022-02-10 18:05:45 +010043from construct import Optional as COptional
44from construct import *
45from typing import Tuple
46from struct import unpack, pack
47import enum
Supreeth Herle475dcaa2020-03-20 18:57:39 +010048EF_UST_map = {
Harald Weltec91085e2022-02-10 18:05:45 +010049 1: 'Local Phone Book',
50 2: 'Fixed Dialling Numbers (FDN)',
51 3: 'Extension 2',
52 4: 'Service Dialling Numbers (SDN)',
53 5: 'Extension3',
54 6: 'Barred Dialling Numbers (BDN)',
55 7: 'Extension4',
56 8: 'Outgoing Call Information (OCI and OCT)',
57 9: 'Incoming Call Information (ICI and ICT)',
58 10: 'Short Message Storage (SMS)',
59 11: 'Short Message Status Reports (SMSR)',
60 12: 'Short Message Service Parameters (SMSP)',
61 13: 'Advice of Charge (AoC)',
62 14: 'Capability Configuration Parameters 2 (CCP2)',
63 15: 'Cell Broadcast Message Identifier',
64 16: 'Cell Broadcast Message Identifier Ranges',
65 17: 'Group Identifier Level 1',
66 18: 'Group Identifier Level 2',
67 19: 'Service Provider Name',
68 20: 'User controlled PLMN selector with Access Technology',
69 21: 'MSISDN',
70 22: 'Image (IMG)',
71 23: 'Support of Localised Service Areas (SoLSA)',
72 24: 'Enhanced Multi-Level Precedence and Pre-emption Service',
73 25: 'Automatic Answer for eMLPP',
74 26: 'RFU',
75 27: 'GSM Access',
76 28: 'Data download via SMS-PP',
77 29: 'Data download via SMS-CB',
78 30: 'Call Control by USIM',
79 31: 'MO-SMS Control by USIM',
80 32: 'RUN AT COMMAND command',
81 33: 'shall be set to 1',
82 34: 'Enabled Services Table',
83 35: 'APN Control List (ACL)',
84 36: 'Depersonalisation Control Keys',
85 37: 'Co-operative Network List',
86 38: 'GSM security context',
87 39: 'CPBCCH Information',
88 40: 'Investigation Scan',
89 41: 'MexE',
90 42: 'Operator controlled PLMN selector with Access Technology',
91 43: 'HPLMN selector with Access Technology',
92 44: 'Extension 5',
93 45: 'PLMN Network Name',
94 46: 'Operator PLMN List',
95 47: 'Mailbox Dialling Numbers',
96 48: 'Message Waiting Indication Status',
97 49: 'Call Forwarding Indication Status',
98 50: 'Reserved and shall be ignored',
99 51: 'Service Provider Display Information',
100 52: 'Multimedia Messaging Service (MMS)',
101 53: 'Extension 8',
102 54: 'Call control on GPRS by USIM',
103 55: 'MMS User Connectivity Parameters',
104 56: 'Network\'s indication of alerting in the MS (NIA)',
105 57: 'VGCS Group Identifier List (EFVGCS and EFVGCSS)',
106 58: 'VBS Group Identifier List (EFVBS and EFVBSS)',
107 59: 'Pseudonym',
108 60: 'User Controlled PLMN selector for I-WLAN access',
109 61: 'Operator Controlled PLMN selector for I-WLAN access',
110 62: 'User controlled WSID list',
111 63: 'Operator controlled WSID list',
112 64: 'VGCS security',
113 65: 'VBS security',
114 66: 'WLAN Reauthentication Identity',
115 67: 'Multimedia Messages Storage',
116 68: 'Generic Bootstrapping Architecture (GBA)',
117 69: 'MBMS security',
118 70: 'Data download via USSD and USSD application mode',
119 71: 'Equivalent HPLMN',
120 72: 'Additional TERMINAL PROFILE after UICC activation',
121 73: 'Equivalent HPLMN Presentation Indication',
122 74: 'Last RPLMN Selection Indication',
123 75: 'OMA BCAST Smart Card Profile',
124 76: 'GBA-based Local Key Establishment Mechanism',
125 77: 'Terminal Applications',
126 78: 'Service Provider Name Icon',
127 79: 'PLMN Network Name Icon',
128 80: 'Connectivity Parameters for USIM IP connections',
129 81: 'Home I-WLAN Specific Identifier List',
130 82: 'I-WLAN Equivalent HPLMN Presentation Indication',
131 83: 'I-WLAN HPLMN Priority Indication',
132 84: 'I-WLAN Last Registered PLMN',
133 85: 'EPS Mobility Management Information',
134 86: 'Allowed CSG Lists and corresponding indications',
135 87: 'Call control on EPS PDN connection by USIM',
136 88: 'HPLMN Direct Access',
137 89: 'eCall Data',
138 90: 'Operator CSG Lists and corresponding indications',
139 91: 'Support for SM-over-IP',
140 92: 'Support of CSG Display Control',
141 93: 'Communication Control for IMS by USIM',
142 94: 'Extended Terminal Applications',
143 95: 'Support of UICC access to IMS',
144 96: 'Non-Access Stratum configuration by USIM',
145 97: 'PWS configuration by USIM',
146 98: 'RFU',
147 99: 'URI support by UICC',
148 100: 'Extended EARFCN support',
149 101: 'ProSe',
150 102: 'USAT Application Pairing',
151 103: 'Media Type support',
152 104: 'IMS call disconnection cause',
153 105: 'URI support for MO SHORT MESSAGE CONTROL',
154 106: 'ePDG configuration Information support',
155 107: 'ePDG configuration Information configured',
156 108: 'ACDC support',
157 109: 'MCPTT',
158 110: 'ePDG configuration Information for Emergency Service support',
159 111: 'ePDG configuration Information for Emergency Service configured',
160 112: 'eCall Data over IMS',
161 113: 'URI support for SMS-PP DOWNLOAD as defined in 3GPP TS 31.111 [12]',
162 114: 'From Preferred',
163 115: 'IMS configuration data',
164 116: 'TV configuration',
165 117: '3GPP PS Data Off',
166 118: '3GPP PS Data Off Service List',
167 119: 'V2X',
168 120: 'XCAP Configuration Data',
169 121: 'EARFCN list for MTC/NB-IOT UEs',
170 122: '5GS Mobility Management Information',
171 123: '5G Security Parameters',
172 124: 'Subscription identifier privacy support',
173 125: 'SUCI calculation by the USIM',
174 126: 'UAC Access Identities support',
175 127: 'Expect control plane-based Steering of Roaming information during initial registration in VPLMN',
176 128: 'Call control on PDU Session by USIM',
177 129: '5GS Operator PLMN List',
178 130: 'Support for SUPI of type NSI or GLI or GCI',
179 131: '3GPP PS Data Off separate Home and Roaming lists',
180 132: 'Support for URSP by USIM',
181 133: '5G Security Parameters extended',
182 134: 'MuD and MiD configuration data',
Harald Weltefc67de22023-05-23 20:29:49 +0200183 135: 'Support for Trusted non-3GPP access networks by USIM',
184 136: 'Support for multiple records of NAS security context storage for multiple registration',
185 137: 'Pre-configured CAG information list',
186 138: 'SOR-CMCI storage in USIM',
187 139: '5G ProSe',
188 140: 'Storage of disaster roaming information in USIM',
189 141: 'Pre-configured eDRX parameters',
190 142: '5G NSWO support',
191 143: 'PWS configuration for SNPN in USIM',
192 144: 'Multiplier Coefficient for Higher Priority PLMN search via NG-RAN satellite access',
193 145: 'K_AUSF derivation configuration',
194 146: 'Network Identifier for SNPN (NID)',
195}
196
197EF_5G_PROSE_ST_map = {
198 1: '5G ProSe configuration data for direct discovery',
199 2: '5G ProSe configuration data for direct communication',
200 3: '5G ProSe configuration data for UE-to-network relay UE',
201 4: '5G ProSe configuration data for remote UE',
202 5: '5G ProSe configuration data for usage information reporting',
Sebastian Viviani0dc8f692020-05-29 00:14:55 +0100203}
204
Harald Weltee8947492022-02-10 10:33:20 +0100205# Mapping between USIM Enbled Service Number and its description
206EF_EST_map = {
207 1: 'Fixed Dialling Numbers (FDN)',
208 2: 'Barred Dialling Numbers (BDN)',
209 3: 'APN Control List (ACL)'
210}
211
Harald Welte21caf322022-07-16 14:06:46 +0200212# 3gPP TS 31.102 Section 7.5.2.1
213class SUCI_TlvDataObject(BER_TLV_IE, tag=0xA1):
214 _construct = HexAdapter(GreedyBytes)
215
Harald Welteb2edd142021-01-08 23:29:35 +0100216######################################################################
217# ADF.USIM
218######################################################################
219
Harald Welteb2edd142021-01-08 23:29:35 +0100220
Harald Weltef12979d2021-05-29 21:47:13 +0200221# 3GPP TS 31.102 Section 4.4.11.4 (EF_5GS3GPPNSC)
222class EF_5GS3GPPNSC(LinFixedEF):
223 class NgKSI(BER_TLV_IE, tag=0x80):
224 _construct = Int8ub
225
226 class K_AMF(BER_TLV_IE, tag=0x81):
227 _construct = HexAdapter(Bytes(32))
228
229 class UplinkNASCount(BER_TLV_IE, tag=0x82):
230 _construct = Int32ub
231
232 class DownlinkNASCount(BER_TLV_IE, tag=0x83):
233 _construct = Int32ub
234
235 class IdsOfSelectedNasAlgos(BER_TLV_IE, tag=0x84):
236 # 3GPP TS 24.501 Section 9.11.3.34
237 _construct = BitStruct('ciphering'/Nibble, 'integrity'/Nibble)
238
239 class IdsOfSelectedEpsAlgos(BER_TLV_IE, tag=0x85):
240 # 3GPP TS 24.301 Section 9.9.3.23
241 _construct = BitStruct('ciphering'/Nibble, 'integrity'/Nibble)
242
243 class FiveGSNasSecurityContext(BER_TLV_IE, tag=0xA0,
Harald Weltec91085e2022-02-10 18:05:45 +0100244 nested=[NgKSI, K_AMF, UplinkNASCount,
245 DownlinkNASCount, IdsOfSelectedNasAlgos,
246 IdsOfSelectedEpsAlgos]):
Harald Weltef12979d2021-05-29 21:47:13 +0200247 pass
248
Harald Welte99e4cc02022-07-21 15:25:47 +0200249 def __init__(self, fid="4f03", sfid=0x03, name='EF.5GS3GPPNSC', rec_len=(57, None),
Harald Welte419bb492022-02-12 21:39:35 +0100250 desc='5GS 3GPP Access NAS Security Context', **kwargs):
251 super().__init__(fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len, **kwargs)
Harald Welte65516272022-02-10 17:51:05 +0100252 self._tlv = EF_5GS3GPPNSC.FiveGSNasSecurityContext
Harald Weltef12979d2021-05-29 21:47:13 +0200253
254# 3GPP TS 31.102 Section 4.4.11.6
255class EF_5GAUTHKEYS(TransparentEF):
256 class K_AUSF(BER_TLV_IE, tag=0x80):
257 _construct = HexAdapter(GreedyBytes)
258
259 class K_SEAF(BER_TLV_IE, tag=0x81):
260 _construct = HexAdapter(GreedyBytes)
261
262 class FiveGAuthKeys(TLV_IE_Collection, nested=[K_AUSF, K_SEAF]):
263 pass
264
Harald Welte13edf302022-07-21 15:19:23 +0200265 def __init__(self, fid='4f05', sfid=0x05, name='EF.5GAUTHKEYS', size=(68, None),
Harald Welte419bb492022-02-12 21:39:35 +0100266 desc='5G authentication keys', **kwargs):
267 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Welte65516272022-02-10 17:51:05 +0100268 self._tlv = EF_5GAUTHKEYS.FiveGAuthKeys
Harald Weltef12979d2021-05-29 21:47:13 +0200269
270# 3GPP TS 31.102 Section 4.4.11.8
271class ProtSchemeIdList(BER_TLV_IE, tag=0xa0):
272 # FIXME: 3GPP TS 24.501 Protection Scheme Identifier
273 # repeated sequence of (id, index) tuples
Harald Weltec91085e2022-02-10 18:05:45 +0100274 _construct = GreedyRange(
275 Struct('id'/Enum(Byte, null=0, A=1, B=2), 'index'/Int8ub))
276
Harald Weltef12979d2021-05-29 21:47:13 +0200277
278class HomeNetPubKeyId(BER_TLV_IE, tag=0x80):
279 # 3GPP TS 24.501 / 3GPP TS 23.003
280 _construct = Int8ub
281
Harald Weltec91085e2022-02-10 18:05:45 +0100282
Harald Weltef12979d2021-05-29 21:47:13 +0200283class HomeNetPubKey(BER_TLV_IE, tag=0x81):
284 # FIXME: RFC 5480
285 _construct = HexAdapter(GreedyBytes)
286
Harald Weltec91085e2022-02-10 18:05:45 +0100287
Harald Weltef12979d2021-05-29 21:47:13 +0200288class HomeNetPubKeyList(BER_TLV_IE, tag=0xa1,
Harald Weltec91085e2022-02-10 18:05:45 +0100289 nested=[HomeNetPubKeyId, HomeNetPubKey]):
Harald Weltef12979d2021-05-29 21:47:13 +0200290 pass
291
292# 3GPP TS 31.102 Section 4.4.11.6
Harald Weltec91085e2022-02-10 18:05:45 +0100293class SUCI_CalcInfo(TLV_IE_Collection, nested=[ProtSchemeIdList, HomeNetPubKeyList]):
Harald Weltef12979d2021-05-29 21:47:13 +0200294 pass
295
296
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200297# TS 31.102 4.4.11.8
298class EF_SUCI_Calc_Info(TransparentEF):
Harald Welte324175f2023-12-21 20:25:30 +0100299 _test_de_encode = [
300 ( 'A00401010000A14A80010A81204E858C4D49D1343E6181284C47CA721730C98742CB7C6182D2E8126E08088D3680010B8120D1BC365F4997D17CE4374E72181431CBFEBA9E1B98D7618F79D48561B144672A',
301 {"prot_scheme_id_list": [{"priority": 0, "identifier": 1, "key_index": 1}, {"priority": 1,
302 "identifier": 0,
303 "key_index": 0}],
304 "hnet_pubkey_list": [{"hnet_pubkey_identifier": 10, "hnet_pubkey":
305 "4e858c4d49d1343e6181284c47ca721730c98742cb7c6182d2e8126e08088d36"},
306 {"hnet_pubkey_identifier": 11, "hnet_pubkey":
307 "d1bc365f4997d17ce4374e72181431cbfeba9e1b98d7618f79d48561b144672a"}]} ),
308 ]
Harald Welte13edf302022-07-21 15:19:23 +0200309 def __init__(self, fid="4f07", sfid=0x07, name='EF.SUCI_Calc_Info', size=(2, None),
Harald Welte419bb492022-02-12 21:39:35 +0100310 desc='SUCI Calc Info', **kwargs):
311 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200312
313 def _encode_prot_scheme_id_list(self, in_list):
314 out_bytes = [0xa0]
Harald Weltec91085e2022-02-10 18:05:45 +0100315 out_bytes.append(len(in_list)*2) # two byte per entry
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200316
317 # position in list determines priority; high-priority items (low index) come first
318 for scheme in sorted(in_list, key=lambda item: item["priority"]):
319 out_bytes.append(scheme["identifier"])
320 out_bytes.append(scheme["key_index"])
321
322 return out_bytes
323
324 def _encode_hnet_pubkey_list(self, hnet_pubkey_list):
Harald Weltec91085e2022-02-10 18:05:45 +0100325 out_bytes = [0xa1] # pubkey list tag
326 out_bytes.append(0x00) # length filled later
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200327 length = 0
328
329 for key in hnet_pubkey_list:
Harald Weltec91085e2022-02-10 18:05:45 +0100330 out_bytes.append(0x80) # identifier tag
331 out_bytes.append(0x01) # TODO size, fixed to 1 byte
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200332 out_bytes.append(key["hnet_pubkey_identifier"])
Harald Weltec91085e2022-02-10 18:05:45 +0100333 out_bytes.append(0x81) # key tag
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200334 out_bytes.append(len(key["hnet_pubkey"])//2)
335 length += 5+len(key["hnet_pubkey"])//2
336
337 pubkey_bytes = h2b(key["hnet_pubkey"])
338 out_bytes += pubkey_bytes
339
340 # fill length
341 out_bytes[1] = length
342 return out_bytes
343
344 def _encode_hex(self, in_json):
Harald Weltec91085e2022-02-10 18:05:45 +0100345 out_bytes = self._encode_prot_scheme_id_list(
346 in_json['prot_scheme_id_list'])
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200347 out_bytes += self._encode_hnet_pubkey_list(in_json['hnet_pubkey_list'])
348 return "".join(["%02X" % i for i in out_bytes])
349
350 def _decode_prot_scheme_id_list(self, in_bytes):
351 prot_scheme_id_list = []
352 pos = 0
353 # two bytes per entry
354 while pos < len(in_bytes):
355 prot_scheme = {
Harald Weltec91085e2022-02-10 18:05:45 +0100356 'priority': pos//2, # first in list: high priority
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200357 'identifier': in_bytes[pos],
358 'key_index': in_bytes[pos+1]
359 }
360 pos += 2
361 prot_scheme_id_list.append(prot_scheme)
362 return prot_scheme_id_list
363
364 def _decode_hnet_pubkey_list(self, in_bytes):
365 hnet_pubkey_list = []
366 pos = 0
367 if in_bytes[pos] != 0xa1:
368 print("missing Home Network Public Key List data object")
369 return {}
370 pos += 1
371 hnet_pubkey_list_len = in_bytes[pos]
372 pos += 1
373
374 while pos < hnet_pubkey_list_len:
375 if in_bytes[pos] != 0x80:
376 print("missing Home Network Public Key Identifier tag")
377 return {}
378 pos += 1
Harald Weltec91085e2022-02-10 18:05:45 +0100379 # TODO might be more than 1 byte?
380 hnet_pubkey_id_len = in_bytes[pos]
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200381 pos += 1
382 hnet_pubkey_id = in_bytes[pos:pos+hnet_pubkey_id_len][0]
383 pos += hnet_pubkey_id_len
384 if in_bytes[pos] != 0x81:
385 print("missing Home Network Public Key tag")
386 return {}
387 pos += 1
388 hnet_pubkey_len = in_bytes[pos]
389 pos += 1
390 hnet_pubkey = in_bytes[pos:pos+hnet_pubkey_len]
391 pos += hnet_pubkey_len
392
393 hnet_pubkey_list.append({
394 'hnet_pubkey_identifier': hnet_pubkey_id,
395 'hnet_pubkey': b2h(hnet_pubkey)
396 })
397
398 return hnet_pubkey_list
399
400 def _decode_bin(self, in_bin):
Vadim Yanitskiy5e41eeb2021-05-02 02:20:33 +0200401 return self._decode_hex(b2h(in_bin))
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200402
403 def _decode_hex(self, in_hex):
404 in_bytes = h2b(in_hex)
405 pos = 0
406
407 if in_bytes[pos] != 0xa0:
408 print("missing Protection Scheme Identifier List data object tag")
409 return {}
410 pos += 1
411
Harald Weltec91085e2022-02-10 18:05:45 +0100412 prot_scheme_id_list_len = in_bytes[pos] # TODO maybe more than 1 byte
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200413 pos += 1
414 # decode Protection Scheme Identifier List data object
Harald Weltec91085e2022-02-10 18:05:45 +0100415 prot_scheme_id_list = self._decode_prot_scheme_id_list(
416 in_bytes[pos:pos+prot_scheme_id_list_len])
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200417 pos += prot_scheme_id_list_len
418
419 # remaining data holds Home Network Public Key Data Object
420 hnet_pubkey_list = self._decode_hnet_pubkey_list(in_bytes[pos:])
421
422 return {
423 'prot_scheme_id_list': prot_scheme_id_list,
424 'hnet_pubkey_list': hnet_pubkey_list
425 }
426
427 def _encode_bin(self, in_json):
428 return h2b(self._encode_hex(in_json))
429
Harald Weltec91085e2022-02-10 18:05:45 +0100430
Harald Welteb2edd142021-01-08 23:29:35 +0100431class EF_LI(TransRecEF):
Harald Welte13edf302022-07-21 15:19:23 +0200432 def __init__(self, fid='6f05', sfid=None, name='EF.LI', size=(2, None), rec_len=2,
Harald Welteb2edd142021-01-08 23:29:35 +0100433 desc='Language Indication'):
434 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, rec_len=rec_len)
Harald Weltec91085e2022-02-10 18:05:45 +0100435
Harald Weltef6b37af2023-01-24 15:42:26 +0100436 def _decode_record_bin(self, in_bin, **kwargs):
Harald Welteb2edd142021-01-08 23:29:35 +0100437 if in_bin == b'\xff\xff':
438 return None
439 else:
440 # officially this is 7-bit GSM alphabet with one padding bit in each byte
441 return in_bin.decode('ascii')
Harald Weltec91085e2022-02-10 18:05:45 +0100442
Harald Weltef6b37af2023-01-24 15:42:26 +0100443 def _encode_record_bin(self, in_json, **kwargs):
Harald Welteb2edd142021-01-08 23:29:35 +0100444 if in_json == None:
445 return b'\xff\xff'
446 else:
447 # officially this is 7-bit GSM alphabet with one padding bit in each byte
448 return in_json.encode('ascii')
449
Harald Weltec91085e2022-02-10 18:05:45 +0100450
Harald Welteb2edd142021-01-08 23:29:35 +0100451class EF_Keys(TransparentEF):
Harald Welte13edf302022-07-21 15:19:23 +0200452 def __init__(self, fid='6f08', sfid=0x08, name='EF.Keys', size=(33, 33),
Harald Welteb2edd142021-01-08 23:29:35 +0100453 desc='Ciphering and Integrity Keys'):
454 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
Harald Weltec91085e2022-02-10 18:05:45 +0100455 self._construct = Struct(
456 'ksi'/Int8ub, 'ck'/HexAdapter(Bytes(16)), 'ik'/HexAdapter(Bytes(16)))
Harald Welteb2edd142021-01-08 23:29:35 +0100457
Harald Welte14105dc2021-05-31 08:48:51 +0200458# TS 31.102 Section 4.2.6
459class EF_HPPLMN(TransparentEF):
Harald Welte865eea62023-01-27 19:26:12 +0100460 _test_de_encode = [ ( '05', 5 ) ]
Harald Welte13edf302022-07-21 15:19:23 +0200461 def __init__(self, fid='6f31', sfid=0x12, name='EF.HPPLMN', size=(1, 1),
Harald Welte14105dc2021-05-31 08:48:51 +0200462 desc='Higher Priority PLMN search period'):
463 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
464 self._construct = Int8ub
465
Harald Welte6ca2fa72022-02-12 16:29:31 +0100466class EF_UST(EF_UServiceTable):
467 def __init__(self, **kwargs):
Harald Welte13edf302022-07-21 15:19:23 +0200468 super().__init__(fid='6f38', sfid=0x04, name='EF.UST', desc='USIM Service Table', size=(1,17), table=EF_UST_map, **kwargs)
Harald Welte6ca2fa72022-02-12 16:29:31 +0100469 # add those commands to the general commands of a TransparentEF
470 self.shell_commands += [self.AddlShellCommands()]
471
Harald Welteb2edd142021-01-08 23:29:35 +0100472 @with_default_category('File-Specific Commands')
473 class AddlShellCommands(CommandSet):
474 def __init__(self):
475 super().__init__()
476
477 def do_ust_service_activate(self, arg):
478 """Activate a service within EF.UST"""
Alexander Couzens6c5c3f82023-07-28 05:13:06 +0200479 selected_file = self._cmd.lchan.selected_file
480 selected_file.ust_update(self._cmd, [int(arg)], [])
Harald Welteb2edd142021-01-08 23:29:35 +0100481
482 def do_ust_service_deactivate(self, arg):
483 """Deactivate a service within EF.UST"""
Alexander Couzens6c5c3f82023-07-28 05:13:06 +0200484 selected_file = self._cmd.lchan.selected_file
485 selected_file.ust_update(self._cmd, [], [int(arg)])
Harald Welteb2edd142021-01-08 23:29:35 +0100486
Harald Welte4c5e2312022-02-12 14:37:48 +0100487 def do_ust_service_check(self, arg):
Harald Welte3bb516b2022-02-12 21:53:18 +0100488 """Check consistency between services of this file and files present/activated.
489
490 Many services determine if one or multiple files shall be present/activated or if they shall be
491 absent/deactivated. This performs a consistency check to ensure that no services are activated
492 for files that are not - and vice-versa, no files are activated for services that are not. Error
493 messages are printed for every inconsistency found."""
Harald Weltea6c0f882022-07-17 14:23:17 +0200494 selected_file = self._cmd.lchan.selected_file
Harald Welte82f75c22022-02-12 18:22:28 +0100495 num_problems = selected_file.ust_service_check(self._cmd)
496 # obtain list of currently active services
497 active_services = selected_file.get_active_services(self._cmd)
498 # Service n°46 can only be declared "available" if service n°45 is declared "available"
499 if 46 in active_services and not 45 in active_services:
Harald Weltefa8b8d12022-02-12 18:30:28 +0100500 self._cmd.perror("ERROR: Service 46 available, but it requires Service 45")
Harald Welte82f75c22022-02-12 18:22:28 +0100501 num_problems += 1
502 # Service n°125 shall only be taken into account if Service n°124 is declared "available"
503 if 125 in active_services and not 124 in active_services:
Harald Weltefa8b8d12022-02-12 18:30:28 +0100504 self._cmd.perror("ERROR: Service 125 is ignored as Service 124 not available")
Harald Welte82f75c22022-02-12 18:22:28 +0100505 num_problems += 1
506 # Service n°95, n°99 and n°115 shall not be declared "available" if an ISIM application is present on the UICC
507 non_isim_services = [95, 99, 115]
508 app_names = selected_file.get_mf().get_app_names()
509 if 'ADF.ISIM' in app_names:
510 for s in non_isim_services:
511 if s in active_services:
Harald Weltefa8b8d12022-02-12 18:30:28 +0100512 self._cmd.perror("ERROR: Service %u shall not be available as ISIM application is present" % s)
Harald Welte82f75c22022-02-12 18:22:28 +0100513 num_problems += 1
514 self._cmd.poutput("===> %u service / file inconsistencies detected" % num_problems)
Harald Welte4c5e2312022-02-12 14:37:48 +0100515
516
Harald Welte89e59542021-04-02 21:33:13 +0200517# TS 31.103 Section 4.2.7 - *not* the same as DF.GSM/EF.ECC!
518class EF_ECC(LinFixedEF):
Harald Welte865eea62023-01-27 19:26:12 +0100519 _test_de_encode = [
520 ( '19f1ff01', { "call_code": "911f",
521 "service_category": { "police": True, "ambulance": False, "fire_brigade": False,
522 "marine_guard": False, "mountain_rescue": False,
523 "manual_ecall": False, "automatic_ecall": False } } ),
524 ( '19f3ff02', { "call_code": "913f",
525 "service_category": { "police": False, "ambulance": True, "fire_brigade": False,
526 "marine_guard": False, "mountain_rescue": False,
527 "manual_ecall": False, "automatic_ecall": False } } ),
528 ]
529 cc_construct = BcdAdapter(Rpad(Bytes(3)))
Harald Welteff2d86d2022-01-21 15:19:47 +0100530 category_construct = FlagsEnum(Byte, police=1, ambulance=2, fire_brigade=3, marine_guard=4,
531 mountain_rescue=5, manual_ecall=6, automatic_ecall=7)
532 alpha_construct = GsmStringAdapter(Rpad(GreedyBytes))
Harald Weltec91085e2022-02-10 18:05:45 +0100533
Harald Welte89e59542021-04-02 21:33:13 +0200534 def __init__(self, fid='6fb7', sfid=0x01, name='EF.ECC',
535 desc='Emergency Call Codes'):
Harald Welte99e4cc02022-07-21 15:25:47 +0200536 super().__init__(fid, sfid=sfid, name=name, desc=desc, rec_len=(4, 20))
Harald Weltec91085e2022-02-10 18:05:45 +0100537
Harald Weltef6b37af2023-01-24 15:42:26 +0100538 def _decode_record_bin(self, in_bin, **kwargs):
Harald Welteff2d86d2022-01-21 15:19:47 +0100539 # mandatory parts
540 code = in_bin[:3]
541 if code == b'\xff\xff\xff':
542 return None
543 svc_category = in_bin[-1:]
544 ret = {'call_code': parse_construct(EF_ECC.cc_construct, code),
Harald Weltec91085e2022-02-10 18:05:45 +0100545 'service_category': parse_construct(EF_ECC.category_construct, svc_category)}
Harald Welteff2d86d2022-01-21 15:19:47 +0100546 # optional alpha identifier
547 if len(in_bin) > 4:
548 alpha_id = in_bin[3:-1]
549 ret['alpha_id'] = parse_construct(EF_ECC.alpha_construct, alpha_id)
550 return ret
Harald Weltec91085e2022-02-10 18:05:45 +0100551
Harald Weltef6b37af2023-01-24 15:42:26 +0100552 def _encode_record_bin(self, in_json, **kwargs):
Harald Welteff2d86d2022-01-21 15:19:47 +0100553 if in_json is None:
554 return b'\xff\xff\xff\xff'
555 code = EF_ECC.cc_construct.build(in_json['call_code'])
Harald Welte9b9efb62023-01-31 16:40:54 +0100556 svc_category = EF_ECC.category_construct.build(in_json['service_category'])
557 if 'alpha_id' in in_json:
558 alpha_id = EF_ECC.alpha_construct.build(in_json['alpha_id'])
559 # FIXME: alpha_id needs padding up to 'record_length - 4'
560 else:
561 alpha_id = b''
Harald Welteff2d86d2022-01-21 15:19:47 +0100562 return code + alpha_id + svc_category
563
Harald Welte89e59542021-04-02 21:33:13 +0200564
Harald Welte790b2702021-04-11 00:01:35 +0200565# TS 31.102 Section 4.2.17
566class EF_LOCI(TransparentEF):
Harald Welte865eea62023-01-27 19:26:12 +0100567 _test_de_encode = [
568 ( '47d1264a62f21037211e00',
569 { "tmsi": "47d1264a", "lai": { "mcc_mnc": "262f01", "lac": "3721" },
570 "rfu": 30, "lu_status": 0 } ),
Harald Welte324175f2023-12-21 20:25:30 +0100571 ( 'ffffffff62f2200000ff01',
572 {"tmsi": "ffffffff", "lai": {"mcc_mnc": "262f02", "lac": "0000"}, "rfu": 255, "lu_status": 1} ),
Harald Welte865eea62023-01-27 19:26:12 +0100573 ]
Harald Welte13edf302022-07-21 15:19:23 +0200574 def __init__(self, fid='6f7e', sfid=0x0b, name='EF.LOCI', desc='Location information', size=(11, 11)):
Harald Welte790b2702021-04-11 00:01:35 +0200575 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
Harald Welte3a5afff2022-02-25 15:33:46 +0100576 Lai = Struct('mcc_mnc'/BcdAdapter(Bytes(3)), 'lac'/HexAdapter(Bytes(2)))
577 self._construct = Struct('tmsi'/HexAdapter(Bytes(4)), 'lai'/Lai, 'rfu'/Int8ub, 'lu_status'/Int8ub)
Harald Welte865eea62023-01-27 19:26:12 +0100578
Harald Welte592b32e2021-06-05 11:26:36 +0200579# TS 31.102 Section 4.2.18
580class EF_AD(TransparentEF):
Harald Welte865eea62023-01-27 19:26:12 +0100581 _test_de_encode = [
582 ( '00000002', { "ms_operation_mode": "normal",
583 "additional_info": { "ciphering_indicator": False, "csg_display_control": False,
584 "prose_services": False, "extended_drx": False },
585 "rfu": 0, "mnc_len": 2, "extensions": b'' } ),
586 ( '01000102', { "ms_operation_mode": "normal_and_specific_facilities",
587 "additional_info": { "ciphering_indicator": True, "csg_display_control": False,
588 "prose_services": False, "extended_drx": False },
589 "rfu": 0, "mnc_len": 2, "extensions": b'' } ),
590 ]
Harald Welte592b32e2021-06-05 11:26:36 +0200591 class OP_MODE(enum.IntEnum):
Harald Weltec91085e2022-02-10 18:05:45 +0100592 normal = 0x00
593 type_approval = 0x80
594 normal_and_specific_facilities = 0x01
595 type_approval_and_specific_facilities = 0x81
596 maintenance_off_line = 0x02
597 cell_test = 0x04
Harald Welte592b32e2021-06-05 11:26:36 +0200598
Harald Welte13edf302022-07-21 15:19:23 +0200599 def __init__(self, fid='6fad', sfid=0x03, name='EF.AD', desc='Administrative Data', size=(4, 6)):
Harald Welte592b32e2021-06-05 11:26:36 +0200600 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
601 self._construct = BitStruct(
602 # Byte 1
603 'ms_operation_mode'/Bytewise(Enum(Byte, EF_AD.OP_MODE)),
604 # Byte 2 + 3
605 'additional_info'/Bytewise(FlagsEnum(Int16ub, ciphering_indicator=1, csg_display_control=2,
606 prose_services=4, extended_drx=8)),
607 'rfu'/BitsRFU(4),
608 'mnc_len'/BitsInteger(4),
609 'extensions'/COptional(Bytewise(GreedyBytesRFU))
610 )
Harald Welte790b2702021-04-11 00:01:35 +0200611
612# TS 31.102 Section 4.2.23
613class EF_PSLOCI(TransparentEF):
Harald Welte13edf302022-07-21 15:19:23 +0200614 def __init__(self, fid='6f73', sfid=0x0c, name='EF.PSLOCI', desc='PS Location information', size=(14, 14)):
Harald Welte790b2702021-04-11 00:01:35 +0200615 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
616 self._construct = Struct('ptmsi'/HexAdapter(Bytes(4)), 'ptmsi_sig'/HexAdapter(Bytes(3)),
617 'rai'/HexAdapter(Bytes(6)), 'rau_status'/Int8ub)
618
619# TS 31.102 Section 4.2.33
620class EF_ICI(CyclicEF):
Harald Welte99e4cc02022-07-21 15:25:47 +0200621 def __init__(self, fid='6f80', sfid=0x14, name='EF.ICI', rec_len=(28, 48),
Harald Welte6169c722022-02-12 09:05:15 +0100622 desc='Incoming Call Information', **kwargs):
623 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len, **kwargs)
Harald Welte3c98d5e2022-07-20 07:40:05 +0200624 self._construct = Struct('alpha_id'/HexAdapter(Bytes(this._.total_len-28)),
Harald Welte790b2702021-04-11 00:01:35 +0200625 'len_of_bcd_contents'/Int8ub,
626 'ton_npi'/Int8ub,
627 'call_number'/BcdAdapter(Bytes(10)),
628 'cap_cfg2_record_id'/Int8ub,
629 'ext5_record_id'/Int8ub,
630 'date_and_time'/BcdAdapter(Bytes(7)),
631 'duration'/Int24ub,
632 'status'/Byte,
Harald Welte3c98d5e2022-07-20 07:40:05 +0200633 'link_to_phonebook'/HexAdapter(Bytes(3)))
Harald Welte790b2702021-04-11 00:01:35 +0200634
635# TS 31.102 Section 4.2.34
636class EF_OCI(CyclicEF):
Harald Welte99e4cc02022-07-21 15:25:47 +0200637 def __init__(self, fid='6f81', sfid=0x15, name='EF.OCI', rec_len=(27, 47),
Harald Welte6169c722022-02-12 09:05:15 +0100638 desc='Outgoing Call Information', **kwargs):
639 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len, **kwargs)
Harald Welte3c98d5e2022-07-20 07:40:05 +0200640 self._construct = Struct('alpha_id'/HexAdapter(Bytes(this._.total_len-27)),
Harald Welte790b2702021-04-11 00:01:35 +0200641 'len_of_bcd_contents'/Int8ub,
642 'ton_npi'/Int8ub,
643 'call_number'/BcdAdapter(Bytes(10)),
644 'cap_cfg2_record_id'/Int8ub,
645 'ext5_record_id'/Int8ub,
646 'date_and_time'/BcdAdapter(Bytes(7)),
647 'duration'/Int24ub,
Harald Welte3c98d5e2022-07-20 07:40:05 +0200648 'link_to_phonebook'/HexAdapter(Bytes(3)))
Harald Welte790b2702021-04-11 00:01:35 +0200649
650# TS 31.102 Section 4.2.35
651class EF_ICT(CyclicEF):
Harald Welte99e4cc02022-07-21 15:25:47 +0200652 def __init__(self, fid='6f82', sfid=None, name='EF.ICT', rec_len=(3, 3),
Harald Welte6169c722022-02-12 09:05:15 +0100653 desc='Incoming Call Timer', **kwargs):
654 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200655 self._construct = Struct('accumulated_call_timer'/Int24ub)
656
657# TS 31.102 Section 4.2.38
658class EF_CCP2(LinFixedEF):
Harald Welte6169c722022-02-12 09:05:15 +0100659 def __init__(self, fid='6f4f', sfid=0x16, name='EF.CCP2', desc='Capability Configuration Parameters 2', **kwargs):
Harald Welte99e4cc02022-07-21 15:25:47 +0200660 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=(15, None), **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200661
Harald Welte6ca2fa72022-02-12 16:29:31 +0100662# TS 31.102 Section 4.2.47
663class EF_EST(EF_UServiceTable):
664 def __init__(self, **kwargs):
Harald Welte13edf302022-07-21 15:19:23 +0200665 super().__init__(fid='6f56', sfid=0x05, name='EF.EST', desc='Enabled Services Table', size=(1,None), table=EF_EST_map, **kwargs)
Harald Welte6ca2fa72022-02-12 16:29:31 +0100666 # add those commands to the general commands of a TransparentEF
667 self.shell_commands += [self.AddlShellCommands()]
668
669 @with_default_category('File-Specific Commands')
670 class AddlShellCommands(CommandSet):
671 def __init__(self):
672 super().__init__()
673
Harald Welte18b75392023-02-23 10:00:51 +0100674 def do_est_service_enable(self, arg):
Alexander Couzensc8facea2023-07-29 05:01:57 +0200675 """Enable a service within EF.EST"""
676 selected_file = self._cmd.lchan.selected_file
677 selected_file.ust_update(self._cmd, [int(arg)], [])
Harald Welte6ca2fa72022-02-12 16:29:31 +0100678
Harald Welte18b75392023-02-23 10:00:51 +0100679 def do_est_service_disable(self, arg):
Alexander Couzensc8facea2023-07-29 05:01:57 +0200680 """Disable a service within EF.EST"""
681 selected_file = self._cmd.lchan.selected_file
682 selected_file.ust_update(self._cmd, [], [int(arg)])
Harald Welte6ca2fa72022-02-12 16:29:31 +0100683
Harald Welte790b2702021-04-11 00:01:35 +0200684# TS 31.102 Section 4.2.48
685class EF_ACL(TransparentEF):
Harald Welte13edf302022-07-21 15:19:23 +0200686 def __init__(self, fid='6f57', sfid=None, name='EF.ACL', size=(32, None),
Harald Welte6169c722022-02-12 09:05:15 +0100687 desc='Access Point Name Control List', **kwargs):
688 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Welte3c98d5e2022-07-20 07:40:05 +0200689 self._construct = Struct('num_of_apns'/Int8ub, 'tlvs'/HexAdapter(GreedyBytes))
Harald Welte790b2702021-04-11 00:01:35 +0200690
691# TS 31.102 Section 4.2.51
692class EF_START_HFN(TransparentEF):
Harald Welte865eea62023-01-27 19:26:12 +0100693 _test_de_encode = [
694 ( 'f00000f00000', { "start_cs": 15728640, "start_ps": 15728640 } ),
695 ]
Harald Welte13edf302022-07-21 15:19:23 +0200696 def __init__(self, fid='6f5b', sfid=0x0f, name='EF.START-HFN', size=(6, 6),
Harald Welte6169c722022-02-12 09:05:15 +0100697 desc='Initialisation values for Hyperframe number', **kwargs):
698 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200699 self._construct = Struct('start_cs'/Int24ub, 'start_ps'/Int24ub)
700
701# TS 31.102 Section 4.2.52
702class EF_THRESHOLD(TransparentEF):
Harald Welte865eea62023-01-27 19:26:12 +0100703 _test_de_encode = [
704 ( 'f01000', { "max_start": 15732736 } ),
705 ]
Harald Welte13edf302022-07-21 15:19:23 +0200706 def __init__(self, fid='6f5c', sfid=0x10, name='EF.THRESHOLD', size=(3, 3),
Harald Welte6169c722022-02-12 09:05:15 +0100707 desc='Maximum value of START', **kwargs):
708 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200709 self._construct = Struct('max_start'/Int24ub)
710
Harald Welte363edd92022-07-17 22:24:03 +0200711# TS 31.102 (old releases like 3.8.0) Section 4.2.56
712class EF_RPLMNAcT(TransRecEF):
Harald Welte13edf302022-07-21 15:19:23 +0200713 def __init__(self, fid='6f65', sfid=None, name='EF.RPLMNAcTD', size=(2, 4), rec_len=2,
Harald Welte363edd92022-07-17 22:24:03 +0200714 desc='RPLMN Last used Access Technology', **kwargs):
715 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, rec_len=rec_len, **kwargs)
Harald Weltef6b37af2023-01-24 15:42:26 +0100716 def _decode_record_hex(self, in_hex, **kwargs):
Harald Welte363edd92022-07-17 22:24:03 +0200717 return dec_act(in_hex)
718 # TODO: Encode
719
Harald Welte790b2702021-04-11 00:01:35 +0200720# TS 31.102 Section 4.2.77
721class EF_VGCSCA(TransRecEF):
Harald Welte13edf302022-07-21 15:19:23 +0200722 def __init__(self, fid='6fd4', sfid=None, name='EF.VGCSCA', size=(2, 100), rec_len=2,
Harald Welte6169c722022-02-12 09:05:15 +0100723 desc='Voice Group Call Service Ciphering Algorithm', **kwargs):
724 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, rec_len=rec_len, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200725 self._construct = Struct('alg_v_ki_1'/Int8ub, 'alg_v_ki_2'/Int8ub)
726
727# TS 31.102 Section 4.2.79
728class EF_GBABP(TransparentEF):
Harald Welte13edf302022-07-21 15:19:23 +0200729 def __init__(self, fid='6fd6', sfid=None, name='EF.GBABP', size=(3, 50),
Harald Welte6169c722022-02-12 09:05:15 +0100730 desc='GBA Bootstrapping parameters', **kwargs):
731 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200732 self._construct = Struct('rand'/LV, 'b_tid'/LV, 'key_lifetime'/LV)
733
734# TS 31.102 Section 4.2.80
735class EF_MSK(LinFixedEF):
Harald Welte6169c722022-02-12 09:05:15 +0100736 def __init__(self, fid='6fd7', sfid=None, name='EF.MSK', desc='MBMS Service Key List', **kwargs):
Harald Welte99e4cc02022-07-21 15:25:47 +0200737 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=(20, None), **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200738 msk_ts_constr = Struct('msk_id'/Int32ub, 'timestamp_counter'/Int32ub)
Harald Welte3c98d5e2022-07-20 07:40:05 +0200739 self._construct = Struct('key_domain_id'/HexAdapter(Bytes(3)),
Harald Welte790b2702021-04-11 00:01:35 +0200740 'num_msk_id'/Int8ub,
741 'msk_ids'/msk_ts_constr[this.num_msk_id])
Harald Welte14105dc2021-05-31 08:48:51 +0200742# TS 31.102 Section 4.2.81
743class EF_MUK(LinFixedEF):
744 class MUK_Idr(BER_TLV_IE, tag=0x80):
745 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100746
Harald Welte14105dc2021-05-31 08:48:51 +0200747 class MUK_Idi(BER_TLV_IE, tag=0x82):
748 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100749
Harald Welte14105dc2021-05-31 08:48:51 +0200750 class MUK_ID(BER_TLV_IE, tag=0xA0, nested=[MUK_Idr, MUK_Idi]):
751 pass
Harald Weltec91085e2022-02-10 18:05:45 +0100752
Harald Welte14105dc2021-05-31 08:48:51 +0200753 class TimeStampCounter(BER_TLV_IE, tag=0x81):
754 pass
Harald Weltec91085e2022-02-10 18:05:45 +0100755
Harald Welte14105dc2021-05-31 08:48:51 +0200756 class EF_MUK_Collection(TLV_IE_Collection, nested=[MUK_ID, TimeStampCounter]):
757 pass
Harald Weltec91085e2022-02-10 18:05:45 +0100758
Harald Welte6169c722022-02-12 09:05:15 +0100759 def __init__(self, fid='6fd8', sfid=None, name='EF.MUK', desc='MBMS User Key', **kwargs):
Harald Welte99e4cc02022-07-21 15:25:47 +0200760 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=(None, None), **kwargs)
Harald Welte14105dc2021-05-31 08:48:51 +0200761 self._tlv = EF_MUK.EF_MUK_Collection
762
763# TS 31.102 Section 4.2.83
764class EF_GBANL(LinFixedEF):
765 class NAF_ID(BER_TLV_IE, tag=0x80):
766 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100767
Harald Welte14105dc2021-05-31 08:48:51 +0200768 class B_TID(BER_TLV_IE, tag=0x81):
769 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100770
Harald Welte14105dc2021-05-31 08:48:51 +0200771 class EF_GBANL_Collection(BER_TLV_IE, nested=[NAF_ID, B_TID]):
772 pass
Harald Weltec91085e2022-02-10 18:05:45 +0100773
Harald Welte6169c722022-02-12 09:05:15 +0100774 def __init__(self, fid='6fda', sfid=None, name='EF.GBANL', desc='GBA NAF List', **kwargs):
Harald Welte99e4cc02022-07-21 15:25:47 +0200775 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=(None, None), **kwargs)
Harald Welte14105dc2021-05-31 08:48:51 +0200776 self._tlv = EF_GBANL.EF_GBANL_Collection
Harald Welte790b2702021-04-11 00:01:35 +0200777
778# TS 31.102 Section 4.2.85
779class EF_EHPLMNPI(TransparentEF):
Harald Welte865eea62023-01-27 19:26:12 +0100780 _test_de_encode = [
Harald Welte324175f2023-12-21 20:25:30 +0100781 ( '00', {"presentation_ind": "no_preference"} ),
Harald Welte865eea62023-01-27 19:26:12 +0100782 ( '02', { "presentation_ind": "display_all" } ),
783 ]
Harald Welte13edf302022-07-21 15:19:23 +0200784 def __init__(self, fid='6fdb', sfid=None, name='EF.EHPLMNPI', size=(1, 1),
Harald Welte6169c722022-02-12 09:05:15 +0100785 desc='Equivalent HPLMN Presentation Indication', **kwargs):
786 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Weltec91085e2022-02-10 18:05:45 +0100787 self._construct = Struct('presentation_ind' /
Harald Welte790b2702021-04-11 00:01:35 +0200788 Enum(Byte, no_preference=0, display_highest_prio_only=1, display_all=2))
Harald Welte14105dc2021-05-31 08:48:51 +0200789
790# TS 31.102 Section 4.2.87
791class EF_NAFKCA(LinFixedEF):
792 class NAF_KeyCentreAddress(BER_TLV_IE, tag=0x80):
793 _construct = HexAdapter(GreedyBytes)
Harald Welte99e4cc02022-07-21 15:25:47 +0200794 def __init__(self, fid='6fdd', sfid=None, name='EF.NAFKCA', rec_len=(None, None),
Harald Welte6169c722022-02-12 09:05:15 +0100795 desc='NAF Key Centre Address', **kwargs):
796 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len, **kwargs)
Harald Welte14105dc2021-05-31 08:48:51 +0200797 self._tlv = EF_NAFKCA.NAF_KeyCentreAddress
798
799# TS 31.102 Section 4.2.90
800class EF_NCP_IP(LinFixedEF):
801 class DataDestAddrRange(TLV_IE, tag=0x83):
802 _construct = Struct('type_of_address'/Enum(Byte, IPv4=0x21, IPv6=0x56),
803 'prefix_length'/Int8ub,
804 'prefix'/HexAdapter(GreedyBytes))
Harald Weltec91085e2022-02-10 18:05:45 +0100805
Harald Welte14105dc2021-05-31 08:48:51 +0200806 class AccessPointName(TLV_IE, tag=0x80):
807 # coded as per TS 23.003
808 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100809
Harald Welte14105dc2021-05-31 08:48:51 +0200810 class Login(TLV_IE, tag=0x81):
811 # as per SMS DCS TS 23.038
812 _construct = GsmStringAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100813
Harald Welte14105dc2021-05-31 08:48:51 +0200814 class Password(TLV_IE, tag=0x82):
815 # as per SMS DCS TS 23.038
816 _construct = GsmStringAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100817
Harald Welte14105dc2021-05-31 08:48:51 +0200818 class BearerDescription(TLV_IE, tag=0x84):
819 # Bearer descriptionTLV DO as per TS 31.111
820 pass
Harald Weltec91085e2022-02-10 18:05:45 +0100821
Harald Welte14105dc2021-05-31 08:48:51 +0200822 class EF_NCP_IP_Collection(TLV_IE_Collection,
823 nested=[AccessPointName, Login, Password, BearerDescription]):
824 pass
Harald Welte99e4cc02022-07-21 15:25:47 +0200825 def __init__(self, fid='6fe2', sfid=None, name='EF.NCP-IP', rec_len=(None, None),
Harald Welte6169c722022-02-12 09:05:15 +0100826 desc='Network Connectivity Parameters for USIM IP connections', **kwargs):
827 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len, **kwargs)
Harald Welte14105dc2021-05-31 08:48:51 +0200828 self._tlv = EF_NCP_IP.EF_NCP_IP_Collection
829
Harald Welte790b2702021-04-11 00:01:35 +0200830# TS 31.102 Section 4.2.91
831class EF_EPSLOCI(TransparentEF):
Harald Welte12721292022-07-21 15:33:06 +0200832 def __init__(self, fid='6fe3', sfid=0x1e, name='EF.EPSLOCI',
833 desc='EPS Location Information', size=(18,18), **kwargs):
Harald Welte6169c722022-02-12 09:05:15 +0100834 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Weltec91085e2022-02-10 18:05:45 +0100835 upd_status_constr = Enum(
836 Byte, updated=0, not_updated=1, roaming_not_allowed=2)
Harald Welte3c98d5e2022-07-20 07:40:05 +0200837 self._construct = Struct('guti'/HexAdapter(Bytes(12)),
838 'last_visited_registered_tai'/HexAdapter(Bytes(5)),
Harald Welte790b2702021-04-11 00:01:35 +0200839 'eps_update_status'/upd_status_constr)
840
Harald Welte14105dc2021-05-31 08:48:51 +0200841# TS 31.102 Section 4.2.92
842class EF_EPSNSC(LinFixedEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100843 class KSI_ASME(BER_TLV_IE, tag=0x80):
Harald Welte14105dc2021-05-31 08:48:51 +0200844 _construct = Int8ub
Harald Weltec91085e2022-02-10 18:05:45 +0100845
846 class K_ASME(BER_TLV_IE, tag=0x81):
Harald Welte14105dc2021-05-31 08:48:51 +0200847 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100848
Harald Welte14105dc2021-05-31 08:48:51 +0200849 class UplinkNASCount(BER_TLV_IE, tag=0x82):
850 _construct = Int32ub
Harald Weltec91085e2022-02-10 18:05:45 +0100851
Harald Welte14105dc2021-05-31 08:48:51 +0200852 class DownlinkNASCount(BER_TLV_IE, tag=0x83):
853 _construct = Int32ub
Harald Weltec91085e2022-02-10 18:05:45 +0100854
Harald Welte14105dc2021-05-31 08:48:51 +0200855 class IDofNASAlgorithms(BER_TLV_IE, tag=0x84):
856 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100857
Harald Welte14105dc2021-05-31 08:48:51 +0200858 class EPS_NAS_Security_Context(BER_TLV_IE, tag=0xa0,
Harald Weltec91085e2022-02-10 18:05:45 +0100859 nested=[KSI_ASME, K_ASME, UplinkNASCount, DownlinkNASCount,
860 IDofNASAlgorithms]):
Harald Welte14105dc2021-05-31 08:48:51 +0200861 pass
Harald Welte99e4cc02022-07-21 15:25:47 +0200862 def __init__(self, fid='6fe4', sfid=0x18, name='EF.EPSNSC', rec_len=(54, 128),
Harald Welte6169c722022-02-12 09:05:15 +0100863 desc='EPS NAS Security Context', **kwargs):
864 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len, **kwargs)
Harald Welte14105dc2021-05-31 08:48:51 +0200865 self._tlv = EF_EPSNSC.EPS_NAS_Security_Context
866
Harald Welte790b2702021-04-11 00:01:35 +0200867# TS 31.102 Section 4.2.96
868class EF_PWS(TransparentEF):
Harald Welte865eea62023-01-27 19:26:12 +0100869 _test_de_encode = [
870 ( '00', { "pws_configuration": { "ignore_pws_in_hplmn_and_equivalent": False,
871 "ignore_pws_in_vplmn": False } } ),
872 ]
Harald Welte13edf302022-07-21 15:19:23 +0200873 def __init__(self, fid='6fec', sfid=None, name='EF.PWS', desc='Public Warning System', size=(1, 1), **kwargs):
Harald Welte6169c722022-02-12 09:05:15 +0100874 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Weltec91085e2022-02-10 18:05:45 +0100875 pws_config = FlagsEnum(
876 Byte, ignore_pws_in_hplmn_and_equivalent=1, ignore_pws_in_vplmn=2)
Harald Welte790b2702021-04-11 00:01:35 +0200877 self._construct = Struct('pws_configuration'/pws_config)
878
879# TS 31.102 Section 4.2.101
880class EF_IPS(CyclicEF):
Harald Welte99e4cc02022-07-21 15:25:47 +0200881 def __init__(self, fid='6ff1', sfid=None, name='EF.IPS', rec_len=(4, 4),
Harald Welte6169c722022-02-12 09:05:15 +0100882 desc='IMEI(SV) Pairing Status', **kwargs):
883 super().__init__(fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200884 self._construct = Struct('status'/PaddedString(2, 'ascii'),
885 'link_to_ef_ipd'/Int8ub, 'rfu'/Byte)
886
Harald Welte14105dc2021-05-31 08:48:51 +0200887# TS 31.102 Section 4.2.103
888class EF_ePDGId(TransparentEF):
Harald Welte478b5fe2023-12-08 14:27:50 +0100889 _test_de_encode = [
890 ( '801100657064672e6f736d6f636f6d2e6f7267', {'e_pdg_id': {"type_of_ePDG_address": "FQDN", "ePDG_address" : "epdg.osmocom.org" } } ),
Harald Welte6e9ae8a2023-12-08 14:57:19 +0100891 ( '800501c0a8a001', {'e_pdg_id': {"type_of_ePDG_address": "IPv4", "ePDG_address" : "192.168.160.1" } } ),
892 ( '80110220010db8000000000000000000000023', {'e_pdg_id': {"type_of_ePDG_address": "IPv6", "ePDG_address" : "2001:db8::23" } } ),
Harald Welte478b5fe2023-12-08 14:27:50 +0100893 ]
894 class ePDGId(BER_TLV_IE, tag=0x80):
Harald Welte14105dc2021-05-31 08:48:51 +0200895 _construct = Struct('type_of_ePDG_address'/Enum(Byte, FQDN=0, IPv4=1, IPv6=2),
Harald Welte478b5fe2023-12-08 14:27:50 +0100896 'ePDG_address'/Switch(this.type_of_ePDG_address,
Philipp Maier791f80a2023-07-26 17:01:37 +0200897 {'FQDN': Utf8Adapter(GreedyBytes),
Harald Welte6e9ae8a2023-12-08 14:57:19 +0100898 'IPv4': Ipv4Adapter(GreedyBytes),
899 'IPv6': Ipv6Adapter(GreedyBytes)}))
Harald Weltec91085e2022-02-10 18:05:45 +0100900
iw040ef2262023-11-07 13:41:12 +0100901 def __init__(self, fid='6ff3', sfid=None, name='EF.ePDGId', desc='Home ePDG Identifier', **kwargs):
Harald Welte6169c722022-02-12 09:05:15 +0100902 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
Harald Welte14105dc2021-05-31 08:48:51 +0200903 self._tlv = EF_ePDGId.ePDGId
904
Harald Weltecdfe1c22023-12-08 12:30:21 +0100905# TS 31.102 Section 4.2.104
906class EF_ePDGSelection(TransparentEF):
Harald Welte478b5fe2023-12-08 14:27:50 +0100907 _test_de_encode = [
908 ( '80060001f1000100', {'e_pdg_selection': [{'plmn': '00101f', 'epdg_priority': 1, 'epdg_fqdn_format': 'operator_identified' }] }),
909 ( '800600011000a001', {'e_pdg_selection': [{'plmn': '001001', 'epdg_priority': 160, 'epdg_fqdn_format': 'location_based' }] }),
910 ]
911 class ePDGSelection(BER_TLV_IE, tag=0x80):
Harald Weltecdfe1c22023-12-08 12:30:21 +0100912 _construct = GreedyRange(Struct('plmn'/BcdAdapter(Bytes(3)),
913 'epdg_priority'/Int16ub,
914 'epdg_fqdn_format'/Enum(Int8ub, operator_identified=0, location_based=1)))
915
916 def __init__(self, fid='6ff4', sfid=None, name='EF.ePDGSelection', desc='ePDG Selection Information', **kwargs):
917 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
918 self._tlv = EF_ePDGSelection.ePDGSelection
919
Harald Welte71290072021-04-21 10:58:24 +0200920# TS 31.102 Section 4.2.106
921class EF_FromPreferred(TransparentEF):
Harald Welte13edf302022-07-21 15:19:23 +0200922 def __init__(self, fid='6ff7', sfid=None, name='EF.FromPreferred', size=(1, 1),
Harald Welte6169c722022-02-12 09:05:15 +0100923 desc='From Preferred', **kwargs):
924 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Welte45477a72023-11-03 01:33:06 +0100925 self._construct = BitStruct('rfu'/BitsRFU(7), 'from_preferred'/Flag)
Harald Welte71290072021-04-21 10:58:24 +0200926
Harald Weltefc67de22023-05-23 20:29:49 +0200927# TS 31.102 Section 4.2.114
928class EF_eAKA(TransparentEF):
929 def __init__(self, fid='6f01', sfid=None, name='EF.eAKA', size=(1, 1),
930 desc='enhanced AKA support', **kwargs):
931 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Welte45477a72023-11-03 01:33:06 +0100932 self._construct = BitStruct('rfu'/BitsRFU(7), 'enhanced_sqn_calculation_supported'/Flag)
Harald Weltefc67de22023-05-23 20:29:49 +0200933
Harald Welted90ceb82022-07-17 22:10:58 +0200934
935######################################################################
936# DF.GSM-ACCESS
937######################################################################
938
939class DF_GSM_ACCESS(CardDF):
940 def __init__(self, fid='5F3B', name='DF.GSM-ACCESS', desc='GSM Access', **kwargs):
941 super().__init__(fid=fid, name=name, desc=desc, service=27, **kwargs)
942 files = [
943 EF_Kc(fid='4f20', sfid=0x01, service=27),
944 EF_Kc(fid='4f52', sfid=0x02, name='EF.KcGPRS', desc='GPRS Ciphering key KcGPRS', service=27),
945 EF_CPBCCH(fid='4f63', service=39),
946 EF_InvScan(fid='4f64', service=40),
947 ]
948 self.add_files(files)
949
950
Harald Welte790b2702021-04-11 00:01:35 +0200951######################################################################
952# DF.5GS
953######################################################################
954
955# TS 31.102 Section 4.4.11.2
956class EF_5GS3GPPLOCI(TransparentEF):
Harald Welte13edf302022-07-21 15:19:23 +0200957 def __init__(self, fid='4f01', sfid=0x01, name='EF.5GS3GPPLOCI', size=(20, 20),
Harald Welte419bb492022-02-12 21:39:35 +0100958 desc='5S 3GP location information', **kwargs):
959 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Weltec91085e2022-02-10 18:05:45 +0100960 upd_status_constr = Enum(
961 Byte, updated=0, not_updated=1, roaming_not_allowed=2)
Harald Welte3c98d5e2022-07-20 07:40:05 +0200962 self._construct = Struct('5g_guti'/HexAdapter(Bytes(13)),
963 'last_visited_registered_tai_in_5gs'/HexAdapter(Bytes(6)),
Harald Welte790b2702021-04-11 00:01:35 +0200964 '5gs_update_status'/upd_status_constr)
965
966# TS 31.102 Section 4.4.11.7
967class EF_UAC_AIC(TransparentEF):
Harald Welte865eea62023-01-27 19:26:12 +0100968 _test_de_encode = [
969 ( '03', { "uac_access_id_config": { "multimedia_priority_service": True,
970 "mission_critical_service": True } } ),
971 ]
Harald Welte13edf302022-07-21 15:19:23 +0200972 def __init__(self, fid='4f06', sfid=0x06, name='EF.UAC_AIC', size=(4, 4),
Harald Welte419bb492022-02-12 21:39:35 +0100973 desc='UAC Access Identities Configuration', **kwargs):
974 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200975 cfg_constr = FlagsEnum(Byte, multimedia_priority_service=1,
Harald Weltec91085e2022-02-10 18:05:45 +0100976 mission_critical_service=2)
Harald Welte790b2702021-04-11 00:01:35 +0200977 self._construct = Struct('uac_access_id_config'/cfg_constr)
978
Harald Welte14105dc2021-05-31 08:48:51 +0200979# TS 31.102 Section 4.4.11.9
Harald Welte790b2702021-04-11 00:01:35 +0200980class EF_OPL5G(LinFixedEF):
Harald Welte52064292023-05-24 15:25:26 +0200981 def __init__(self, fid='4f08', sfid=0x08, name='EF.OPL5G', desc='5GS Operator PLMN List', **kwargs):
Harald Welte99e4cc02022-07-21 15:25:47 +0200982 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=(10, None), **kwargs)
Harald Welte3c98d5e2022-07-20 07:40:05 +0200983 Tai = Struct('mcc_mnc'/BcdAdapter(Bytes(3)), 'tac_min'/HexAdapter(Bytes(3)),
984 'tac_max'/HexAdapter(Bytes(3)))
Harald Weltea0377622022-02-25 15:36:44 +0100985 self._construct = Struct('tai'/Tai, 'pnn_record_id'/Int8ub)
Harald Welte790b2702021-04-11 00:01:35 +0200986
Harald Welte14105dc2021-05-31 08:48:51 +0200987# TS 31.102 Section 4.4.11.10
988class EF_SUPI_NAI(TransparentEF):
989 class NetworkSpecificIdentifier(TLV_IE, tag=0x80):
990 # RFC 7542 encoded as UTF-8 string
Philipp Maier791f80a2023-07-26 17:01:37 +0200991 _construct = Utf8Adapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100992
Harald Welte14105dc2021-05-31 08:48:51 +0200993 class GlobalLineIdentifier(TLV_IE, tag=0x81):
994 # TS 23.003 clause 28.16.2
Philipp Maier791f80a2023-07-26 17:01:37 +0200995 _construct = Utf8Adapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100996
Harald Welte14105dc2021-05-31 08:48:51 +0200997 class GlobalCableIdentifier(TLV_IE, tag=0x82):
998 # TS 23.003 clause 28.15.2
Philipp Maier791f80a2023-07-26 17:01:37 +0200999 _construct = Utf8Adapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +01001000
Harald Welte14105dc2021-05-31 08:48:51 +02001001 class NAI_TLV_Collection(TLV_IE_Collection,
Harald Weltec91085e2022-02-10 18:05:45 +01001002 nested=[NetworkSpecificIdentifier, GlobalLineIdentifier, GlobalCableIdentifier]):
Harald Welte14105dc2021-05-31 08:48:51 +02001003 pass
1004 def __init__(self, fid='4f09', sfid=0x09, name='EF.SUPI_NAI',
Harald Welte419bb492022-02-12 21:39:35 +01001005 desc='SUPI as Network Access Identifier', **kwargs):
1006 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
Harald Welte14105dc2021-05-31 08:48:51 +02001007 self._tlv = EF_SUPI_NAI.NAI_TLV_Collection
1008
Harald Welte455611c2023-05-27 12:48:54 +02001009# TS 31.102 Section 4.4.11.11
1010class EF_Routing_Indicator(TransparentEF):
1011 def __init__(self, fid='4f0a', sfid=0x0a, name='EF.Routing_Indicator', desc='Routing Indicator', **kwargs):
1012 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
1013 # 3GPP TS 24.501 Table 9.11.3.4.1:
1014 # Routing Indicator shall consist of 1 to 4 digits. The coding of this field is the
1015 # responsibility of home network operator but BCD coding shall be used. If a network
1016 # operator decides to assign less than 4 digits to Routing Indicator, the remaining digits
1017 # shall be coded as "1111" to fill the 4 digits coding of Routing Indicator
Harald Weltef9a5ba52023-06-09 09:17:05 +02001018 self._construct = Struct('routing_indicator'/Rpad(BcdAdapter(Bytes(2)), 'f', 2),
1019 'rfu'/HexAdapter(Bytes(2)))
Harald Weltec91085e2022-02-10 18:05:45 +01001020
Harald Weltefc67de22023-05-23 20:29:49 +02001021# TS 31.102 Section 4.4.11.13
Harald Welte14105dc2021-05-31 08:48:51 +02001022class EF_TN3GPPSNN(TransparentEF):
1023 class ServingNetworkName(BER_TLV_IE, tag=0x80):
Philipp Maier791f80a2023-07-26 17:01:37 +02001024 _construct = Utf8Adapter(GreedyBytes)
Harald Welte14105dc2021-05-31 08:48:51 +02001025 def __init__(self, fid='4f0c', sfid=0x0c, name='EF.TN3GPPSNN',
Harald Welte419bb492022-02-12 21:39:35 +01001026 desc='Trusted non-3GPP Serving network names list', **kwargs):
1027 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
Harald Welte14105dc2021-05-31 08:48:51 +02001028 self._tlv = EF_TN3GPPSNN.ServingNetworkName
1029
Harald Weltefc67de22023-05-23 20:29:49 +02001030# TS 31.102 Section 4.4.11.14 (Rel 17)
1031class EF_CAG(TransparentEF):
1032 def __init__(self, fid='4f0d', sfid=0x0d, name='EF.CAG',
1033 desc='Pre-configured CAG information list EF', **kwargs):
1034 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
1035 self._construct = HexAdapter(GreedyBytes)
1036
1037# TS 31.102 Section 4.4.11.15 (Rel 17)
1038class EF_SOR_CMCI(TransparentEF):
1039 def __init__(self, fid='4f0e', sfid=0x0e, name='EF.SOR-CMCI',
1040 desc='Steering Of Roaming - Connected Mode Control Information', **kwargs):
1041 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
1042 self._construct = HexAdapter(GreedyBytes)
1043
1044# TS 31.102 Section 4.4.11.17 (Rel 17)
1045class EF_DRI(TransparentEF):
1046 def __init__(self, fid='4f0f', sfid=0x0f, name='EF.DRI',
1047 desc='Disaster roaming information EF', **kwargs):
1048 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
1049 self._construct = Struct('disaster_roaming_enabled'/Byte,
1050 'parameters_indicator_status'/FlagsEnum(Byte, roaming_wait_range=1,
1051 return_wait_range=2,
1052 applicability_indicator=3),
1053 'roaming_wait_range'/HexAdapter(Bytes(2)),
1054 'return_wait_range'/HexAdapter(Bytes(2)),
1055 'applicability_indicator'/HexAdapter(Byte))
1056
1057# TS 31.102 Section 4.4.12.2 (Rel 17)
1058class EF_PWS_SNPN(TransparentEF):
1059 def __init__(self, fid='4f01', sfid=0x01, name='EF.PWS_SNPN',
1060 desc='Public Warning System in SNPNs', **kwargs):
1061 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
1062 self._construct = Struct('pws_config_in_snpns'/FlagsEnum(Byte, ignore_all_pws_in_subscribed=1,
1063 ignore_all_pws_in_non_subscribed=2))
1064
1065# TS 31.102 Section 4.4.12.2 (Rel 17)
1066class EF_NID(LinFixedEF):
1067 def __init__(self, fid='4f02', sfid=0x02, name='EF.NID',
1068 desc='Network Identifier for SNPN', **kwargs):
1069 super().__init__(fid, sfid=sfid, name=name, desc=desc, rec_len=(6,6), **kwargs)
1070 self._construct = Struct('assignment_mode'/Enum(Byte, coordinated_ass_opt1=0,
1071 self_ass=1,
1072 coordinated_ass_opt2=2),
1073 'network_identifier'/HexAdapter(Bytes(5)))
1074
1075# TS 31.102 Section 4.4.12 (Rel 17)
1076class DF_SNPN(CardDF):
1077 def __init__(self, fid='5fe0', name='DF.SNPN', desc='Files for SNPN purpose', **kwargs):
1078 super().__init__(fid=fid, name=name, desc=desc, **kwargs)
1079 files = [
1080 EF_PWS_SNPN(service=143),
1081 EF_NID(service=146),
1082 ]
1083 self.add_files(files)
1084
1085# TS 31.102 Section 4.4.13.2 (Rel 17)
1086class EF_5G_PROSE_ST(EF_UServiceTable):
1087 def __init__(self, **kwargs):
1088 super().__init__(fid='4f01', sfid=0x01, name='EF.5G_PROSE_ST',
1089 desc='5G ProSe Service Table', size=(1,2), table=EF_5G_PROSE_ST_map, **kwargs)
1090 # add those commands to the general commands of a TransparentEF
1091 self.shell_commands += [self.AddlShellCommands()]
1092
1093 @with_default_category('File-Specific Commands')
1094 class AddlShellCommands(CommandSet):
1095 def __init__(self):
1096 super().__init__()
1097
1098 def do_prose_service_activate(self, arg):
1099 """Activate a service within EF.5G_PROSE_ST"""
Alexander Couzensc8facea2023-07-29 05:01:57 +02001100 selected_file = self._cmd.lchan.selected_file
1101 selected_file.ust_update(self._cmd, [int(arg)], [])
Harald Weltefc67de22023-05-23 20:29:49 +02001102
1103 def do_prose_service_deactivate(self, arg):
1104 """Deactivate a service within EF.5G_PROSE_ST"""
Alexander Couzensc8facea2023-07-29 05:01:57 +02001105 selected_file = self._cmd.lchan.selected_file
1106 selected_file.ust_update(self._cmd, [], [int(arg)])
Harald Weltefc67de22023-05-23 20:29:49 +02001107
1108# TS 31.102 Section 4.4.13.3 (Rel 17)
1109class EF_5G_PROSE_DD(TransparentEF):
1110 class ServedByNgRan(BER_TLV_IE, tag=0x80):
1111 pass
1112 class NotServedByNgran(BER_TLV_IE, tag=0x81):
1113 pass
1114 class ProSeIdentifiers(BER_TLV_IE, tag=0x82):
1115 pass
1116 class ProSeIdToDefaultDestL2Id(BER_TLV_IE, tag=0x83):
1117 pass
1118 class GroupMemberDiscoveryParameters(BER_TLV_IE, tag=0x84):
1119 pass
1120 class ValidityTimer(BER_TLV_IE, tag=0x85):
1121 pass
1122 class ProSeDirectDiscoveryUeId(BER_TLV_IE, tag=0x86):
1123 pass
1124 class Hplmn5GDdnmfAddressInformation(BER_TLV_IE, tag=0x87):
1125 pass
1126 class ProSeConfigForDirectDiscovery(BER_TLV_IE, tag=0xA0,
1127 nested=[ServedByNgRan, NotServedByNgran, ProSeIdentifiers,
1128 ProSeIdToDefaultDestL2Id, GroupMemberDiscoveryParameters,
1129 ValidityTimer, ProSeDirectDiscoveryUeId,
1130 Hplmn5GDdnmfAddressInformation]):
1131 pass
1132 def __init__(self, fid='4f02', sfid=0x02, name='EF.5G_PROSE_DD',
1133 desc='5G ProSe configuration data for direct discovery', **kwargs):
1134 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
1135 # contains TLV structure despite being TransparentEF, not BER-TLV ?!?
1136 self._tlv = EF_5G_PROSE_DD.ProSeConfigForDirectDiscovery
1137
1138# TS 31.102 Section 4.4.13.4 (Rel 17)
1139class EF_5G_PROSE_DC(TransparentEF):
1140 class PrivacyConfig(BER_TLV_IE, tag=0x87):
1141 pass
1142 class DirectCommInNrPc5(BER_TLV_IE, tag=0x88):
1143 pass
1144 class ApplicationToPathPreferenceMappingRules(BER_TLV_IE, tag=0x89):
1145 pass
1146 class ProSeIdToNrTxProfileForBroadcastAndGroupcastMappingRules(BER_TLV_IE, tag=0x91):
1147 pass
1148 class ProSeConfigForDirectCommunication(BER_TLV_IE, tag=0xA0,
1149 nested=[EF_5G_PROSE_DD.ServedByNgRan,
1150 EF_5G_PROSE_DD.NotServedByNgran,
1151 PrivacyConfig, DirectCommInNrPc5,
1152 ApplicationToPathPreferenceMappingRules,
1153 EF_5G_PROSE_DD.ValidityTimer,
1154 ProSeIdToNrTxProfileForBroadcastAndGroupcastMappingRules]):
1155 pass
1156 def __init__(self, fid='4f03', sfid=0x03, name='EF.5G_PROSE_DC',
1157 desc='5G ProSe configuration data for direct communication', **kwargs):
1158 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
1159 # contains TLV structure despite being TransparentEF, not BER-TLV ?!?
1160 self._tlv = EF_5G_PROSE_DC.ProSeConfigForDirectCommunication
1161
1162# TS 31.102 Section 4.4.13.5 (Rel 17)
1163class EF_5G_PROSE_U2NRU(TransparentEF):
1164 class ProSeIdToDefaultDestL2Id(BER_TLV_IE, tag=0x8a):
1165 pass
1166 class RxcInfoList(BER_TLV_IE, tag=0x8b):
1167 pass
1168 class FiveQiToPc65QosParametersMappingRules(BER_TLV_IE, tag=0x8c):
1169 pass
1170 class ProSeIdToAppSrvAddrMappingRules(BER_TLV_IE, tag=0x8d):
1171 pass
1172 class UserInfoIdForDiscovery(BER_TLV_IE, tag=0x8e):
1173 pass
1174 class PrivacyTimer(BER_TLV_IE, tag=0x92):
1175 pass
1176 class FiveGPkkmfAddressInformation(BER_TLV_IE, tag=0x93):
1177 pass
1178 class ProSeConfigDataForUeToNetworkRelayUe(BER_TLV_IE, tag=0xA0,
1179 nested=[EF_5G_PROSE_DD.ServedByNgRan,
1180 EF_5G_PROSE_DD.NotServedByNgran,
1181 ProSeIdToDefaultDestL2Id,
1182 RxcInfoList,
1183 FiveQiToPc65QosParametersMappingRules,
1184 ProSeIdToAppSrvAddrMappingRules,
1185 EF_5G_PROSE_DD.ValidityTimer,
1186 UserInfoIdForDiscovery,
1187 PrivacyTimer,
1188 FiveGPkkmfAddressInformation]):
1189 pass
1190 def __init__(self, fid='4f04', sfid=0x04, name='EF.5G_PROSE_U2NRU',
1191 desc='5G ProSe configuration data for UE-to-network relay UE', **kwargs):
1192 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
1193 # contains TLV structure despite being TransparentEF, not BER-TLV ?!?
1194 self._tlv = EF_5G_PROSE_U2NRU.ProSeConfigDataForUeToNetworkRelayUe
1195
1196# TS 31.102 Section 4.4.13.6 (Rel 17)
1197class EF_5G_PROSE_RU(TransparentEF):
1198 class DefaultDestL2Ids(BER_TLV_IE, tag=0x8f):
1199 pass
1200 class N3IwfSelectionInfoFor5GProSeL3RemoteUE(BER_TLV_IE, tag=0x90):
1201 pass
1202 class ProSeConfigDataForRemoteUe(BER_TLV_IE, tag=0xa0,
1203 nested=[EF_5G_PROSE_DD.ServedByNgRan,
1204 EF_5G_PROSE_DD.NotServedByNgran,
1205 DefaultDestL2Ids,
1206 EF_5G_PROSE_U2NRU.RxcInfoList,
1207 N3IwfSelectionInfoFor5GProSeL3RemoteUE,
1208 EF_5G_PROSE_DD.ValidityTimer,
1209 EF_5G_PROSE_U2NRU.UserInfoIdForDiscovery,
1210 EF_5G_PROSE_U2NRU.PrivacyTimer,
1211 EF_5G_PROSE_U2NRU.FiveGPkkmfAddressInformation]):
1212 pass
1213 def __init__(self, fid='4f05', sfid=0x05, name='EF.5G_PROSE_RU',
1214 desc='5G ProSe configuration data for remote UE', **kwargs):
1215 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
1216 # contains TLV structure despite being TransparentEF, not BER-TLV ?!?
1217 self._tlv = EF_5G_PROSE_RU.ProSeConfigDataForRemoteUe
1218
1219# TS 31.102 Section 4.4.13.7 (Rel 17)
1220class EF_5G_PROSE_UIR(TransparentEF):
1221 class CollectionPeriod(BER_TLV_IE, tag=0x94):
1222 pass
1223 class ReportingWindow(BER_TLV_IE, tag=0x95):
1224 pass
1225 class ReportingIndicators(BER_TLV_IE, tag=0x96):
1226 pass
1227 class FiveGDdnmfCtfAddrForUploading(BER_TLV_IE, tag=0x97):
1228 pass
1229 class ProSeConfigDataForUeToNetworkRelayUE(BER_TLV_IE, tag=0xa0,
1230 nested=[EF_5G_PROSE_DD.ValidityTimer,
1231 CollectionPeriod, ReportingWindow,
1232 ReportingIndicators,
1233 FiveGDdnmfCtfAddrForUploading]):
1234 pass
1235 def __init__(self, fid='4f06', sfid=0x06, name='EF.5G_PROSE_UIR',
1236 desc='5G ProSe configuration data for usage information reporting', **kwargs):
1237 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
1238 # contains TLV structure despite being TransparentEF, not BER-TLV ?!?
1239 self._tlv = EF_5G_PROSE_UIR.ProSeConfigDataForUeToNetworkRelayUE
1240
1241# TS 31.102 Section 4.4.13 (Rel 17)
1242class DF_5G_ProSe(CardDF):
1243 def __init__(self, fid='5ff0', name='DF.5G_ProSe', desc='Files for 5G ProSe purpose', **kwargs):
1244 super().__init__(fid=fid, name=name, desc=desc, **kwargs)
1245 files = [
1246 EF_5G_PROSE_ST(),
1247 EF_5G_PROSE_DD(service=1),
1248 EF_5G_PROSE_DC(service=2),
1249 EF_5G_PROSE_U2NRU(service=3),
1250 EF_5G_PROSE_RU(service=4),
1251 EF_5G_PROSE_UIR(service=5),
1252 ]
1253 self.add_files(files)
1254
1255# TS 31.102 Section 4.4.11.18 (Rel 17)
1256class EF_5GSEDRX(TransparentEF):
1257 def __init__(self, fid='4f10', sfid=0x10, name='EF.5GSEDRX',
1258 desc='5GS eDRX Parameters', **kwargs):
1259 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
1260 self._construct = Struct('5gs_rat_type'/FlagsEnum(Byte, ng_ran=1, sat_ng_ran=2),
1261 'edrx_cycle_length'/Int8ub)
1262
1263# TS 31.102 Section 4.4.11.19 (Rel 17)
1264class EF_5GNSWO_CONF(TransparentEF):
1265 def __init__(self, fid='4f11', sfid=0x11, name='EF.5GNSWO_CONF',
1266 desc='5G Non-Seamless WLAN Offload configuration', **kwargs):
1267 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
1268 self._construct = Struct('5g_nswo_usage_ind'/Enum(Byte, disabled=0, enabled=1))
1269
1270# TS 31.102 Section 4.4.11.20 (Rel 17)
1271class EF_MCHPPLMN(TransparentEF):
Harald Welte24e77a72023-05-24 15:26:29 +02001272 def __init__(self, fid='4f15', sfid=0x15, name='EF.MCHPPLMN',
Harald Weltefc67de22023-05-23 20:29:49 +02001273 desc='Multiplier Coefficient for Higher Priority PLMN search', **kwargs):
1274 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
1275 self._construct = Struct('multiplier_coefficient'/Int8ub)
1276
1277# TS 31.102 Section 4.4.11.21 (Rel 17)
1278class EF_KAUSF_DERIVATION(TransparentEF):
1279 def __init__(self, fid='4f16', sfid=0x16, name='EF.KAUSF_DERIVATION',
1280 desc='K_AUSF derivation configuration', **kwargs):
1281 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
1282 self._construct = Struct('k_ausf_deriv_cfg'/FlagsEnum(Byte, use_msk=1), 'rfu'/HexAdapter(GreedyBytes))
1283
Harald Welte3990ebb2021-04-20 23:55:14 +02001284# TS 31.102 Section 4.4.5
1285class DF_WLAN(CardDF):
Harald Welte6169c722022-02-12 09:05:15 +01001286 def __init__(self, fid='5f40', name='DF.WLAN', desc='Files for WLAN purpose', **kwargs):
1287 super().__init__(fid=fid, name=name, desc=desc, **kwargs)
Harald Welte3990ebb2021-04-20 23:55:14 +02001288 files = [
Harald Welte419bb492022-02-12 21:39:35 +01001289 TransparentEF('4f41', 0x01, 'EF.Pseudo', 'Pseudonym', service=59),
Harald Weltec91085e2022-02-10 18:05:45 +01001290 TransparentEF('4f42', 0x02, 'EF.UPLMNWLAN',
Harald Welte419bb492022-02-12 21:39:35 +01001291 'User controlled PLMN selector for I-WLAN Access', service=60),
Harald Weltec91085e2022-02-10 18:05:45 +01001292 TransparentEF('4f43', 0x03, 'EF.OPLMNWLAN',
Harald Welte419bb492022-02-12 21:39:35 +01001293 'Operator controlled PLMN selector for I-WLAN Access', service=61),
Harald Weltec91085e2022-02-10 18:05:45 +01001294 LinFixedEF('4f44', 0x04, 'EF.UWSIDL',
Harald Welte419bb492022-02-12 21:39:35 +01001295 'User controlled WLAN Specific Identifier List', service=62),
Harald Weltec91085e2022-02-10 18:05:45 +01001296 LinFixedEF('4f45', 0x05, 'EF.OWSIDL',
Harald Welte419bb492022-02-12 21:39:35 +01001297 'Operator controlled WLAN Specific Identifier List', service=63),
Harald Weltec91085e2022-02-10 18:05:45 +01001298 TransparentEF('4f46', 0x06, 'EF.WRI',
Harald Welte419bb492022-02-12 21:39:35 +01001299 'WLAN Reauthentication Identity', service=66),
Harald Weltec91085e2022-02-10 18:05:45 +01001300 LinFixedEF('4f47', 0x07, 'EF.HWSIDL',
Harald Welte419bb492022-02-12 21:39:35 +01001301 'Home I-WLAN Specific Identifier List', service=81),
Harald Weltec91085e2022-02-10 18:05:45 +01001302 TransparentEF('4f48', 0x08, 'EF.WEHPLMNPI',
Harald Welte419bb492022-02-12 21:39:35 +01001303 'I-WLAN Equivalent HPLMN Presentation Indication', service=82),
Harald Weltec91085e2022-02-10 18:05:45 +01001304 TransparentEF('4f49', 0x09, 'EF.WHPI',
Harald Welte419bb492022-02-12 21:39:35 +01001305 'I-WLAN HPLMN Priority Indication', service=83),
Harald Weltec91085e2022-02-10 18:05:45 +01001306 TransparentEF('4f4a', 0x0a, 'EF.WLRPLMN',
Harald Welte419bb492022-02-12 21:39:35 +01001307 'I-WLAN Last Registered PLMN', service=84),
Harald Weltec91085e2022-02-10 18:05:45 +01001308 TransparentEF('4f4b', 0x0b, 'EF.HPLMNDAI',
Harald Welte419bb492022-02-12 21:39:35 +01001309 'HPLMN Direct Access Indicator', service=88),
Harald Weltec91085e2022-02-10 18:05:45 +01001310 ]
Harald Welte3990ebb2021-04-20 23:55:14 +02001311 self.add_files(files)
1312
1313# TS 31.102 Section 4.4.6
1314class DF_HNB(CardDF):
Harald Welte6169c722022-02-12 09:05:15 +01001315 def __init__(self, fid='5f50', name='DF.HNB', desc='Files for HomeNodeB purpose', **kwargs):
1316 super().__init__(fid=fid, name=name, desc=desc, **kwargs)
Harald Welte3990ebb2021-04-20 23:55:14 +02001317 files = [
Harald Welteeb882052022-07-17 21:13:57 +02001318 LinFixedEF('4f81', 0x01, 'EF.ACSGL', 'Allowed CSG Lists', service=86),
1319 LinFixedEF('4f82', 0x02, 'EF.CSGTL', 'CSG Types', service=86),
1320 LinFixedEF('4f83', 0x03, 'EF.HNBN', 'Home NodeB Name', service=86),
1321 LinFixedEF('4f84', 0x04, 'EF.OCSGL', 'Operator CSG Lists', service=90),
1322 LinFixedEF('4f85', 0x05, 'EF.OCSGT', 'Operator CSG Type', service=90),
1323 LinFixedEF('4f86', 0x06, 'EF.OHNBN', 'Operator Home NodeB Name', service=90),
Harald Weltec91085e2022-02-10 18:05:45 +01001324 ]
Harald Welte3990ebb2021-04-20 23:55:14 +02001325 self.add_files(files)
1326
1327# TS 31.102 Section 4.4.8
1328class DF_ProSe(CardDF):
Harald Welte6169c722022-02-12 09:05:15 +01001329 def __init__(self, fid='5f90', name='DF.ProSe', desc='Files for ProSe purpose', **kwargs):
1330 super().__init__(fid=fid, name=name, desc=desc, **kwargs)
Harald Welte3990ebb2021-04-20 23:55:14 +02001331 files = [
Harald Weltec91085e2022-02-10 18:05:45 +01001332 LinFixedEF('4f01', 0x01, 'EF.PROSE_MON',
1333 'ProSe Monitoring Parameters'),
1334 LinFixedEF('4f02', 0x02, 'EF.PROSE_ANN',
1335 'ProSe Announcing Parameters'),
Harald Welte3990ebb2021-04-20 23:55:14 +02001336 LinFixedEF('4f03', 0x03, 'EF.PROSEFUNC', 'HPLMN ProSe Function'),
Harald Weltec91085e2022-02-10 18:05:45 +01001337 TransparentEF('4f04', 0x04, 'EF.PROSE_RADIO_COM',
1338 'ProSe Direct Communication Radio Parameters'),
1339 TransparentEF('4f05', 0x05, 'EF.PROSE_RADIO_MON',
1340 'ProSe Direct Discovery Monitoring Radio Parameters'),
1341 TransparentEF('4f06', 0x06, 'EF.PROSE_RADIO_ANN',
1342 'ProSe Direct Discovery Announcing Radio Parameters'),
1343 LinFixedEF('4f07', 0x07, 'EF.PROSE_POLICY',
1344 'ProSe Policy Parameters'),
Harald Welte3990ebb2021-04-20 23:55:14 +02001345 LinFixedEF('4f08', 0x08, 'EF.PROSE_PLMN', 'ProSe PLMN Parameters'),
1346 TransparentEF('4f09', 0x09, 'EF.PROSE_GC', 'ProSe Group Counter'),
1347 TransparentEF('4f10', 0x10, 'EF.PST', 'ProSe Service Table'),
Harald Weltec91085e2022-02-10 18:05:45 +01001348 TransparentEF('4f11', 0x11, 'EF.UIRC',
1349 'ProSe UsageInformationReportingConfiguration'),
1350 LinFixedEF('4f12', 0x12, 'EF.PROSE_GM_DISCOVERY',
1351 'ProSe Group Member Discovery Parameters'),
1352 LinFixedEF('4f13', 0x13, 'EF.PROSE_RELAY',
1353 'ProSe Relay Parameters'),
1354 TransparentEF('4f14', 0x14, 'EF.PROSE_RELAY_DISCOVERY',
1355 'ProSe Relay Discovery Parameters'),
1356 ]
Harald Welte3990ebb2021-04-20 23:55:14 +02001357 self.add_files(files)
1358
Harald Weltec91085e2022-02-10 18:05:45 +01001359
Merlin Chlosta05ca36b2021-04-01 16:15:28 +02001360class DF_USIM_5GS(CardDF):
Harald Welte6169c722022-02-12 09:05:15 +01001361 def __init__(self, fid='5FC0', name='DF.5GS', desc='5GS related files', **kwargs):
1362 super().__init__(fid=fid, name=name, desc=desc, **kwargs)
Merlin Chlosta05ca36b2021-04-01 16:15:28 +02001363 files = [
Harald Weltec91085e2022-02-10 18:05:45 +01001364 # I'm looking at 31.102 R16.6
Harald Welte419bb492022-02-12 21:39:35 +01001365 EF_5GS3GPPLOCI(service=122),
Harald Weltec91085e2022-02-10 18:05:45 +01001366 EF_5GS3GPPLOCI('4f02', 0x02, 'EF.5GSN3GPPLOCI',
Harald Welte28accc82023-10-18 23:21:46 +02001367 desc='5GS non-3GPP location information', service=122),
Harald Welte419bb492022-02-12 21:39:35 +01001368 EF_5GS3GPPNSC(service=122),
Harald Weltec91085e2022-02-10 18:05:45 +01001369 EF_5GS3GPPNSC('4f04', 0x04, 'EF.5GSN3GPPNSC',
Harald Welte28accc82023-10-18 23:21:46 +02001370 desc='5GS non-3GPP Access NAS Security Context', service=122),
Harald Welte419bb492022-02-12 21:39:35 +01001371 EF_5GAUTHKEYS(service=123),
1372 EF_UAC_AIC(service=126),
1373 EF_SUCI_Calc_Info(service=124),
1374 EF_OPL5G(service=129),
1375 EF_SUPI_NAI(service=130),
Harald Welte455611c2023-05-27 12:48:54 +02001376 EF_Routing_Indicator(service=124),
Harald Weltec91085e2022-02-10 18:05:45 +01001377 TransparentEF('4F0B', 0x0b, 'EF.URSP',
Harald Welte28accc82023-10-18 23:21:46 +02001378 desc='UE Route Selector Policies per PLMN', service=132),
Harald Welte419bb492022-02-12 21:39:35 +01001379 EF_TN3GPPSNN(service=133),
Harald Weltefc67de22023-05-23 20:29:49 +02001380 # Rel-17 additions below
1381 EF_CAG(service=137),
1382 EF_SOR_CMCI(service=138),
1383 EF_DRI(service=140),
1384 EF_5GSEDRX(service=141),
1385 EF_5GNSWO_CONF(service=142),
1386 EF_MCHPPLMN(service=144),
1387 EF_KAUSF_DERIVATION(service=145),
Merlin Chlosta05ca36b2021-04-01 16:15:28 +02001388 ]
Merlin Chlosta05ca36b2021-04-01 16:15:28 +02001389 self.add_files(files)
1390
Harald Weltec91085e2022-02-10 18:05:45 +01001391
Harald Welte2bee70c2023-05-25 09:14:28 +02001392class DF_SAIP(CardDF):
1393 """This is not really TS 31.102 but part of the eUICC Profile Package: Interoperable Format Technical
1394 Specification as released by TCA (formerly SIMalliance)"""
1395 def __init__(self, fid='5FD0', name='DF.SAIP', desc='SIMalliance Interoperable Profile', **kwargs):
1396 super().__init__(fid=fid, name=name, desc=desc, **kwargs)
1397 files = [
1398 # uses the same file format as DF.5GS/EF_SUCI_Calc_Info, but different FID
1399 EF_SUCI_Calc_Info(fid='4f01')
1400 ]
1401 self.add_files(files)
1402
1403
Harald Welteb2edd142021-01-08 23:29:35 +01001404class ADF_USIM(CardADF):
Philipp Maiera1850ae2023-10-25 18:05:09 +02001405 def __init__(self, aid='a0000000871002', has_fs=True, name='ADF.USIM', fid=None, sfid=None,
Harald Welteb2edd142021-01-08 23:29:35 +01001406 desc='USIM Application'):
Philipp Maiera1850ae2023-10-25 18:05:09 +02001407 super().__init__(aid=aid, has_fs=has_fs, fid=fid, sfid=sfid, name=name, desc=desc)
Harald Welte15fae982021-04-10 10:22:27 +02001408 # add those commands to the general commands of a TransparentEF
1409 self.shell_commands += [self.AddlShellCommands()]
Harald Welteb2edd142021-01-08 23:29:35 +01001410
1411 files = [
Harald Weltec91085e2022-02-10 18:05:45 +01001412 EF_LI(sfid=0x02),
1413 EF_IMSI(sfid=0x07),
1414 EF_Keys(),
1415 EF_Keys('6f09', 0x09, 'EF.KeysPS',
1416 desc='Ciphering and Integrity Keys for PS domain'),
1417 EF_xPLMNwAcT('6f60', 0x0a, 'EF.PLMNwAcT',
Harald Welte509ecf82023-10-18 23:32:57 +02001418 desc='User controlled PLMN Selector with Access Technology', service=20),
Harald Weltec91085e2022-02-10 18:05:45 +01001419 EF_HPPLMN(),
Harald Welte6169c722022-02-12 09:05:15 +01001420 EF_ACMmax(service=13),
Harald Welte6ca2fa72022-02-12 16:29:31 +01001421 EF_UST(),
Harald Weltec91085e2022-02-10 18:05:45 +01001422 CyclicEF('6f39', None, 'EF.ACM',
Harald Welte509ecf82023-10-18 23:32:57 +02001423 desc='Accumulated call meter', rec_len=(3, 3), service=13),
1424 TransparentEF('6f3e', None, 'EF.GID1', desc='Group Identifier Level 1', service=17),
1425 TransparentEF('6f3f', None, 'EF.GID2', desc='Group Identifier Level 2', service=18),
Harald Welte6169c722022-02-12 09:05:15 +01001426 EF_SPN(service=19),
Harald Weltec91085e2022-02-10 18:05:45 +01001427 TransparentEF('6f41', None, 'EF.PUCT',
Harald Welte509ecf82023-10-18 23:32:57 +02001428 desc='Price per unit and currency table', size=(5, 5), service=13),
Harald Welte6169c722022-02-12 09:05:15 +01001429 EF_CBMI(service=15),
Harald Weltec91085e2022-02-10 18:05:45 +01001430 EF_ACC(sfid=0x06),
Harald Welte509ecf82023-10-18 23:32:57 +02001431 EF_PLMNsel('6f7b', 0x0d, 'EF.FPLMN', desc='Forbidden PLMNs', size=(12, None)),
Harald Weltec91085e2022-02-10 18:05:45 +01001432 EF_LOCI(),
1433 EF_AD(),
Harald Welte6169c722022-02-12 09:05:15 +01001434 EF_CBMID(sfid=0x0e, service=29),
Harald Weltec91085e2022-02-10 18:05:45 +01001435 EF_ECC(),
Harald Welte6169c722022-02-12 09:05:15 +01001436 EF_CBMIR(service=16),
Harald Weltec91085e2022-02-10 18:05:45 +01001437 EF_PSLOCI(),
Harald Welte509ecf82023-10-18 23:32:57 +02001438 EF_ADN('6f3b', None, 'EF.FDN', desc='Fixed Dialling Numbers', service=[2, 89], ext=2),
Harald Welte6169c722022-02-12 09:05:15 +01001439 EF_SMS('6f3c', None, service=10),
1440 EF_MSISDN(service=21),
1441 EF_SMSP(service=12),
1442 EF_SMSS(service=10),
Harald Welte509ecf82023-10-18 23:32:57 +02001443 EF_ADN('6f49', None, 'EF.SDN', desc='Service Dialling Numbers', service=[4, 89], ext=3),
1444 EF_EXT('6f4b', None, 'EF.EXT2', desc='Extension2 (FDN)', service=3),
1445 EF_EXT('6f4c', None, 'EF.EXT3', desc='Extension2 (SDN)', service=5),
Harald Welte6169c722022-02-12 09:05:15 +01001446 EF_SMSR(service=11),
1447 EF_ICI(service=9),
1448 EF_OCI(service=8),
1449 EF_ICT(service=9),
Harald Welte509ecf82023-10-18 23:32:57 +02001450 EF_ICT('6f83', None, 'EF.OCT', desc='Outgoing Call Timer', service=8),
1451 EF_EXT('6f4e', None, 'EF.EXT5', desc='Extension5 (ICI/OCI/MSISDN)', service=44),
Harald Welte6169c722022-02-12 09:05:15 +01001452 EF_CCP2(service=14),
1453 EF_eMLPP(service=24),
1454 EF_AAeM(service=25),
Harald Weltec91085e2022-02-10 18:05:45 +01001455 # EF_Hiddenkey
Harald Welte509ecf82023-10-18 23:32:57 +02001456 EF_ADN('6f4d', None, 'EF.BDN', desc='Barred Dialling Numbers', service=6, ext=4),
1457 EF_EXT('6f55', None, 'EF.EXT4', desc='Extension4 (BDN/SSC)', service=7),
Harald Welte6169c722022-02-12 09:05:15 +01001458 EF_CMI(service=6),
Harald Welte6ca2fa72022-02-12 16:29:31 +01001459 EF_EST(service=[2, 6, 34, 35]),
Harald Welte6169c722022-02-12 09:05:15 +01001460 EF_ACL(service=35),
1461 EF_DCK(service=36),
1462 EF_CNL(service=37),
Harald Weltec91085e2022-02-10 18:05:45 +01001463 EF_START_HFN(),
1464 EF_THRESHOLD(),
Harald Welte509ecf82023-10-18 23:32:57 +02001465 EF_xPLMNwAcT('6f61', 0x11, 'EF.OPLMNwAcT', desc='User controlled PLMN Selector with Access Technology', service=42),
1466 EF_xPLMNwAcT('6f62', 0x13, 'EF.HPLMNwAcT', desc='HPLMN Selector with Access Technology', service=43),
Harald Weltec91085e2022-02-10 18:05:45 +01001467 EF_ARR('6f06', 0x17),
Harald Welte363edd92022-07-17 22:24:03 +02001468 EF_RPLMNAcT(),
Harald Welte509ecf82023-10-18 23:32:57 +02001469 TransparentEF('6fc4', None, 'EF.NETPAR', desc='Network Parameters'),
Harald Welte6169c722022-02-12 09:05:15 +01001470 EF_PNN('6fc5', 0x19, service=45),
1471 EF_OPL(service=46),
Harald Welte509ecf82023-10-18 23:32:57 +02001472 EF_ADN('6fc7', None, 'EF.MBDN', desc='Mailbox Dialling Numbers', service=47, ext=6),
1473 EF_EXT('6fc8', None, 'EF.EXT6', desc='Extension6 (MBDN)'),
Harald Welte6169c722022-02-12 09:05:15 +01001474 EF_MBI(service=47),
1475 EF_MWIS(service=48),
Harald Welte53762512023-12-21 20:16:17 +01001476 EF_CFIS(service=49, ext=7),
Harald Welte509ecf82023-10-18 23:32:57 +02001477 EF_EXT('6fcc', None, 'EF.EXT7', desc='Extension7 (CFIS)'),
1478 TransparentEF('6fcd', None, 'EF.SPDI', desc='Service Provider Display Information', service=51),
Harald Welte6169c722022-02-12 09:05:15 +01001479 EF_MMSN(service=52),
Harald Welte509ecf82023-10-18 23:32:57 +02001480 EF_EXT('6fcf', None, 'EF.EXT8', desc='Extension8 (MMSN)', service=53),
Harald Welte6169c722022-02-12 09:05:15 +01001481 EF_MMSICP(service=52),
1482 EF_MMSUP(service=52),
1483 EF_MMSUCP(service=(52, 55)),
Harald Welte04bd5142023-05-24 15:23:53 +02001484 EF_NIA(service=56, fid='6fd3'),
Harald Welte6169c722022-02-12 09:05:15 +01001485 EF_VGCS(service=57),
1486 EF_VGCSS(service=57),
Harald Welte509ecf82023-10-18 23:32:57 +02001487 EF_VGCS('6fb3', None, 'EF.VBS', desc='Voice Broadcast Service', service=58),
1488 EF_VGCSS('6fb4', None, 'EF.VBSS', desc='Voice Broadcast Service Status', service=58),
Harald Welte6169c722022-02-12 09:05:15 +01001489 EF_VGCSCA(service=64),
Harald Welte509ecf82023-10-18 23:32:57 +02001490 EF_VGCSCA('6fd5', None, 'EF.VBCSCA', desc='Voice Broadcast Service Ciphering Algorithm', service=65),
Harald Welte6169c722022-02-12 09:05:15 +01001491 EF_GBABP(service=68),
1492 EF_MSK(service=69),
1493 EF_MUK(service=69),
1494 EF_GBANL(service=68),
Harald Welte509ecf82023-10-18 23:32:57 +02001495 EF_PLMNsel('6fd9', 0x1d, 'EF.EHPLMN', desc='Equivalent HPLMN', size=(12, None), service=71),
Harald Welte6169c722022-02-12 09:05:15 +01001496 EF_EHPLMNPI(service=(71, 73)),
1497 # EF_LRPLMNSI ('6fdc', service=74)
1498 EF_NAFKCA(service=(68, 76)),
Harald Welte509ecf82023-10-18 23:32:57 +02001499 TransparentEF('6fde', None, 'EF.SPNI', desc='Service Provider Name Icon', service=78),
1500 LinFixedEF('6fdf', None, 'EF.PNNI', desc='PLMN Network Name Icon', service=79),
Harald Welte6169c722022-02-12 09:05:15 +01001501 EF_NCP_IP(service=80),
Harald Welte509ecf82023-10-18 23:32:57 +02001502 EF_EPSLOCI('6fe3', 0x1e, 'EF.EPSLOCI', desc='EPS location information', service=85),
Harald Welte6169c722022-02-12 09:05:15 +01001503 EF_EPSNSC(service=85),
Harald Welte324175f2023-12-21 20:25:30 +01001504 # EF.UFC Test data: 801e60c01e900080040000000000000000f0000000004000000000000080
Harald Welte509ecf82023-10-18 23:32:57 +02001505 TransparentEF('6fe6', None, 'EF.UFC', desc='USAT Facility Control', size=(1, 16)),
1506 TransparentEF('6fe8', None, 'EF.NASCONFIG', desc='Non Access Stratum Configuration', service=96),
Harald Welte6169c722022-02-12 09:05:15 +01001507 # UICC IARI (only in cards that have no ISIM) service=95
1508 EF_PWS(service=97),
Harald Welte509ecf82023-10-18 23:32:57 +02001509 LinFixedEF('6fed', None, 'EF.FDNURI', desc='Fixed Dialling Numbers URI', service=(2, 99)),
1510 LinFixedEF('6fee', None, 'EF.BDNURI', desc='Barred Dialling Numbers URI', service=(6, 99)),
1511 LinFixedEF('6fef', None, 'EF.SDNURI', desc='Service Dialling Numbers URI', service=(4, 99)),
Harald Welte6169c722022-02-12 09:05:15 +01001512 # EF_IWL (IMEI(SV) White List)
Harald Weltec91085e2022-02-10 18:05:45 +01001513 EF_IPS(),
Harald Welte6169c722022-02-12 09:05:15 +01001514 EF_ePDGId(service=(106, 107)),
Harald Weltecdfe1c22023-12-08 12:30:21 +01001515 EF_ePDGSelection(service=(106, 107)),
Harald Welte5277b5c2023-12-08 12:22:28 +01001516 EF_ePDGId('6ff5', None, 'EF.ePDGIdEm', desc='Emergency ePDG Identifier', service=(110, 111)),
Harald Weltecdfe1c22023-12-08 12:30:21 +01001517 EF_ePDGSelection('6ff6', None, 'EF.ePDGSelectionEm',
1518 desc='ePDG Selection Information for Emergency Services', service=(110, 111)),
Harald Welte6169c722022-02-12 09:05:15 +01001519 EF_FromPreferred(service=114),
Harald Weltefc67de22023-05-23 20:29:49 +02001520 EF_eAKA(),
Harald Welte6169c722022-02-12 09:05:15 +01001521 # FIXME: DF_SoLSA service=23
Harald Weltede4c14c2022-07-16 11:53:59 +02001522 DF_PHONEBOOK(),
Harald Welted90ceb82022-07-17 22:10:58 +02001523 DF_GSM_ACCESS(),
Harald Welte6169c722022-02-12 09:05:15 +01001524 DF_WLAN(service=[59, 60, 61, 62, 63, 66, 81, 82, 83, 84, 88]),
1525 DF_HNB(service=[86, 90]),
1526 DF_ProSe(service=101),
1527 # FIXME: DF_ACDC service=108
1528 # FIXME: DF_TV service=116
1529 DF_USIM_5GS(service=[122, 123, 124, 125, 126, 127, 129, 130]),
Harald Weltefc67de22023-05-23 20:29:49 +02001530 DF_SNPN(service=[143,146]),
1531 DF_5G_ProSe(service=139),
Harald Welte2bee70c2023-05-25 09:14:28 +02001532 DF_SAIP(),
Harald Weltec91085e2022-02-10 18:05:45 +01001533 ]
Harald Welteb2edd142021-01-08 23:29:35 +01001534 self.add_files(files)
1535
1536 def decode_select_response(self, data_hex):
Philipp Maier5998a3a2021-11-16 15:16:39 +01001537 return pySim.ts_102_221.CardProfileUICC.decode_select_response(data_hex)
Harald Welteb2edd142021-01-08 23:29:35 +01001538
Harald Welte15fae982021-04-10 10:22:27 +02001539 @with_default_category('Application-Specific Commands')
1540 class AddlShellCommands(CommandSet):
1541 def __init__(self):
1542 super().__init__()
1543
1544 authenticate_parser = argparse.ArgumentParser()
1545 authenticate_parser.add_argument('rand', help='Random challenge')
1546 authenticate_parser.add_argument('autn', help='Authentication Nonce')
1547 #authenticate_parser.add_argument('--context', help='Authentication context', default='3G')
Harald Weltec91085e2022-02-10 18:05:45 +01001548
Harald Welte15fae982021-04-10 10:22:27 +02001549 @cmd2.with_argparser(authenticate_parser)
1550 def do_authenticate(self, opts):
1551 """Perform Authentication and Key Agreement (AKA)."""
Harald Welte46255122023-10-21 23:40:42 +02001552 (data, sw) = self._cmd.lchan.scc.authenticate(opts.rand, opts.autn)
Harald Welte15fae982021-04-10 10:22:27 +02001553 self._cmd.poutput_json(data)
1554
Harald Welte12af7932022-02-15 16:39:08 +01001555 term_prof_parser = argparse.ArgumentParser()
1556 term_prof_parser.add_argument('PROFILE', help='Hexstring of encoded terminal profile')
1557
1558 @cmd2.with_argparser(term_prof_parser)
Harald Welte51b3abb2022-07-30 16:30:33 +02001559 def do_terminal_profile(self, opts):
Harald Welte12af7932022-02-15 16:39:08 +01001560 """Send a TERMINAL PROFILE command to the card.
1561 This is used to inform the card about which optional
1562 features the terminal (modem/phone) supports, particularly
1563 in the context of SIM Toolkit, Proactive SIM and OTA. You
1564 must specify a hex-string with the encoded terminal profile
1565 you want to send to the card."""
Harald Welte46255122023-10-21 23:40:42 +02001566 (data, sw) = self._cmd.lchan.scc.terminal_profile(opts.PROFILE)
Harald Welte846a8982021-10-08 15:47:16 +02001567 self._cmd.poutput('SW: %s, data: %s' % (sw, data))
Harald Welte15fae982021-04-10 10:22:27 +02001568
Harald Welte12af7932022-02-15 16:39:08 +01001569 envelope_parser = argparse.ArgumentParser()
1570 envelope_parser.add_argument('PAYLOAD', help='Hexstring of encoded payload to ENVELOPE')
1571
1572 @cmd2.with_argparser(envelope_parser)
Harald Welte51b3abb2022-07-30 16:30:33 +02001573 def do_envelope(self, opts):
Harald Welte12af7932022-02-15 16:39:08 +01001574 """Send an ENVELOPE command to the card. This is how a
1575 variety of information is communicated from the terminal
1576 (modem/phone) to the card, particularly in the context of
1577 SIM Toolkit, Proactive SIM and OTA."""
Harald Welte46255122023-10-21 23:40:42 +02001578 (data, sw) = self._cmd.lchan.scc.envelope(opts.PAYLOAD)
Harald Welte7cb94e42021-10-08 15:47:57 +02001579 self._cmd.poutput('SW: %s, data: %s' % (sw, data))
1580
Harald Welte12af7932022-02-15 16:39:08 +01001581 envelope_sms_parser = argparse.ArgumentParser()
1582 envelope_sms_parser.add_argument('TPDU', help='Hexstring of encoded SMS TPDU')
1583
1584 @cmd2.with_argparser(envelope_sms_parser)
Harald Welte51b3abb2022-07-30 16:30:33 +02001585 def do_envelope_sms(self, opts):
Harald Welte12af7932022-02-15 16:39:08 +01001586 """Send an ENVELOPE(SMS-PP-Download) command to the card.
1587 This emulates a terminal (modem/phone) having received a SMS
1588 with a PID of 'SMS for the SIM card'. You can use this
1589 command in the context of testing OTA related features
Philipp Maier4e5aa302023-06-06 19:22:19 +02001590 without a modem/phone or a cellular network."""
Harald Welte7cb94e42021-10-08 15:47:57 +02001591 tpdu_ie = SMS_TPDU()
Harald Welte51b3abb2022-07-30 16:30:33 +02001592 tpdu_ie.from_bytes(h2b(opts.TPDU))
Harald Weltec91085e2022-02-10 18:05:45 +01001593 dev_ids = DeviceIdentities(
1594 decoded={'source_dev_id': 'network', 'dest_dev_id': 'uicc'})
Harald Welte7cb94e42021-10-08 15:47:57 +02001595 sms_dl = SMSPPDownload(children=[dev_ids, tpdu_ie])
Harald Welte46255122023-10-21 23:40:42 +02001596 (data, sw) = self._cmd.lchan.scc.envelope(b2h(sms_dl.to_tlv()))
Harald Welte7cb94e42021-10-08 15:47:57 +02001597 self._cmd.poutput('SW: %s, data: %s' % (sw, data))
1598
Harald Welte7ec82232023-06-06 18:15:52 +02001599 get_id_parser = argparse.ArgumentParser()
1600 get_id_parser.add_argument("--nswo-context", action='store_true')
1601
1602 @cmd2.with_argparser(get_id_parser)
1603 def do_get_identity(self, opts):
1604 """Send a GET IDENTITY command to the card. This is part of the
1605 procedure for "SUCI calculation performed on USIM" supported
1606 by USIM with support for both EF.UST service 124 and 125."""
1607 context = 0x01 # SUCI
1608 if opts.nswo_context:
1609 context = 0x02 # SUCI 5G NSWO
Harald Welte46255122023-10-21 23:40:42 +02001610 (data, sw) = self._cmd.lchan.scc.get_identity(context)
Harald Welte7ec82232023-06-06 18:15:52 +02001611 do = SUCI_TlvDataObject()
1612 do.from_tlv(h2b(data))
1613 do_d = do.to_dict()
1614 self._cmd.poutput('SUCI TLV Data Object: %s' % do_d['suci__tlv_data_object'])
1615
Harald Welte15fae982021-04-10 10:22:27 +02001616
Harald Welteb2edd142021-01-08 23:29:35 +01001617# TS 31.102 Section 7.3
1618sw_usim = {
1619 'Security management': {
1620 '9862': 'Authentication error, incorrect MAC',
1621 '9864': 'Authentication error, security context not supported',
1622 '9865': 'Key freshness failure',
1623 '9866': 'Authentication error, no memory space available',
1624 '9867': 'Authentication error, no memory space available in EF MUK',
1625 }
1626}
1627
Harald Weltec91085e2022-02-10 18:05:45 +01001628
Philipp Maier57f65ee2021-10-18 14:09:02 +02001629class CardApplicationUSIM(CardApplication):
1630 def __init__(self):
Harald Weltec91085e2022-02-10 18:05:45 +01001631 super().__init__('USIM', adf=ADF_USIM(), sw=sw_usim)