blob: 74a2c4c89dd149e91b14c2a8d914e7f317e16b02 [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
34from pySim.ts_51_011 import EF_CBMID, EF_CBMIR, EF_ADN, EF_SMS, EF_MSISDN, EF_SMSP, EF_SMSS
35from 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 Welte13edf302022-07-21 15:19:23 +0200299 def __init__(self, fid="4f07", sfid=0x07, name='EF.SUCI_Calc_Info', size=(2, None),
Harald Welte419bb492022-02-12 21:39:35 +0100300 desc='SUCI Calc Info', **kwargs):
301 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200302
303 def _encode_prot_scheme_id_list(self, in_list):
304 out_bytes = [0xa0]
Harald Weltec91085e2022-02-10 18:05:45 +0100305 out_bytes.append(len(in_list)*2) # two byte per entry
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200306
307 # position in list determines priority; high-priority items (low index) come first
308 for scheme in sorted(in_list, key=lambda item: item["priority"]):
309 out_bytes.append(scheme["identifier"])
310 out_bytes.append(scheme["key_index"])
311
312 return out_bytes
313
314 def _encode_hnet_pubkey_list(self, hnet_pubkey_list):
Harald Weltec91085e2022-02-10 18:05:45 +0100315 out_bytes = [0xa1] # pubkey list tag
316 out_bytes.append(0x00) # length filled later
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200317 length = 0
318
319 for key in hnet_pubkey_list:
Harald Weltec91085e2022-02-10 18:05:45 +0100320 out_bytes.append(0x80) # identifier tag
321 out_bytes.append(0x01) # TODO size, fixed to 1 byte
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200322 out_bytes.append(key["hnet_pubkey_identifier"])
Harald Weltec91085e2022-02-10 18:05:45 +0100323 out_bytes.append(0x81) # key tag
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200324 out_bytes.append(len(key["hnet_pubkey"])//2)
325 length += 5+len(key["hnet_pubkey"])//2
326
327 pubkey_bytes = h2b(key["hnet_pubkey"])
328 out_bytes += pubkey_bytes
329
330 # fill length
331 out_bytes[1] = length
332 return out_bytes
333
334 def _encode_hex(self, in_json):
Harald Weltec91085e2022-02-10 18:05:45 +0100335 out_bytes = self._encode_prot_scheme_id_list(
336 in_json['prot_scheme_id_list'])
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200337 out_bytes += self._encode_hnet_pubkey_list(in_json['hnet_pubkey_list'])
338 return "".join(["%02X" % i for i in out_bytes])
339
340 def _decode_prot_scheme_id_list(self, in_bytes):
341 prot_scheme_id_list = []
342 pos = 0
343 # two bytes per entry
344 while pos < len(in_bytes):
345 prot_scheme = {
Harald Weltec91085e2022-02-10 18:05:45 +0100346 'priority': pos//2, # first in list: high priority
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200347 'identifier': in_bytes[pos],
348 'key_index': in_bytes[pos+1]
349 }
350 pos += 2
351 prot_scheme_id_list.append(prot_scheme)
352 return prot_scheme_id_list
353
354 def _decode_hnet_pubkey_list(self, in_bytes):
355 hnet_pubkey_list = []
356 pos = 0
357 if in_bytes[pos] != 0xa1:
358 print("missing Home Network Public Key List data object")
359 return {}
360 pos += 1
361 hnet_pubkey_list_len = in_bytes[pos]
362 pos += 1
363
364 while pos < hnet_pubkey_list_len:
365 if in_bytes[pos] != 0x80:
366 print("missing Home Network Public Key Identifier tag")
367 return {}
368 pos += 1
Harald Weltec91085e2022-02-10 18:05:45 +0100369 # TODO might be more than 1 byte?
370 hnet_pubkey_id_len = in_bytes[pos]
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200371 pos += 1
372 hnet_pubkey_id = in_bytes[pos:pos+hnet_pubkey_id_len][0]
373 pos += hnet_pubkey_id_len
374 if in_bytes[pos] != 0x81:
375 print("missing Home Network Public Key tag")
376 return {}
377 pos += 1
378 hnet_pubkey_len = in_bytes[pos]
379 pos += 1
380 hnet_pubkey = in_bytes[pos:pos+hnet_pubkey_len]
381 pos += hnet_pubkey_len
382
383 hnet_pubkey_list.append({
384 'hnet_pubkey_identifier': hnet_pubkey_id,
385 'hnet_pubkey': b2h(hnet_pubkey)
386 })
387
388 return hnet_pubkey_list
389
390 def _decode_bin(self, in_bin):
Vadim Yanitskiy5e41eeb2021-05-02 02:20:33 +0200391 return self._decode_hex(b2h(in_bin))
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200392
393 def _decode_hex(self, in_hex):
394 in_bytes = h2b(in_hex)
395 pos = 0
396
397 if in_bytes[pos] != 0xa0:
398 print("missing Protection Scheme Identifier List data object tag")
399 return {}
400 pos += 1
401
Harald Weltec91085e2022-02-10 18:05:45 +0100402 prot_scheme_id_list_len = in_bytes[pos] # TODO maybe more than 1 byte
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200403 pos += 1
404 # decode Protection Scheme Identifier List data object
Harald Weltec91085e2022-02-10 18:05:45 +0100405 prot_scheme_id_list = self._decode_prot_scheme_id_list(
406 in_bytes[pos:pos+prot_scheme_id_list_len])
Merlin Chlosta05ca36b2021-04-01 16:15:28 +0200407 pos += prot_scheme_id_list_len
408
409 # remaining data holds Home Network Public Key Data Object
410 hnet_pubkey_list = self._decode_hnet_pubkey_list(in_bytes[pos:])
411
412 return {
413 'prot_scheme_id_list': prot_scheme_id_list,
414 'hnet_pubkey_list': hnet_pubkey_list
415 }
416
417 def _encode_bin(self, in_json):
418 return h2b(self._encode_hex(in_json))
419
Harald Weltec91085e2022-02-10 18:05:45 +0100420
Harald Welteb2edd142021-01-08 23:29:35 +0100421class EF_LI(TransRecEF):
Harald Welte13edf302022-07-21 15:19:23 +0200422 def __init__(self, fid='6f05', sfid=None, name='EF.LI', size=(2, None), rec_len=2,
Harald Welteb2edd142021-01-08 23:29:35 +0100423 desc='Language Indication'):
424 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, rec_len=rec_len)
Harald Weltec91085e2022-02-10 18:05:45 +0100425
Harald Weltef6b37af2023-01-24 15:42:26 +0100426 def _decode_record_bin(self, in_bin, **kwargs):
Harald Welteb2edd142021-01-08 23:29:35 +0100427 if in_bin == b'\xff\xff':
428 return None
429 else:
430 # officially this is 7-bit GSM alphabet with one padding bit in each byte
431 return in_bin.decode('ascii')
Harald Weltec91085e2022-02-10 18:05:45 +0100432
Harald Weltef6b37af2023-01-24 15:42:26 +0100433 def _encode_record_bin(self, in_json, **kwargs):
Harald Welteb2edd142021-01-08 23:29:35 +0100434 if in_json == None:
435 return b'\xff\xff'
436 else:
437 # officially this is 7-bit GSM alphabet with one padding bit in each byte
438 return in_json.encode('ascii')
439
Harald Weltec91085e2022-02-10 18:05:45 +0100440
Harald Welteb2edd142021-01-08 23:29:35 +0100441class EF_Keys(TransparentEF):
Harald Welte13edf302022-07-21 15:19:23 +0200442 def __init__(self, fid='6f08', sfid=0x08, name='EF.Keys', size=(33, 33),
Harald Welteb2edd142021-01-08 23:29:35 +0100443 desc='Ciphering and Integrity Keys'):
444 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
Harald Weltec91085e2022-02-10 18:05:45 +0100445 self._construct = Struct(
446 'ksi'/Int8ub, 'ck'/HexAdapter(Bytes(16)), 'ik'/HexAdapter(Bytes(16)))
Harald Welteb2edd142021-01-08 23:29:35 +0100447
Harald Welte14105dc2021-05-31 08:48:51 +0200448# TS 31.102 Section 4.2.6
449class EF_HPPLMN(TransparentEF):
Harald Welte865eea62023-01-27 19:26:12 +0100450 _test_de_encode = [ ( '05', 5 ) ]
Harald Welte13edf302022-07-21 15:19:23 +0200451 def __init__(self, fid='6f31', sfid=0x12, name='EF.HPPLMN', size=(1, 1),
Harald Welte14105dc2021-05-31 08:48:51 +0200452 desc='Higher Priority PLMN search period'):
453 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
454 self._construct = Int8ub
455
Harald Welte6ca2fa72022-02-12 16:29:31 +0100456class EF_UST(EF_UServiceTable):
457 def __init__(self, **kwargs):
Harald Welte13edf302022-07-21 15:19:23 +0200458 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 +0100459 # add those commands to the general commands of a TransparentEF
460 self.shell_commands += [self.AddlShellCommands()]
461
Harald Welteb2edd142021-01-08 23:29:35 +0100462 @with_default_category('File-Specific Commands')
463 class AddlShellCommands(CommandSet):
464 def __init__(self):
465 super().__init__()
466
467 def do_ust_service_activate(self, arg):
468 """Activate a service within EF.UST"""
Alexander Couzens6c5c3f82023-07-28 05:13:06 +0200469 selected_file = self._cmd.lchan.selected_file
470 selected_file.ust_update(self._cmd, [int(arg)], [])
Harald Welteb2edd142021-01-08 23:29:35 +0100471
472 def do_ust_service_deactivate(self, arg):
473 """Deactivate a service within EF.UST"""
Alexander Couzens6c5c3f82023-07-28 05:13:06 +0200474 selected_file = self._cmd.lchan.selected_file
475 selected_file.ust_update(self._cmd, [], [int(arg)])
Harald Welteb2edd142021-01-08 23:29:35 +0100476
Harald Welte4c5e2312022-02-12 14:37:48 +0100477 def do_ust_service_check(self, arg):
Harald Welte3bb516b2022-02-12 21:53:18 +0100478 """Check consistency between services of this file and files present/activated.
479
480 Many services determine if one or multiple files shall be present/activated or if they shall be
481 absent/deactivated. This performs a consistency check to ensure that no services are activated
482 for files that are not - and vice-versa, no files are activated for services that are not. Error
483 messages are printed for every inconsistency found."""
Harald Weltea6c0f882022-07-17 14:23:17 +0200484 selected_file = self._cmd.lchan.selected_file
Harald Welte82f75c22022-02-12 18:22:28 +0100485 num_problems = selected_file.ust_service_check(self._cmd)
486 # obtain list of currently active services
487 active_services = selected_file.get_active_services(self._cmd)
488 # Service n°46 can only be declared "available" if service n°45 is declared "available"
489 if 46 in active_services and not 45 in active_services:
Harald Weltefa8b8d12022-02-12 18:30:28 +0100490 self._cmd.perror("ERROR: Service 46 available, but it requires Service 45")
Harald Welte82f75c22022-02-12 18:22:28 +0100491 num_problems += 1
492 # Service n°125 shall only be taken into account if Service n°124 is declared "available"
493 if 125 in active_services and not 124 in active_services:
Harald Weltefa8b8d12022-02-12 18:30:28 +0100494 self._cmd.perror("ERROR: Service 125 is ignored as Service 124 not available")
Harald Welte82f75c22022-02-12 18:22:28 +0100495 num_problems += 1
496 # Service n°95, n°99 and n°115 shall not be declared "available" if an ISIM application is present on the UICC
497 non_isim_services = [95, 99, 115]
498 app_names = selected_file.get_mf().get_app_names()
499 if 'ADF.ISIM' in app_names:
500 for s in non_isim_services:
501 if s in active_services:
Harald Weltefa8b8d12022-02-12 18:30:28 +0100502 self._cmd.perror("ERROR: Service %u shall not be available as ISIM application is present" % s)
Harald Welte82f75c22022-02-12 18:22:28 +0100503 num_problems += 1
504 self._cmd.poutput("===> %u service / file inconsistencies detected" % num_problems)
Harald Welte4c5e2312022-02-12 14:37:48 +0100505
506
Harald Welte89e59542021-04-02 21:33:13 +0200507# TS 31.103 Section 4.2.7 - *not* the same as DF.GSM/EF.ECC!
508class EF_ECC(LinFixedEF):
Harald Welte865eea62023-01-27 19:26:12 +0100509 _test_de_encode = [
510 ( '19f1ff01', { "call_code": "911f",
511 "service_category": { "police": True, "ambulance": False, "fire_brigade": False,
512 "marine_guard": False, "mountain_rescue": False,
513 "manual_ecall": False, "automatic_ecall": False } } ),
514 ( '19f3ff02', { "call_code": "913f",
515 "service_category": { "police": False, "ambulance": True, "fire_brigade": False,
516 "marine_guard": False, "mountain_rescue": False,
517 "manual_ecall": False, "automatic_ecall": False } } ),
518 ]
519 cc_construct = BcdAdapter(Rpad(Bytes(3)))
Harald Welteff2d86d2022-01-21 15:19:47 +0100520 category_construct = FlagsEnum(Byte, police=1, ambulance=2, fire_brigade=3, marine_guard=4,
521 mountain_rescue=5, manual_ecall=6, automatic_ecall=7)
522 alpha_construct = GsmStringAdapter(Rpad(GreedyBytes))
Harald Weltec91085e2022-02-10 18:05:45 +0100523
Harald Welte89e59542021-04-02 21:33:13 +0200524 def __init__(self, fid='6fb7', sfid=0x01, name='EF.ECC',
525 desc='Emergency Call Codes'):
Harald Welte99e4cc02022-07-21 15:25:47 +0200526 super().__init__(fid, sfid=sfid, name=name, desc=desc, rec_len=(4, 20))
Harald Weltec91085e2022-02-10 18:05:45 +0100527
Harald Weltef6b37af2023-01-24 15:42:26 +0100528 def _decode_record_bin(self, in_bin, **kwargs):
Harald Welteff2d86d2022-01-21 15:19:47 +0100529 # mandatory parts
530 code = in_bin[:3]
531 if code == b'\xff\xff\xff':
532 return None
533 svc_category = in_bin[-1:]
534 ret = {'call_code': parse_construct(EF_ECC.cc_construct, code),
Harald Weltec91085e2022-02-10 18:05:45 +0100535 'service_category': parse_construct(EF_ECC.category_construct, svc_category)}
Harald Welteff2d86d2022-01-21 15:19:47 +0100536 # optional alpha identifier
537 if len(in_bin) > 4:
538 alpha_id = in_bin[3:-1]
539 ret['alpha_id'] = parse_construct(EF_ECC.alpha_construct, alpha_id)
540 return ret
Harald Weltec91085e2022-02-10 18:05:45 +0100541
Harald Weltef6b37af2023-01-24 15:42:26 +0100542 def _encode_record_bin(self, in_json, **kwargs):
Harald Welteff2d86d2022-01-21 15:19:47 +0100543 if in_json is None:
544 return b'\xff\xff\xff\xff'
545 code = EF_ECC.cc_construct.build(in_json['call_code'])
Harald Welte9b9efb62023-01-31 16:40:54 +0100546 svc_category = EF_ECC.category_construct.build(in_json['service_category'])
547 if 'alpha_id' in in_json:
548 alpha_id = EF_ECC.alpha_construct.build(in_json['alpha_id'])
549 # FIXME: alpha_id needs padding up to 'record_length - 4'
550 else:
551 alpha_id = b''
Harald Welteff2d86d2022-01-21 15:19:47 +0100552 return code + alpha_id + svc_category
553
Harald Welte89e59542021-04-02 21:33:13 +0200554
Harald Welte790b2702021-04-11 00:01:35 +0200555# TS 31.102 Section 4.2.17
556class EF_LOCI(TransparentEF):
Harald Welte865eea62023-01-27 19:26:12 +0100557 _test_de_encode = [
558 ( '47d1264a62f21037211e00',
559 { "tmsi": "47d1264a", "lai": { "mcc_mnc": "262f01", "lac": "3721" },
560 "rfu": 30, "lu_status": 0 } ),
561 ]
Harald Welte13edf302022-07-21 15:19:23 +0200562 def __init__(self, fid='6f7e', sfid=0x0b, name='EF.LOCI', desc='Location information', size=(11, 11)):
Harald Welte790b2702021-04-11 00:01:35 +0200563 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
Harald Welte3a5afff2022-02-25 15:33:46 +0100564 Lai = Struct('mcc_mnc'/BcdAdapter(Bytes(3)), 'lac'/HexAdapter(Bytes(2)))
565 self._construct = Struct('tmsi'/HexAdapter(Bytes(4)), 'lai'/Lai, 'rfu'/Int8ub, 'lu_status'/Int8ub)
Harald Welte865eea62023-01-27 19:26:12 +0100566
Harald Welte592b32e2021-06-05 11:26:36 +0200567# TS 31.102 Section 4.2.18
568class EF_AD(TransparentEF):
Harald Welte865eea62023-01-27 19:26:12 +0100569 _test_de_encode = [
570 ( '00000002', { "ms_operation_mode": "normal",
571 "additional_info": { "ciphering_indicator": False, "csg_display_control": False,
572 "prose_services": False, "extended_drx": False },
573 "rfu": 0, "mnc_len": 2, "extensions": b'' } ),
574 ( '01000102', { "ms_operation_mode": "normal_and_specific_facilities",
575 "additional_info": { "ciphering_indicator": True, "csg_display_control": False,
576 "prose_services": False, "extended_drx": False },
577 "rfu": 0, "mnc_len": 2, "extensions": b'' } ),
578 ]
Harald Welte592b32e2021-06-05 11:26:36 +0200579 class OP_MODE(enum.IntEnum):
Harald Weltec91085e2022-02-10 18:05:45 +0100580 normal = 0x00
581 type_approval = 0x80
582 normal_and_specific_facilities = 0x01
583 type_approval_and_specific_facilities = 0x81
584 maintenance_off_line = 0x02
585 cell_test = 0x04
Harald Welte592b32e2021-06-05 11:26:36 +0200586
Harald Welte13edf302022-07-21 15:19:23 +0200587 def __init__(self, fid='6fad', sfid=0x03, name='EF.AD', desc='Administrative Data', size=(4, 6)):
Harald Welte592b32e2021-06-05 11:26:36 +0200588 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
589 self._construct = BitStruct(
590 # Byte 1
591 'ms_operation_mode'/Bytewise(Enum(Byte, EF_AD.OP_MODE)),
592 # Byte 2 + 3
593 'additional_info'/Bytewise(FlagsEnum(Int16ub, ciphering_indicator=1, csg_display_control=2,
594 prose_services=4, extended_drx=8)),
595 'rfu'/BitsRFU(4),
596 'mnc_len'/BitsInteger(4),
597 'extensions'/COptional(Bytewise(GreedyBytesRFU))
598 )
Harald Welte790b2702021-04-11 00:01:35 +0200599
600# TS 31.102 Section 4.2.23
601class EF_PSLOCI(TransparentEF):
Harald Welte13edf302022-07-21 15:19:23 +0200602 def __init__(self, fid='6f73', sfid=0x0c, name='EF.PSLOCI', desc='PS Location information', size=(14, 14)):
Harald Welte790b2702021-04-11 00:01:35 +0200603 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size)
604 self._construct = Struct('ptmsi'/HexAdapter(Bytes(4)), 'ptmsi_sig'/HexAdapter(Bytes(3)),
605 'rai'/HexAdapter(Bytes(6)), 'rau_status'/Int8ub)
606
607# TS 31.102 Section 4.2.33
608class EF_ICI(CyclicEF):
Harald Welte99e4cc02022-07-21 15:25:47 +0200609 def __init__(self, fid='6f80', sfid=0x14, name='EF.ICI', rec_len=(28, 48),
Harald Welte6169c722022-02-12 09:05:15 +0100610 desc='Incoming Call Information', **kwargs):
611 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len, **kwargs)
Harald Welte3c98d5e2022-07-20 07:40:05 +0200612 self._construct = Struct('alpha_id'/HexAdapter(Bytes(this._.total_len-28)),
Harald Welte790b2702021-04-11 00:01:35 +0200613 'len_of_bcd_contents'/Int8ub,
614 'ton_npi'/Int8ub,
615 'call_number'/BcdAdapter(Bytes(10)),
616 'cap_cfg2_record_id'/Int8ub,
617 'ext5_record_id'/Int8ub,
618 'date_and_time'/BcdAdapter(Bytes(7)),
619 'duration'/Int24ub,
620 'status'/Byte,
Harald Welte3c98d5e2022-07-20 07:40:05 +0200621 'link_to_phonebook'/HexAdapter(Bytes(3)))
Harald Welte790b2702021-04-11 00:01:35 +0200622
623# TS 31.102 Section 4.2.34
624class EF_OCI(CyclicEF):
Harald Welte99e4cc02022-07-21 15:25:47 +0200625 def __init__(self, fid='6f81', sfid=0x15, name='EF.OCI', rec_len=(27, 47),
Harald Welte6169c722022-02-12 09:05:15 +0100626 desc='Outgoing Call Information', **kwargs):
627 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len, **kwargs)
Harald Welte3c98d5e2022-07-20 07:40:05 +0200628 self._construct = Struct('alpha_id'/HexAdapter(Bytes(this._.total_len-27)),
Harald Welte790b2702021-04-11 00:01:35 +0200629 'len_of_bcd_contents'/Int8ub,
630 'ton_npi'/Int8ub,
631 'call_number'/BcdAdapter(Bytes(10)),
632 'cap_cfg2_record_id'/Int8ub,
633 'ext5_record_id'/Int8ub,
634 'date_and_time'/BcdAdapter(Bytes(7)),
635 'duration'/Int24ub,
Harald Welte3c98d5e2022-07-20 07:40:05 +0200636 'link_to_phonebook'/HexAdapter(Bytes(3)))
Harald Welte790b2702021-04-11 00:01:35 +0200637
638# TS 31.102 Section 4.2.35
639class EF_ICT(CyclicEF):
Harald Welte99e4cc02022-07-21 15:25:47 +0200640 def __init__(self, fid='6f82', sfid=None, name='EF.ICT', rec_len=(3, 3),
Harald Welte6169c722022-02-12 09:05:15 +0100641 desc='Incoming Call Timer', **kwargs):
642 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200643 self._construct = Struct('accumulated_call_timer'/Int24ub)
644
645# TS 31.102 Section 4.2.38
646class EF_CCP2(LinFixedEF):
Harald Welte6169c722022-02-12 09:05:15 +0100647 def __init__(self, fid='6f4f', sfid=0x16, name='EF.CCP2', desc='Capability Configuration Parameters 2', **kwargs):
Harald Welte99e4cc02022-07-21 15:25:47 +0200648 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=(15, None), **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200649
Harald Welte6ca2fa72022-02-12 16:29:31 +0100650# TS 31.102 Section 4.2.47
651class EF_EST(EF_UServiceTable):
652 def __init__(self, **kwargs):
Harald Welte13edf302022-07-21 15:19:23 +0200653 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 +0100654 # add those commands to the general commands of a TransparentEF
655 self.shell_commands += [self.AddlShellCommands()]
656
657 @with_default_category('File-Specific Commands')
658 class AddlShellCommands(CommandSet):
659 def __init__(self):
660 super().__init__()
661
Harald Welte18b75392023-02-23 10:00:51 +0100662 def do_est_service_enable(self, arg):
Alexander Couzensc8facea2023-07-29 05:01:57 +0200663 """Enable a service within EF.EST"""
664 selected_file = self._cmd.lchan.selected_file
665 selected_file.ust_update(self._cmd, [int(arg)], [])
Harald Welte6ca2fa72022-02-12 16:29:31 +0100666
Harald Welte18b75392023-02-23 10:00:51 +0100667 def do_est_service_disable(self, arg):
Alexander Couzensc8facea2023-07-29 05:01:57 +0200668 """Disable a service within EF.EST"""
669 selected_file = self._cmd.lchan.selected_file
670 selected_file.ust_update(self._cmd, [], [int(arg)])
Harald Welte6ca2fa72022-02-12 16:29:31 +0100671
Harald Welte790b2702021-04-11 00:01:35 +0200672# TS 31.102 Section 4.2.48
673class EF_ACL(TransparentEF):
Harald Welte13edf302022-07-21 15:19:23 +0200674 def __init__(self, fid='6f57', sfid=None, name='EF.ACL', size=(32, None),
Harald Welte6169c722022-02-12 09:05:15 +0100675 desc='Access Point Name Control List', **kwargs):
676 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Welte3c98d5e2022-07-20 07:40:05 +0200677 self._construct = Struct('num_of_apns'/Int8ub, 'tlvs'/HexAdapter(GreedyBytes))
Harald Welte790b2702021-04-11 00:01:35 +0200678
679# TS 31.102 Section 4.2.51
680class EF_START_HFN(TransparentEF):
Harald Welte865eea62023-01-27 19:26:12 +0100681 _test_de_encode = [
682 ( 'f00000f00000', { "start_cs": 15728640, "start_ps": 15728640 } ),
683 ]
Harald Welte13edf302022-07-21 15:19:23 +0200684 def __init__(self, fid='6f5b', sfid=0x0f, name='EF.START-HFN', size=(6, 6),
Harald Welte6169c722022-02-12 09:05:15 +0100685 desc='Initialisation values for Hyperframe number', **kwargs):
686 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200687 self._construct = Struct('start_cs'/Int24ub, 'start_ps'/Int24ub)
688
689# TS 31.102 Section 4.2.52
690class EF_THRESHOLD(TransparentEF):
Harald Welte865eea62023-01-27 19:26:12 +0100691 _test_de_encode = [
692 ( 'f01000', { "max_start": 15732736 } ),
693 ]
Harald Welte13edf302022-07-21 15:19:23 +0200694 def __init__(self, fid='6f5c', sfid=0x10, name='EF.THRESHOLD', size=(3, 3),
Harald Welte6169c722022-02-12 09:05:15 +0100695 desc='Maximum value of START', **kwargs):
696 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200697 self._construct = Struct('max_start'/Int24ub)
698
Harald Welte363edd92022-07-17 22:24:03 +0200699# TS 31.102 (old releases like 3.8.0) Section 4.2.56
700class EF_RPLMNAcT(TransRecEF):
Harald Welte13edf302022-07-21 15:19:23 +0200701 def __init__(self, fid='6f65', sfid=None, name='EF.RPLMNAcTD', size=(2, 4), rec_len=2,
Harald Welte363edd92022-07-17 22:24:03 +0200702 desc='RPLMN Last used Access Technology', **kwargs):
703 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, rec_len=rec_len, **kwargs)
Harald Weltef6b37af2023-01-24 15:42:26 +0100704 def _decode_record_hex(self, in_hex, **kwargs):
Harald Welte363edd92022-07-17 22:24:03 +0200705 return dec_act(in_hex)
706 # TODO: Encode
707
Harald Welte790b2702021-04-11 00:01:35 +0200708# TS 31.102 Section 4.2.77
709class EF_VGCSCA(TransRecEF):
Harald Welte13edf302022-07-21 15:19:23 +0200710 def __init__(self, fid='6fd4', sfid=None, name='EF.VGCSCA', size=(2, 100), rec_len=2,
Harald Welte6169c722022-02-12 09:05:15 +0100711 desc='Voice Group Call Service Ciphering Algorithm', **kwargs):
712 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, rec_len=rec_len, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200713 self._construct = Struct('alg_v_ki_1'/Int8ub, 'alg_v_ki_2'/Int8ub)
714
715# TS 31.102 Section 4.2.79
716class EF_GBABP(TransparentEF):
Harald Welte13edf302022-07-21 15:19:23 +0200717 def __init__(self, fid='6fd6', sfid=None, name='EF.GBABP', size=(3, 50),
Harald Welte6169c722022-02-12 09:05:15 +0100718 desc='GBA Bootstrapping parameters', **kwargs):
719 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200720 self._construct = Struct('rand'/LV, 'b_tid'/LV, 'key_lifetime'/LV)
721
722# TS 31.102 Section 4.2.80
723class EF_MSK(LinFixedEF):
Harald Welte6169c722022-02-12 09:05:15 +0100724 def __init__(self, fid='6fd7', sfid=None, name='EF.MSK', desc='MBMS Service Key List', **kwargs):
Harald Welte99e4cc02022-07-21 15:25:47 +0200725 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=(20, None), **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200726 msk_ts_constr = Struct('msk_id'/Int32ub, 'timestamp_counter'/Int32ub)
Harald Welte3c98d5e2022-07-20 07:40:05 +0200727 self._construct = Struct('key_domain_id'/HexAdapter(Bytes(3)),
Harald Welte790b2702021-04-11 00:01:35 +0200728 'num_msk_id'/Int8ub,
729 'msk_ids'/msk_ts_constr[this.num_msk_id])
Harald Welte14105dc2021-05-31 08:48:51 +0200730# TS 31.102 Section 4.2.81
731class EF_MUK(LinFixedEF):
732 class MUK_Idr(BER_TLV_IE, tag=0x80):
733 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100734
Harald Welte14105dc2021-05-31 08:48:51 +0200735 class MUK_Idi(BER_TLV_IE, tag=0x82):
736 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100737
Harald Welte14105dc2021-05-31 08:48:51 +0200738 class MUK_ID(BER_TLV_IE, tag=0xA0, nested=[MUK_Idr, MUK_Idi]):
739 pass
Harald Weltec91085e2022-02-10 18:05:45 +0100740
Harald Welte14105dc2021-05-31 08:48:51 +0200741 class TimeStampCounter(BER_TLV_IE, tag=0x81):
742 pass
Harald Weltec91085e2022-02-10 18:05:45 +0100743
Harald Welte14105dc2021-05-31 08:48:51 +0200744 class EF_MUK_Collection(TLV_IE_Collection, nested=[MUK_ID, TimeStampCounter]):
745 pass
Harald Weltec91085e2022-02-10 18:05:45 +0100746
Harald Welte6169c722022-02-12 09:05:15 +0100747 def __init__(self, fid='6fd8', sfid=None, name='EF.MUK', desc='MBMS User Key', **kwargs):
Harald Welte99e4cc02022-07-21 15:25:47 +0200748 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=(None, None), **kwargs)
Harald Welte14105dc2021-05-31 08:48:51 +0200749 self._tlv = EF_MUK.EF_MUK_Collection
750
751# TS 31.102 Section 4.2.83
752class EF_GBANL(LinFixedEF):
753 class NAF_ID(BER_TLV_IE, tag=0x80):
754 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100755
Harald Welte14105dc2021-05-31 08:48:51 +0200756 class B_TID(BER_TLV_IE, tag=0x81):
757 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100758
Harald Welte14105dc2021-05-31 08:48:51 +0200759 class EF_GBANL_Collection(BER_TLV_IE, nested=[NAF_ID, B_TID]):
760 pass
Harald Weltec91085e2022-02-10 18:05:45 +0100761
Harald Welte6169c722022-02-12 09:05:15 +0100762 def __init__(self, fid='6fda', sfid=None, name='EF.GBANL', desc='GBA NAF List', **kwargs):
Harald Welte99e4cc02022-07-21 15:25:47 +0200763 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=(None, None), **kwargs)
Harald Welte14105dc2021-05-31 08:48:51 +0200764 self._tlv = EF_GBANL.EF_GBANL_Collection
Harald Welte790b2702021-04-11 00:01:35 +0200765
766# TS 31.102 Section 4.2.85
767class EF_EHPLMNPI(TransparentEF):
Harald Welte865eea62023-01-27 19:26:12 +0100768 _test_de_encode = [
769 ( '02', { "presentation_ind": "display_all" } ),
770 ]
Harald Welte13edf302022-07-21 15:19:23 +0200771 def __init__(self, fid='6fdb', sfid=None, name='EF.EHPLMNPI', size=(1, 1),
Harald Welte6169c722022-02-12 09:05:15 +0100772 desc='Equivalent HPLMN Presentation Indication', **kwargs):
773 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Weltec91085e2022-02-10 18:05:45 +0100774 self._construct = Struct('presentation_ind' /
Harald Welte790b2702021-04-11 00:01:35 +0200775 Enum(Byte, no_preference=0, display_highest_prio_only=1, display_all=2))
Harald Welte14105dc2021-05-31 08:48:51 +0200776
777# TS 31.102 Section 4.2.87
778class EF_NAFKCA(LinFixedEF):
779 class NAF_KeyCentreAddress(BER_TLV_IE, tag=0x80):
780 _construct = HexAdapter(GreedyBytes)
Harald Welte99e4cc02022-07-21 15:25:47 +0200781 def __init__(self, fid='6fdd', sfid=None, name='EF.NAFKCA', rec_len=(None, None),
Harald Welte6169c722022-02-12 09:05:15 +0100782 desc='NAF Key Centre Address', **kwargs):
783 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len, **kwargs)
Harald Welte14105dc2021-05-31 08:48:51 +0200784 self._tlv = EF_NAFKCA.NAF_KeyCentreAddress
785
786# TS 31.102 Section 4.2.90
787class EF_NCP_IP(LinFixedEF):
788 class DataDestAddrRange(TLV_IE, tag=0x83):
789 _construct = Struct('type_of_address'/Enum(Byte, IPv4=0x21, IPv6=0x56),
790 'prefix_length'/Int8ub,
791 'prefix'/HexAdapter(GreedyBytes))
Harald Weltec91085e2022-02-10 18:05:45 +0100792
Harald Welte14105dc2021-05-31 08:48:51 +0200793 class AccessPointName(TLV_IE, tag=0x80):
794 # coded as per TS 23.003
795 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100796
Harald Welte14105dc2021-05-31 08:48:51 +0200797 class Login(TLV_IE, tag=0x81):
798 # as per SMS DCS TS 23.038
799 _construct = GsmStringAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100800
Harald Welte14105dc2021-05-31 08:48:51 +0200801 class Password(TLV_IE, tag=0x82):
802 # as per SMS DCS TS 23.038
803 _construct = GsmStringAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100804
Harald Welte14105dc2021-05-31 08:48:51 +0200805 class BearerDescription(TLV_IE, tag=0x84):
806 # Bearer descriptionTLV DO as per TS 31.111
807 pass
Harald Weltec91085e2022-02-10 18:05:45 +0100808
Harald Welte14105dc2021-05-31 08:48:51 +0200809 class EF_NCP_IP_Collection(TLV_IE_Collection,
810 nested=[AccessPointName, Login, Password, BearerDescription]):
811 pass
Harald Welte99e4cc02022-07-21 15:25:47 +0200812 def __init__(self, fid='6fe2', sfid=None, name='EF.NCP-IP', rec_len=(None, None),
Harald Welte6169c722022-02-12 09:05:15 +0100813 desc='Network Connectivity Parameters for USIM IP connections', **kwargs):
814 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len, **kwargs)
Harald Welte14105dc2021-05-31 08:48:51 +0200815 self._tlv = EF_NCP_IP.EF_NCP_IP_Collection
816
Harald Welte790b2702021-04-11 00:01:35 +0200817# TS 31.102 Section 4.2.91
818class EF_EPSLOCI(TransparentEF):
Harald Welte12721292022-07-21 15:33:06 +0200819 def __init__(self, fid='6fe3', sfid=0x1e, name='EF.EPSLOCI',
820 desc='EPS Location Information', size=(18,18), **kwargs):
Harald Welte6169c722022-02-12 09:05:15 +0100821 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Weltec91085e2022-02-10 18:05:45 +0100822 upd_status_constr = Enum(
823 Byte, updated=0, not_updated=1, roaming_not_allowed=2)
Harald Welte3c98d5e2022-07-20 07:40:05 +0200824 self._construct = Struct('guti'/HexAdapter(Bytes(12)),
825 'last_visited_registered_tai'/HexAdapter(Bytes(5)),
Harald Welte790b2702021-04-11 00:01:35 +0200826 'eps_update_status'/upd_status_constr)
827
Harald Welte14105dc2021-05-31 08:48:51 +0200828# TS 31.102 Section 4.2.92
829class EF_EPSNSC(LinFixedEF):
Harald Weltec91085e2022-02-10 18:05:45 +0100830 class KSI_ASME(BER_TLV_IE, tag=0x80):
Harald Welte14105dc2021-05-31 08:48:51 +0200831 _construct = Int8ub
Harald Weltec91085e2022-02-10 18:05:45 +0100832
833 class K_ASME(BER_TLV_IE, tag=0x81):
Harald Welte14105dc2021-05-31 08:48:51 +0200834 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100835
Harald Welte14105dc2021-05-31 08:48:51 +0200836 class UplinkNASCount(BER_TLV_IE, tag=0x82):
837 _construct = Int32ub
Harald Weltec91085e2022-02-10 18:05:45 +0100838
Harald Welte14105dc2021-05-31 08:48:51 +0200839 class DownlinkNASCount(BER_TLV_IE, tag=0x83):
840 _construct = Int32ub
Harald Weltec91085e2022-02-10 18:05:45 +0100841
Harald Welte14105dc2021-05-31 08:48:51 +0200842 class IDofNASAlgorithms(BER_TLV_IE, tag=0x84):
843 _construct = HexAdapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100844
Harald Welte14105dc2021-05-31 08:48:51 +0200845 class EPS_NAS_Security_Context(BER_TLV_IE, tag=0xa0,
Harald Weltec91085e2022-02-10 18:05:45 +0100846 nested=[KSI_ASME, K_ASME, UplinkNASCount, DownlinkNASCount,
847 IDofNASAlgorithms]):
Harald Welte14105dc2021-05-31 08:48:51 +0200848 pass
Harald Welte99e4cc02022-07-21 15:25:47 +0200849 def __init__(self, fid='6fe4', sfid=0x18, name='EF.EPSNSC', rec_len=(54, 128),
Harald Welte6169c722022-02-12 09:05:15 +0100850 desc='EPS NAS Security Context', **kwargs):
851 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len, **kwargs)
Harald Welte14105dc2021-05-31 08:48:51 +0200852 self._tlv = EF_EPSNSC.EPS_NAS_Security_Context
853
Harald Welte790b2702021-04-11 00:01:35 +0200854# TS 31.102 Section 4.2.96
855class EF_PWS(TransparentEF):
Harald Welte865eea62023-01-27 19:26:12 +0100856 _test_de_encode = [
857 ( '00', { "pws_configuration": { "ignore_pws_in_hplmn_and_equivalent": False,
858 "ignore_pws_in_vplmn": False } } ),
859 ]
Harald Welte13edf302022-07-21 15:19:23 +0200860 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 +0100861 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Weltec91085e2022-02-10 18:05:45 +0100862 pws_config = FlagsEnum(
863 Byte, ignore_pws_in_hplmn_and_equivalent=1, ignore_pws_in_vplmn=2)
Harald Welte790b2702021-04-11 00:01:35 +0200864 self._construct = Struct('pws_configuration'/pws_config)
865
866# TS 31.102 Section 4.2.101
867class EF_IPS(CyclicEF):
Harald Welte99e4cc02022-07-21 15:25:47 +0200868 def __init__(self, fid='6ff1', sfid=None, name='EF.IPS', rec_len=(4, 4),
Harald Welte6169c722022-02-12 09:05:15 +0100869 desc='IMEI(SV) Pairing Status', **kwargs):
870 super().__init__(fid, sfid=sfid, name=name, desc=desc, rec_len=rec_len, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200871 self._construct = Struct('status'/PaddedString(2, 'ascii'),
872 'link_to_ef_ipd'/Int8ub, 'rfu'/Byte)
873
Harald Welte14105dc2021-05-31 08:48:51 +0200874# TS 31.102 Section 4.2.103
875class EF_ePDGId(TransparentEF):
Harald Welte478b5fe2023-12-08 14:27:50 +0100876 _test_de_encode = [
877 ( '801100657064672e6f736d6f636f6d2e6f7267', {'e_pdg_id': {"type_of_ePDG_address": "FQDN", "ePDG_address" : "epdg.osmocom.org" } } ),
878 ( '800501c0a8a001', {'e_pdg_id': {"type_of_ePDG_address": "IPv4", "ePDG_address" : "c0a8a001" } } ),
879 ]
880 class ePDGId(BER_TLV_IE, tag=0x80):
Harald Welte14105dc2021-05-31 08:48:51 +0200881 _construct = Struct('type_of_ePDG_address'/Enum(Byte, FQDN=0, IPv4=1, IPv6=2),
Harald Welte478b5fe2023-12-08 14:27:50 +0100882 'ePDG_address'/Switch(this.type_of_ePDG_address,
Philipp Maier791f80a2023-07-26 17:01:37 +0200883 {'FQDN': Utf8Adapter(GreedyBytes),
Harald Weltec91085e2022-02-10 18:05:45 +0100884 'IPv4': HexAdapter(GreedyBytes),
885 'IPv6': HexAdapter(GreedyBytes)}))
886
iw040ef2262023-11-07 13:41:12 +0100887 def __init__(self, fid='6ff3', sfid=None, name='EF.ePDGId', desc='Home ePDG Identifier', **kwargs):
Harald Welte6169c722022-02-12 09:05:15 +0100888 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
Harald Welte14105dc2021-05-31 08:48:51 +0200889 self._tlv = EF_ePDGId.ePDGId
890
Harald Weltecdfe1c22023-12-08 12:30:21 +0100891# TS 31.102 Section 4.2.104
892class EF_ePDGSelection(TransparentEF):
Harald Welte478b5fe2023-12-08 14:27:50 +0100893 _test_de_encode = [
894 ( '80060001f1000100', {'e_pdg_selection': [{'plmn': '00101f', 'epdg_priority': 1, 'epdg_fqdn_format': 'operator_identified' }] }),
895 ( '800600011000a001', {'e_pdg_selection': [{'plmn': '001001', 'epdg_priority': 160, 'epdg_fqdn_format': 'location_based' }] }),
896 ]
897 class ePDGSelection(BER_TLV_IE, tag=0x80):
Harald Weltecdfe1c22023-12-08 12:30:21 +0100898 _construct = GreedyRange(Struct('plmn'/BcdAdapter(Bytes(3)),
899 'epdg_priority'/Int16ub,
900 'epdg_fqdn_format'/Enum(Int8ub, operator_identified=0, location_based=1)))
901
902 def __init__(self, fid='6ff4', sfid=None, name='EF.ePDGSelection', desc='ePDG Selection Information', **kwargs):
903 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
904 self._tlv = EF_ePDGSelection.ePDGSelection
905
Harald Welte71290072021-04-21 10:58:24 +0200906# TS 31.102 Section 4.2.106
907class EF_FromPreferred(TransparentEF):
Harald Welte13edf302022-07-21 15:19:23 +0200908 def __init__(self, fid='6ff7', sfid=None, name='EF.FromPreferred', size=(1, 1),
Harald Welte6169c722022-02-12 09:05:15 +0100909 desc='From Preferred', **kwargs):
910 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Welte45477a72023-11-03 01:33:06 +0100911 self._construct = BitStruct('rfu'/BitsRFU(7), 'from_preferred'/Flag)
Harald Welte71290072021-04-21 10:58:24 +0200912
Harald Weltefc67de22023-05-23 20:29:49 +0200913# TS 31.102 Section 4.2.114
914class EF_eAKA(TransparentEF):
915 def __init__(self, fid='6f01', sfid=None, name='EF.eAKA', size=(1, 1),
916 desc='enhanced AKA support', **kwargs):
917 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Welte45477a72023-11-03 01:33:06 +0100918 self._construct = BitStruct('rfu'/BitsRFU(7), 'enhanced_sqn_calculation_supported'/Flag)
Harald Weltefc67de22023-05-23 20:29:49 +0200919
Harald Welted90ceb82022-07-17 22:10:58 +0200920
921######################################################################
922# DF.GSM-ACCESS
923######################################################################
924
925class DF_GSM_ACCESS(CardDF):
926 def __init__(self, fid='5F3B', name='DF.GSM-ACCESS', desc='GSM Access', **kwargs):
927 super().__init__(fid=fid, name=name, desc=desc, service=27, **kwargs)
928 files = [
929 EF_Kc(fid='4f20', sfid=0x01, service=27),
930 EF_Kc(fid='4f52', sfid=0x02, name='EF.KcGPRS', desc='GPRS Ciphering key KcGPRS', service=27),
931 EF_CPBCCH(fid='4f63', service=39),
932 EF_InvScan(fid='4f64', service=40),
933 ]
934 self.add_files(files)
935
936
Harald Welte790b2702021-04-11 00:01:35 +0200937######################################################################
938# DF.5GS
939######################################################################
940
941# TS 31.102 Section 4.4.11.2
942class EF_5GS3GPPLOCI(TransparentEF):
Harald Welte13edf302022-07-21 15:19:23 +0200943 def __init__(self, fid='4f01', sfid=0x01, name='EF.5GS3GPPLOCI', size=(20, 20),
Harald Welte419bb492022-02-12 21:39:35 +0100944 desc='5S 3GP location information', **kwargs):
945 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Weltec91085e2022-02-10 18:05:45 +0100946 upd_status_constr = Enum(
947 Byte, updated=0, not_updated=1, roaming_not_allowed=2)
Harald Welte3c98d5e2022-07-20 07:40:05 +0200948 self._construct = Struct('5g_guti'/HexAdapter(Bytes(13)),
949 'last_visited_registered_tai_in_5gs'/HexAdapter(Bytes(6)),
Harald Welte790b2702021-04-11 00:01:35 +0200950 '5gs_update_status'/upd_status_constr)
951
952# TS 31.102 Section 4.4.11.7
953class EF_UAC_AIC(TransparentEF):
Harald Welte865eea62023-01-27 19:26:12 +0100954 _test_de_encode = [
955 ( '03', { "uac_access_id_config": { "multimedia_priority_service": True,
956 "mission_critical_service": True } } ),
957 ]
Harald Welte13edf302022-07-21 15:19:23 +0200958 def __init__(self, fid='4f06', sfid=0x06, name='EF.UAC_AIC', size=(4, 4),
Harald Welte419bb492022-02-12 21:39:35 +0100959 desc='UAC Access Identities Configuration', **kwargs):
960 super().__init__(fid, sfid=sfid, name=name, desc=desc, size=size, **kwargs)
Harald Welte790b2702021-04-11 00:01:35 +0200961 cfg_constr = FlagsEnum(Byte, multimedia_priority_service=1,
Harald Weltec91085e2022-02-10 18:05:45 +0100962 mission_critical_service=2)
Harald Welte790b2702021-04-11 00:01:35 +0200963 self._construct = Struct('uac_access_id_config'/cfg_constr)
964
Harald Welte14105dc2021-05-31 08:48:51 +0200965# TS 31.102 Section 4.4.11.9
Harald Welte790b2702021-04-11 00:01:35 +0200966class EF_OPL5G(LinFixedEF):
Harald Welte52064292023-05-24 15:25:26 +0200967 def __init__(self, fid='4f08', sfid=0x08, name='EF.OPL5G', desc='5GS Operator PLMN List', **kwargs):
Harald Welte99e4cc02022-07-21 15:25:47 +0200968 super().__init__(fid=fid, sfid=sfid, name=name, desc=desc, rec_len=(10, None), **kwargs)
Harald Welte3c98d5e2022-07-20 07:40:05 +0200969 Tai = Struct('mcc_mnc'/BcdAdapter(Bytes(3)), 'tac_min'/HexAdapter(Bytes(3)),
970 'tac_max'/HexAdapter(Bytes(3)))
Harald Weltea0377622022-02-25 15:36:44 +0100971 self._construct = Struct('tai'/Tai, 'pnn_record_id'/Int8ub)
Harald Welte790b2702021-04-11 00:01:35 +0200972
Harald Welte14105dc2021-05-31 08:48:51 +0200973# TS 31.102 Section 4.4.11.10
974class EF_SUPI_NAI(TransparentEF):
975 class NetworkSpecificIdentifier(TLV_IE, tag=0x80):
976 # RFC 7542 encoded as UTF-8 string
Philipp Maier791f80a2023-07-26 17:01:37 +0200977 _construct = Utf8Adapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100978
Harald Welte14105dc2021-05-31 08:48:51 +0200979 class GlobalLineIdentifier(TLV_IE, tag=0x81):
980 # TS 23.003 clause 28.16.2
Philipp Maier791f80a2023-07-26 17:01:37 +0200981 _construct = Utf8Adapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100982
Harald Welte14105dc2021-05-31 08:48:51 +0200983 class GlobalCableIdentifier(TLV_IE, tag=0x82):
984 # TS 23.003 clause 28.15.2
Philipp Maier791f80a2023-07-26 17:01:37 +0200985 _construct = Utf8Adapter(GreedyBytes)
Harald Weltec91085e2022-02-10 18:05:45 +0100986
Harald Welte14105dc2021-05-31 08:48:51 +0200987 class NAI_TLV_Collection(TLV_IE_Collection,
Harald Weltec91085e2022-02-10 18:05:45 +0100988 nested=[NetworkSpecificIdentifier, GlobalLineIdentifier, GlobalCableIdentifier]):
Harald Welte14105dc2021-05-31 08:48:51 +0200989 pass
990 def __init__(self, fid='4f09', sfid=0x09, name='EF.SUPI_NAI',
Harald Welte419bb492022-02-12 21:39:35 +0100991 desc='SUPI as Network Access Identifier', **kwargs):
992 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
Harald Welte14105dc2021-05-31 08:48:51 +0200993 self._tlv = EF_SUPI_NAI.NAI_TLV_Collection
994
Harald Welte455611c2023-05-27 12:48:54 +0200995# TS 31.102 Section 4.4.11.11
996class EF_Routing_Indicator(TransparentEF):
997 def __init__(self, fid='4f0a', sfid=0x0a, name='EF.Routing_Indicator', desc='Routing Indicator', **kwargs):
998 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
999 # 3GPP TS 24.501 Table 9.11.3.4.1:
1000 # Routing Indicator shall consist of 1 to 4 digits. The coding of this field is the
1001 # responsibility of home network operator but BCD coding shall be used. If a network
1002 # operator decides to assign less than 4 digits to Routing Indicator, the remaining digits
1003 # shall be coded as "1111" to fill the 4 digits coding of Routing Indicator
Harald Weltef9a5ba52023-06-09 09:17:05 +02001004 self._construct = Struct('routing_indicator'/Rpad(BcdAdapter(Bytes(2)), 'f', 2),
1005 'rfu'/HexAdapter(Bytes(2)))
Harald Weltec91085e2022-02-10 18:05:45 +01001006
Harald Weltefc67de22023-05-23 20:29:49 +02001007# TS 31.102 Section 4.4.11.13
Harald Welte14105dc2021-05-31 08:48:51 +02001008class EF_TN3GPPSNN(TransparentEF):
1009 class ServingNetworkName(BER_TLV_IE, tag=0x80):
Philipp Maier791f80a2023-07-26 17:01:37 +02001010 _construct = Utf8Adapter(GreedyBytes)
Harald Welte14105dc2021-05-31 08:48:51 +02001011 def __init__(self, fid='4f0c', sfid=0x0c, name='EF.TN3GPPSNN',
Harald Welte419bb492022-02-12 21:39:35 +01001012 desc='Trusted non-3GPP Serving network names list', **kwargs):
1013 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
Harald Welte14105dc2021-05-31 08:48:51 +02001014 self._tlv = EF_TN3GPPSNN.ServingNetworkName
1015
Harald Weltefc67de22023-05-23 20:29:49 +02001016# TS 31.102 Section 4.4.11.14 (Rel 17)
1017class EF_CAG(TransparentEF):
1018 def __init__(self, fid='4f0d', sfid=0x0d, name='EF.CAG',
1019 desc='Pre-configured CAG information list EF', **kwargs):
1020 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
1021 self._construct = HexAdapter(GreedyBytes)
1022
1023# TS 31.102 Section 4.4.11.15 (Rel 17)
1024class EF_SOR_CMCI(TransparentEF):
1025 def __init__(self, fid='4f0e', sfid=0x0e, name='EF.SOR-CMCI',
1026 desc='Steering Of Roaming - Connected Mode Control Information', **kwargs):
1027 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
1028 self._construct = HexAdapter(GreedyBytes)
1029
1030# TS 31.102 Section 4.4.11.17 (Rel 17)
1031class EF_DRI(TransparentEF):
1032 def __init__(self, fid='4f0f', sfid=0x0f, name='EF.DRI',
1033 desc='Disaster roaming information EF', **kwargs):
1034 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
1035 self._construct = Struct('disaster_roaming_enabled'/Byte,
1036 'parameters_indicator_status'/FlagsEnum(Byte, roaming_wait_range=1,
1037 return_wait_range=2,
1038 applicability_indicator=3),
1039 'roaming_wait_range'/HexAdapter(Bytes(2)),
1040 'return_wait_range'/HexAdapter(Bytes(2)),
1041 'applicability_indicator'/HexAdapter(Byte))
1042
1043# TS 31.102 Section 4.4.12.2 (Rel 17)
1044class EF_PWS_SNPN(TransparentEF):
1045 def __init__(self, fid='4f01', sfid=0x01, name='EF.PWS_SNPN',
1046 desc='Public Warning System in SNPNs', **kwargs):
1047 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
1048 self._construct = Struct('pws_config_in_snpns'/FlagsEnum(Byte, ignore_all_pws_in_subscribed=1,
1049 ignore_all_pws_in_non_subscribed=2))
1050
1051# TS 31.102 Section 4.4.12.2 (Rel 17)
1052class EF_NID(LinFixedEF):
1053 def __init__(self, fid='4f02', sfid=0x02, name='EF.NID',
1054 desc='Network Identifier for SNPN', **kwargs):
1055 super().__init__(fid, sfid=sfid, name=name, desc=desc, rec_len=(6,6), **kwargs)
1056 self._construct = Struct('assignment_mode'/Enum(Byte, coordinated_ass_opt1=0,
1057 self_ass=1,
1058 coordinated_ass_opt2=2),
1059 'network_identifier'/HexAdapter(Bytes(5)))
1060
1061# TS 31.102 Section 4.4.12 (Rel 17)
1062class DF_SNPN(CardDF):
1063 def __init__(self, fid='5fe0', name='DF.SNPN', desc='Files for SNPN purpose', **kwargs):
1064 super().__init__(fid=fid, name=name, desc=desc, **kwargs)
1065 files = [
1066 EF_PWS_SNPN(service=143),
1067 EF_NID(service=146),
1068 ]
1069 self.add_files(files)
1070
1071# TS 31.102 Section 4.4.13.2 (Rel 17)
1072class EF_5G_PROSE_ST(EF_UServiceTable):
1073 def __init__(self, **kwargs):
1074 super().__init__(fid='4f01', sfid=0x01, name='EF.5G_PROSE_ST',
1075 desc='5G ProSe Service Table', size=(1,2), table=EF_5G_PROSE_ST_map, **kwargs)
1076 # add those commands to the general commands of a TransparentEF
1077 self.shell_commands += [self.AddlShellCommands()]
1078
1079 @with_default_category('File-Specific Commands')
1080 class AddlShellCommands(CommandSet):
1081 def __init__(self):
1082 super().__init__()
1083
1084 def do_prose_service_activate(self, arg):
1085 """Activate a service within EF.5G_PROSE_ST"""
Alexander Couzensc8facea2023-07-29 05:01:57 +02001086 selected_file = self._cmd.lchan.selected_file
1087 selected_file.ust_update(self._cmd, [int(arg)], [])
Harald Weltefc67de22023-05-23 20:29:49 +02001088
1089 def do_prose_service_deactivate(self, arg):
1090 """Deactivate a service within EF.5G_PROSE_ST"""
Alexander Couzensc8facea2023-07-29 05:01:57 +02001091 selected_file = self._cmd.lchan.selected_file
1092 selected_file.ust_update(self._cmd, [], [int(arg)])
Harald Weltefc67de22023-05-23 20:29:49 +02001093
1094# TS 31.102 Section 4.4.13.3 (Rel 17)
1095class EF_5G_PROSE_DD(TransparentEF):
1096 class ServedByNgRan(BER_TLV_IE, tag=0x80):
1097 pass
1098 class NotServedByNgran(BER_TLV_IE, tag=0x81):
1099 pass
1100 class ProSeIdentifiers(BER_TLV_IE, tag=0x82):
1101 pass
1102 class ProSeIdToDefaultDestL2Id(BER_TLV_IE, tag=0x83):
1103 pass
1104 class GroupMemberDiscoveryParameters(BER_TLV_IE, tag=0x84):
1105 pass
1106 class ValidityTimer(BER_TLV_IE, tag=0x85):
1107 pass
1108 class ProSeDirectDiscoveryUeId(BER_TLV_IE, tag=0x86):
1109 pass
1110 class Hplmn5GDdnmfAddressInformation(BER_TLV_IE, tag=0x87):
1111 pass
1112 class ProSeConfigForDirectDiscovery(BER_TLV_IE, tag=0xA0,
1113 nested=[ServedByNgRan, NotServedByNgran, ProSeIdentifiers,
1114 ProSeIdToDefaultDestL2Id, GroupMemberDiscoveryParameters,
1115 ValidityTimer, ProSeDirectDiscoveryUeId,
1116 Hplmn5GDdnmfAddressInformation]):
1117 pass
1118 def __init__(self, fid='4f02', sfid=0x02, name='EF.5G_PROSE_DD',
1119 desc='5G ProSe configuration data for direct discovery', **kwargs):
1120 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
1121 # contains TLV structure despite being TransparentEF, not BER-TLV ?!?
1122 self._tlv = EF_5G_PROSE_DD.ProSeConfigForDirectDiscovery
1123
1124# TS 31.102 Section 4.4.13.4 (Rel 17)
1125class EF_5G_PROSE_DC(TransparentEF):
1126 class PrivacyConfig(BER_TLV_IE, tag=0x87):
1127 pass
1128 class DirectCommInNrPc5(BER_TLV_IE, tag=0x88):
1129 pass
1130 class ApplicationToPathPreferenceMappingRules(BER_TLV_IE, tag=0x89):
1131 pass
1132 class ProSeIdToNrTxProfileForBroadcastAndGroupcastMappingRules(BER_TLV_IE, tag=0x91):
1133 pass
1134 class ProSeConfigForDirectCommunication(BER_TLV_IE, tag=0xA0,
1135 nested=[EF_5G_PROSE_DD.ServedByNgRan,
1136 EF_5G_PROSE_DD.NotServedByNgran,
1137 PrivacyConfig, DirectCommInNrPc5,
1138 ApplicationToPathPreferenceMappingRules,
1139 EF_5G_PROSE_DD.ValidityTimer,
1140 ProSeIdToNrTxProfileForBroadcastAndGroupcastMappingRules]):
1141 pass
1142 def __init__(self, fid='4f03', sfid=0x03, name='EF.5G_PROSE_DC',
1143 desc='5G ProSe configuration data for direct communication', **kwargs):
1144 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
1145 # contains TLV structure despite being TransparentEF, not BER-TLV ?!?
1146 self._tlv = EF_5G_PROSE_DC.ProSeConfigForDirectCommunication
1147
1148# TS 31.102 Section 4.4.13.5 (Rel 17)
1149class EF_5G_PROSE_U2NRU(TransparentEF):
1150 class ProSeIdToDefaultDestL2Id(BER_TLV_IE, tag=0x8a):
1151 pass
1152 class RxcInfoList(BER_TLV_IE, tag=0x8b):
1153 pass
1154 class FiveQiToPc65QosParametersMappingRules(BER_TLV_IE, tag=0x8c):
1155 pass
1156 class ProSeIdToAppSrvAddrMappingRules(BER_TLV_IE, tag=0x8d):
1157 pass
1158 class UserInfoIdForDiscovery(BER_TLV_IE, tag=0x8e):
1159 pass
1160 class PrivacyTimer(BER_TLV_IE, tag=0x92):
1161 pass
1162 class FiveGPkkmfAddressInformation(BER_TLV_IE, tag=0x93):
1163 pass
1164 class ProSeConfigDataForUeToNetworkRelayUe(BER_TLV_IE, tag=0xA0,
1165 nested=[EF_5G_PROSE_DD.ServedByNgRan,
1166 EF_5G_PROSE_DD.NotServedByNgran,
1167 ProSeIdToDefaultDestL2Id,
1168 RxcInfoList,
1169 FiveQiToPc65QosParametersMappingRules,
1170 ProSeIdToAppSrvAddrMappingRules,
1171 EF_5G_PROSE_DD.ValidityTimer,
1172 UserInfoIdForDiscovery,
1173 PrivacyTimer,
1174 FiveGPkkmfAddressInformation]):
1175 pass
1176 def __init__(self, fid='4f04', sfid=0x04, name='EF.5G_PROSE_U2NRU',
1177 desc='5G ProSe configuration data for UE-to-network relay UE', **kwargs):
1178 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
1179 # contains TLV structure despite being TransparentEF, not BER-TLV ?!?
1180 self._tlv = EF_5G_PROSE_U2NRU.ProSeConfigDataForUeToNetworkRelayUe
1181
1182# TS 31.102 Section 4.4.13.6 (Rel 17)
1183class EF_5G_PROSE_RU(TransparentEF):
1184 class DefaultDestL2Ids(BER_TLV_IE, tag=0x8f):
1185 pass
1186 class N3IwfSelectionInfoFor5GProSeL3RemoteUE(BER_TLV_IE, tag=0x90):
1187 pass
1188 class ProSeConfigDataForRemoteUe(BER_TLV_IE, tag=0xa0,
1189 nested=[EF_5G_PROSE_DD.ServedByNgRan,
1190 EF_5G_PROSE_DD.NotServedByNgran,
1191 DefaultDestL2Ids,
1192 EF_5G_PROSE_U2NRU.RxcInfoList,
1193 N3IwfSelectionInfoFor5GProSeL3RemoteUE,
1194 EF_5G_PROSE_DD.ValidityTimer,
1195 EF_5G_PROSE_U2NRU.UserInfoIdForDiscovery,
1196 EF_5G_PROSE_U2NRU.PrivacyTimer,
1197 EF_5G_PROSE_U2NRU.FiveGPkkmfAddressInformation]):
1198 pass
1199 def __init__(self, fid='4f05', sfid=0x05, name='EF.5G_PROSE_RU',
1200 desc='5G ProSe configuration data for remote UE', **kwargs):
1201 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
1202 # contains TLV structure despite being TransparentEF, not BER-TLV ?!?
1203 self._tlv = EF_5G_PROSE_RU.ProSeConfigDataForRemoteUe
1204
1205# TS 31.102 Section 4.4.13.7 (Rel 17)
1206class EF_5G_PROSE_UIR(TransparentEF):
1207 class CollectionPeriod(BER_TLV_IE, tag=0x94):
1208 pass
1209 class ReportingWindow(BER_TLV_IE, tag=0x95):
1210 pass
1211 class ReportingIndicators(BER_TLV_IE, tag=0x96):
1212 pass
1213 class FiveGDdnmfCtfAddrForUploading(BER_TLV_IE, tag=0x97):
1214 pass
1215 class ProSeConfigDataForUeToNetworkRelayUE(BER_TLV_IE, tag=0xa0,
1216 nested=[EF_5G_PROSE_DD.ValidityTimer,
1217 CollectionPeriod, ReportingWindow,
1218 ReportingIndicators,
1219 FiveGDdnmfCtfAddrForUploading]):
1220 pass
1221 def __init__(self, fid='4f06', sfid=0x06, name='EF.5G_PROSE_UIR',
1222 desc='5G ProSe configuration data for usage information reporting', **kwargs):
1223 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
1224 # contains TLV structure despite being TransparentEF, not BER-TLV ?!?
1225 self._tlv = EF_5G_PROSE_UIR.ProSeConfigDataForUeToNetworkRelayUE
1226
1227# TS 31.102 Section 4.4.13 (Rel 17)
1228class DF_5G_ProSe(CardDF):
1229 def __init__(self, fid='5ff0', name='DF.5G_ProSe', desc='Files for 5G ProSe purpose', **kwargs):
1230 super().__init__(fid=fid, name=name, desc=desc, **kwargs)
1231 files = [
1232 EF_5G_PROSE_ST(),
1233 EF_5G_PROSE_DD(service=1),
1234 EF_5G_PROSE_DC(service=2),
1235 EF_5G_PROSE_U2NRU(service=3),
1236 EF_5G_PROSE_RU(service=4),
1237 EF_5G_PROSE_UIR(service=5),
1238 ]
1239 self.add_files(files)
1240
1241# TS 31.102 Section 4.4.11.18 (Rel 17)
1242class EF_5GSEDRX(TransparentEF):
1243 def __init__(self, fid='4f10', sfid=0x10, name='EF.5GSEDRX',
1244 desc='5GS eDRX Parameters', **kwargs):
1245 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
1246 self._construct = Struct('5gs_rat_type'/FlagsEnum(Byte, ng_ran=1, sat_ng_ran=2),
1247 'edrx_cycle_length'/Int8ub)
1248
1249# TS 31.102 Section 4.4.11.19 (Rel 17)
1250class EF_5GNSWO_CONF(TransparentEF):
1251 def __init__(self, fid='4f11', sfid=0x11, name='EF.5GNSWO_CONF',
1252 desc='5G Non-Seamless WLAN Offload configuration', **kwargs):
1253 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
1254 self._construct = Struct('5g_nswo_usage_ind'/Enum(Byte, disabled=0, enabled=1))
1255
1256# TS 31.102 Section 4.4.11.20 (Rel 17)
1257class EF_MCHPPLMN(TransparentEF):
Harald Welte24e77a72023-05-24 15:26:29 +02001258 def __init__(self, fid='4f15', sfid=0x15, name='EF.MCHPPLMN',
Harald Weltefc67de22023-05-23 20:29:49 +02001259 desc='Multiplier Coefficient for Higher Priority PLMN search', **kwargs):
1260 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
1261 self._construct = Struct('multiplier_coefficient'/Int8ub)
1262
1263# TS 31.102 Section 4.4.11.21 (Rel 17)
1264class EF_KAUSF_DERIVATION(TransparentEF):
1265 def __init__(self, fid='4f16', sfid=0x16, name='EF.KAUSF_DERIVATION',
1266 desc='K_AUSF derivation configuration', **kwargs):
1267 super().__init__(fid, sfid=sfid, name=name, desc=desc, **kwargs)
1268 self._construct = Struct('k_ausf_deriv_cfg'/FlagsEnum(Byte, use_msk=1), 'rfu'/HexAdapter(GreedyBytes))
1269
Harald Welte3990ebb2021-04-20 23:55:14 +02001270# TS 31.102 Section 4.4.5
1271class DF_WLAN(CardDF):
Harald Welte6169c722022-02-12 09:05:15 +01001272 def __init__(self, fid='5f40', name='DF.WLAN', desc='Files for WLAN purpose', **kwargs):
1273 super().__init__(fid=fid, name=name, desc=desc, **kwargs)
Harald Welte3990ebb2021-04-20 23:55:14 +02001274 files = [
Harald Welte419bb492022-02-12 21:39:35 +01001275 TransparentEF('4f41', 0x01, 'EF.Pseudo', 'Pseudonym', service=59),
Harald Weltec91085e2022-02-10 18:05:45 +01001276 TransparentEF('4f42', 0x02, 'EF.UPLMNWLAN',
Harald Welte419bb492022-02-12 21:39:35 +01001277 'User controlled PLMN selector for I-WLAN Access', service=60),
Harald Weltec91085e2022-02-10 18:05:45 +01001278 TransparentEF('4f43', 0x03, 'EF.OPLMNWLAN',
Harald Welte419bb492022-02-12 21:39:35 +01001279 'Operator controlled PLMN selector for I-WLAN Access', service=61),
Harald Weltec91085e2022-02-10 18:05:45 +01001280 LinFixedEF('4f44', 0x04, 'EF.UWSIDL',
Harald Welte419bb492022-02-12 21:39:35 +01001281 'User controlled WLAN Specific Identifier List', service=62),
Harald Weltec91085e2022-02-10 18:05:45 +01001282 LinFixedEF('4f45', 0x05, 'EF.OWSIDL',
Harald Welte419bb492022-02-12 21:39:35 +01001283 'Operator controlled WLAN Specific Identifier List', service=63),
Harald Weltec91085e2022-02-10 18:05:45 +01001284 TransparentEF('4f46', 0x06, 'EF.WRI',
Harald Welte419bb492022-02-12 21:39:35 +01001285 'WLAN Reauthentication Identity', service=66),
Harald Weltec91085e2022-02-10 18:05:45 +01001286 LinFixedEF('4f47', 0x07, 'EF.HWSIDL',
Harald Welte419bb492022-02-12 21:39:35 +01001287 'Home I-WLAN Specific Identifier List', service=81),
Harald Weltec91085e2022-02-10 18:05:45 +01001288 TransparentEF('4f48', 0x08, 'EF.WEHPLMNPI',
Harald Welte419bb492022-02-12 21:39:35 +01001289 'I-WLAN Equivalent HPLMN Presentation Indication', service=82),
Harald Weltec91085e2022-02-10 18:05:45 +01001290 TransparentEF('4f49', 0x09, 'EF.WHPI',
Harald Welte419bb492022-02-12 21:39:35 +01001291 'I-WLAN HPLMN Priority Indication', service=83),
Harald Weltec91085e2022-02-10 18:05:45 +01001292 TransparentEF('4f4a', 0x0a, 'EF.WLRPLMN',
Harald Welte419bb492022-02-12 21:39:35 +01001293 'I-WLAN Last Registered PLMN', service=84),
Harald Weltec91085e2022-02-10 18:05:45 +01001294 TransparentEF('4f4b', 0x0b, 'EF.HPLMNDAI',
Harald Welte419bb492022-02-12 21:39:35 +01001295 'HPLMN Direct Access Indicator', service=88),
Harald Weltec91085e2022-02-10 18:05:45 +01001296 ]
Harald Welte3990ebb2021-04-20 23:55:14 +02001297 self.add_files(files)
1298
1299# TS 31.102 Section 4.4.6
1300class DF_HNB(CardDF):
Harald Welte6169c722022-02-12 09:05:15 +01001301 def __init__(self, fid='5f50', name='DF.HNB', desc='Files for HomeNodeB purpose', **kwargs):
1302 super().__init__(fid=fid, name=name, desc=desc, **kwargs)
Harald Welte3990ebb2021-04-20 23:55:14 +02001303 files = [
Harald Welteeb882052022-07-17 21:13:57 +02001304 LinFixedEF('4f81', 0x01, 'EF.ACSGL', 'Allowed CSG Lists', service=86),
1305 LinFixedEF('4f82', 0x02, 'EF.CSGTL', 'CSG Types', service=86),
1306 LinFixedEF('4f83', 0x03, 'EF.HNBN', 'Home NodeB Name', service=86),
1307 LinFixedEF('4f84', 0x04, 'EF.OCSGL', 'Operator CSG Lists', service=90),
1308 LinFixedEF('4f85', 0x05, 'EF.OCSGT', 'Operator CSG Type', service=90),
1309 LinFixedEF('4f86', 0x06, 'EF.OHNBN', 'Operator Home NodeB Name', service=90),
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.8
1314class DF_ProSe(CardDF):
Harald Welte6169c722022-02-12 09:05:15 +01001315 def __init__(self, fid='5f90', name='DF.ProSe', desc='Files for ProSe purpose', **kwargs):
1316 super().__init__(fid=fid, name=name, desc=desc, **kwargs)
Harald Welte3990ebb2021-04-20 23:55:14 +02001317 files = [
Harald Weltec91085e2022-02-10 18:05:45 +01001318 LinFixedEF('4f01', 0x01, 'EF.PROSE_MON',
1319 'ProSe Monitoring Parameters'),
1320 LinFixedEF('4f02', 0x02, 'EF.PROSE_ANN',
1321 'ProSe Announcing Parameters'),
Harald Welte3990ebb2021-04-20 23:55:14 +02001322 LinFixedEF('4f03', 0x03, 'EF.PROSEFUNC', 'HPLMN ProSe Function'),
Harald Weltec91085e2022-02-10 18:05:45 +01001323 TransparentEF('4f04', 0x04, 'EF.PROSE_RADIO_COM',
1324 'ProSe Direct Communication Radio Parameters'),
1325 TransparentEF('4f05', 0x05, 'EF.PROSE_RADIO_MON',
1326 'ProSe Direct Discovery Monitoring Radio Parameters'),
1327 TransparentEF('4f06', 0x06, 'EF.PROSE_RADIO_ANN',
1328 'ProSe Direct Discovery Announcing Radio Parameters'),
1329 LinFixedEF('4f07', 0x07, 'EF.PROSE_POLICY',
1330 'ProSe Policy Parameters'),
Harald Welte3990ebb2021-04-20 23:55:14 +02001331 LinFixedEF('4f08', 0x08, 'EF.PROSE_PLMN', 'ProSe PLMN Parameters'),
1332 TransparentEF('4f09', 0x09, 'EF.PROSE_GC', 'ProSe Group Counter'),
1333 TransparentEF('4f10', 0x10, 'EF.PST', 'ProSe Service Table'),
Harald Weltec91085e2022-02-10 18:05:45 +01001334 TransparentEF('4f11', 0x11, 'EF.UIRC',
1335 'ProSe UsageInformationReportingConfiguration'),
1336 LinFixedEF('4f12', 0x12, 'EF.PROSE_GM_DISCOVERY',
1337 'ProSe Group Member Discovery Parameters'),
1338 LinFixedEF('4f13', 0x13, 'EF.PROSE_RELAY',
1339 'ProSe Relay Parameters'),
1340 TransparentEF('4f14', 0x14, 'EF.PROSE_RELAY_DISCOVERY',
1341 'ProSe Relay Discovery Parameters'),
1342 ]
Harald Welte3990ebb2021-04-20 23:55:14 +02001343 self.add_files(files)
1344
Harald Weltec91085e2022-02-10 18:05:45 +01001345
Merlin Chlosta05ca36b2021-04-01 16:15:28 +02001346class DF_USIM_5GS(CardDF):
Harald Welte6169c722022-02-12 09:05:15 +01001347 def __init__(self, fid='5FC0', name='DF.5GS', desc='5GS related files', **kwargs):
1348 super().__init__(fid=fid, name=name, desc=desc, **kwargs)
Merlin Chlosta05ca36b2021-04-01 16:15:28 +02001349 files = [
Harald Weltec91085e2022-02-10 18:05:45 +01001350 # I'm looking at 31.102 R16.6
Harald Welte419bb492022-02-12 21:39:35 +01001351 EF_5GS3GPPLOCI(service=122),
Harald Weltec91085e2022-02-10 18:05:45 +01001352 EF_5GS3GPPLOCI('4f02', 0x02, 'EF.5GSN3GPPLOCI',
Harald Welte28accc82023-10-18 23:21:46 +02001353 desc='5GS non-3GPP location information', service=122),
Harald Welte419bb492022-02-12 21:39:35 +01001354 EF_5GS3GPPNSC(service=122),
Harald Weltec91085e2022-02-10 18:05:45 +01001355 EF_5GS3GPPNSC('4f04', 0x04, 'EF.5GSN3GPPNSC',
Harald Welte28accc82023-10-18 23:21:46 +02001356 desc='5GS non-3GPP Access NAS Security Context', service=122),
Harald Welte419bb492022-02-12 21:39:35 +01001357 EF_5GAUTHKEYS(service=123),
1358 EF_UAC_AIC(service=126),
1359 EF_SUCI_Calc_Info(service=124),
1360 EF_OPL5G(service=129),
1361 EF_SUPI_NAI(service=130),
Harald Welte455611c2023-05-27 12:48:54 +02001362 EF_Routing_Indicator(service=124),
Harald Weltec91085e2022-02-10 18:05:45 +01001363 TransparentEF('4F0B', 0x0b, 'EF.URSP',
Harald Welte28accc82023-10-18 23:21:46 +02001364 desc='UE Route Selector Policies per PLMN', service=132),
Harald Welte419bb492022-02-12 21:39:35 +01001365 EF_TN3GPPSNN(service=133),
Harald Weltefc67de22023-05-23 20:29:49 +02001366 # Rel-17 additions below
1367 EF_CAG(service=137),
1368 EF_SOR_CMCI(service=138),
1369 EF_DRI(service=140),
1370 EF_5GSEDRX(service=141),
1371 EF_5GNSWO_CONF(service=142),
1372 EF_MCHPPLMN(service=144),
1373 EF_KAUSF_DERIVATION(service=145),
Merlin Chlosta05ca36b2021-04-01 16:15:28 +02001374 ]
Merlin Chlosta05ca36b2021-04-01 16:15:28 +02001375 self.add_files(files)
1376
Harald Weltec91085e2022-02-10 18:05:45 +01001377
Harald Welte2bee70c2023-05-25 09:14:28 +02001378class DF_SAIP(CardDF):
1379 """This is not really TS 31.102 but part of the eUICC Profile Package: Interoperable Format Technical
1380 Specification as released by TCA (formerly SIMalliance)"""
1381 def __init__(self, fid='5FD0', name='DF.SAIP', desc='SIMalliance Interoperable Profile', **kwargs):
1382 super().__init__(fid=fid, name=name, desc=desc, **kwargs)
1383 files = [
1384 # uses the same file format as DF.5GS/EF_SUCI_Calc_Info, but different FID
1385 EF_SUCI_Calc_Info(fid='4f01')
1386 ]
1387 self.add_files(files)
1388
1389
Harald Welteb2edd142021-01-08 23:29:35 +01001390class ADF_USIM(CardADF):
Philipp Maiera1850ae2023-10-25 18:05:09 +02001391 def __init__(self, aid='a0000000871002', has_fs=True, name='ADF.USIM', fid=None, sfid=None,
Harald Welteb2edd142021-01-08 23:29:35 +01001392 desc='USIM Application'):
Philipp Maiera1850ae2023-10-25 18:05:09 +02001393 super().__init__(aid=aid, has_fs=has_fs, fid=fid, sfid=sfid, name=name, desc=desc)
Harald Welte15fae982021-04-10 10:22:27 +02001394 # add those commands to the general commands of a TransparentEF
1395 self.shell_commands += [self.AddlShellCommands()]
Harald Welteb2edd142021-01-08 23:29:35 +01001396
1397 files = [
Harald Weltec91085e2022-02-10 18:05:45 +01001398 EF_LI(sfid=0x02),
1399 EF_IMSI(sfid=0x07),
1400 EF_Keys(),
1401 EF_Keys('6f09', 0x09, 'EF.KeysPS',
1402 desc='Ciphering and Integrity Keys for PS domain'),
1403 EF_xPLMNwAcT('6f60', 0x0a, 'EF.PLMNwAcT',
Harald Welte509ecf82023-10-18 23:32:57 +02001404 desc='User controlled PLMN Selector with Access Technology', service=20),
Harald Weltec91085e2022-02-10 18:05:45 +01001405 EF_HPPLMN(),
Harald Welte6169c722022-02-12 09:05:15 +01001406 EF_ACMmax(service=13),
Harald Welte6ca2fa72022-02-12 16:29:31 +01001407 EF_UST(),
Harald Weltec91085e2022-02-10 18:05:45 +01001408 CyclicEF('6f39', None, 'EF.ACM',
Harald Welte509ecf82023-10-18 23:32:57 +02001409 desc='Accumulated call meter', rec_len=(3, 3), service=13),
1410 TransparentEF('6f3e', None, 'EF.GID1', desc='Group Identifier Level 1', service=17),
1411 TransparentEF('6f3f', None, 'EF.GID2', desc='Group Identifier Level 2', service=18),
Harald Welte6169c722022-02-12 09:05:15 +01001412 EF_SPN(service=19),
Harald Weltec91085e2022-02-10 18:05:45 +01001413 TransparentEF('6f41', None, 'EF.PUCT',
Harald Welte509ecf82023-10-18 23:32:57 +02001414 desc='Price per unit and currency table', size=(5, 5), service=13),
Harald Welte6169c722022-02-12 09:05:15 +01001415 EF_CBMI(service=15),
Harald Weltec91085e2022-02-10 18:05:45 +01001416 EF_ACC(sfid=0x06),
Harald Welte509ecf82023-10-18 23:32:57 +02001417 EF_PLMNsel('6f7b', 0x0d, 'EF.FPLMN', desc='Forbidden PLMNs', size=(12, None)),
Harald Weltec91085e2022-02-10 18:05:45 +01001418 EF_LOCI(),
1419 EF_AD(),
Harald Welte6169c722022-02-12 09:05:15 +01001420 EF_CBMID(sfid=0x0e, service=29),
Harald Weltec91085e2022-02-10 18:05:45 +01001421 EF_ECC(),
Harald Welte6169c722022-02-12 09:05:15 +01001422 EF_CBMIR(service=16),
Harald Weltec91085e2022-02-10 18:05:45 +01001423 EF_PSLOCI(),
Harald Welte509ecf82023-10-18 23:32:57 +02001424 EF_ADN('6f3b', None, 'EF.FDN', desc='Fixed Dialling Numbers', service=[2, 89], ext=2),
Harald Welte6169c722022-02-12 09:05:15 +01001425 EF_SMS('6f3c', None, service=10),
1426 EF_MSISDN(service=21),
1427 EF_SMSP(service=12),
1428 EF_SMSS(service=10),
Harald Welte509ecf82023-10-18 23:32:57 +02001429 EF_ADN('6f49', None, 'EF.SDN', desc='Service Dialling Numbers', service=[4, 89], ext=3),
1430 EF_EXT('6f4b', None, 'EF.EXT2', desc='Extension2 (FDN)', service=3),
1431 EF_EXT('6f4c', None, 'EF.EXT3', desc='Extension2 (SDN)', service=5),
Harald Welte6169c722022-02-12 09:05:15 +01001432 EF_SMSR(service=11),
1433 EF_ICI(service=9),
1434 EF_OCI(service=8),
1435 EF_ICT(service=9),
Harald Welte509ecf82023-10-18 23:32:57 +02001436 EF_ICT('6f83', None, 'EF.OCT', desc='Outgoing Call Timer', service=8),
1437 EF_EXT('6f4e', None, 'EF.EXT5', desc='Extension5 (ICI/OCI/MSISDN)', service=44),
Harald Welte6169c722022-02-12 09:05:15 +01001438 EF_CCP2(service=14),
1439 EF_eMLPP(service=24),
1440 EF_AAeM(service=25),
Harald Weltec91085e2022-02-10 18:05:45 +01001441 # EF_Hiddenkey
Harald Welte509ecf82023-10-18 23:32:57 +02001442 EF_ADN('6f4d', None, 'EF.BDN', desc='Barred Dialling Numbers', service=6, ext=4),
1443 EF_EXT('6f55', None, 'EF.EXT4', desc='Extension4 (BDN/SSC)', service=7),
Harald Welte6169c722022-02-12 09:05:15 +01001444 EF_CMI(service=6),
Harald Welte6ca2fa72022-02-12 16:29:31 +01001445 EF_EST(service=[2, 6, 34, 35]),
Harald Welte6169c722022-02-12 09:05:15 +01001446 EF_ACL(service=35),
1447 EF_DCK(service=36),
1448 EF_CNL(service=37),
Harald Weltec91085e2022-02-10 18:05:45 +01001449 EF_START_HFN(),
1450 EF_THRESHOLD(),
Harald Welte509ecf82023-10-18 23:32:57 +02001451 EF_xPLMNwAcT('6f61', 0x11, 'EF.OPLMNwAcT', desc='User controlled PLMN Selector with Access Technology', service=42),
1452 EF_xPLMNwAcT('6f62', 0x13, 'EF.HPLMNwAcT', desc='HPLMN Selector with Access Technology', service=43),
Harald Weltec91085e2022-02-10 18:05:45 +01001453 EF_ARR('6f06', 0x17),
Harald Welte363edd92022-07-17 22:24:03 +02001454 EF_RPLMNAcT(),
Harald Welte509ecf82023-10-18 23:32:57 +02001455 TransparentEF('6fc4', None, 'EF.NETPAR', desc='Network Parameters'),
Harald Welte6169c722022-02-12 09:05:15 +01001456 EF_PNN('6fc5', 0x19, service=45),
1457 EF_OPL(service=46),
Harald Welte509ecf82023-10-18 23:32:57 +02001458 EF_ADN('6fc7', None, 'EF.MBDN', desc='Mailbox Dialling Numbers', service=47, ext=6),
1459 EF_EXT('6fc8', None, 'EF.EXT6', desc='Extension6 (MBDN)'),
Harald Welte6169c722022-02-12 09:05:15 +01001460 EF_MBI(service=47),
1461 EF_MWIS(service=48),
Harald Welte509ecf82023-10-18 23:32:57 +02001462 EF_ADN('6fcb', None, 'EF.CFIS', desc='Call Forwarding Indication Status', service=49, ext=7),
1463 EF_EXT('6fcc', None, 'EF.EXT7', desc='Extension7 (CFIS)'),
1464 TransparentEF('6fcd', None, 'EF.SPDI', desc='Service Provider Display Information', service=51),
Harald Welte6169c722022-02-12 09:05:15 +01001465 EF_MMSN(service=52),
Harald Welte509ecf82023-10-18 23:32:57 +02001466 EF_EXT('6fcf', None, 'EF.EXT8', desc='Extension8 (MMSN)', service=53),
Harald Welte6169c722022-02-12 09:05:15 +01001467 EF_MMSICP(service=52),
1468 EF_MMSUP(service=52),
1469 EF_MMSUCP(service=(52, 55)),
Harald Welte04bd5142023-05-24 15:23:53 +02001470 EF_NIA(service=56, fid='6fd3'),
Harald Welte6169c722022-02-12 09:05:15 +01001471 EF_VGCS(service=57),
1472 EF_VGCSS(service=57),
Harald Welte509ecf82023-10-18 23:32:57 +02001473 EF_VGCS('6fb3', None, 'EF.VBS', desc='Voice Broadcast Service', service=58),
1474 EF_VGCSS('6fb4', None, 'EF.VBSS', desc='Voice Broadcast Service Status', service=58),
Harald Welte6169c722022-02-12 09:05:15 +01001475 EF_VGCSCA(service=64),
Harald Welte509ecf82023-10-18 23:32:57 +02001476 EF_VGCSCA('6fd5', None, 'EF.VBCSCA', desc='Voice Broadcast Service Ciphering Algorithm', service=65),
Harald Welte6169c722022-02-12 09:05:15 +01001477 EF_GBABP(service=68),
1478 EF_MSK(service=69),
1479 EF_MUK(service=69),
1480 EF_GBANL(service=68),
Harald Welte509ecf82023-10-18 23:32:57 +02001481 EF_PLMNsel('6fd9', 0x1d, 'EF.EHPLMN', desc='Equivalent HPLMN', size=(12, None), service=71),
Harald Welte6169c722022-02-12 09:05:15 +01001482 EF_EHPLMNPI(service=(71, 73)),
1483 # EF_LRPLMNSI ('6fdc', service=74)
1484 EF_NAFKCA(service=(68, 76)),
Harald Welte509ecf82023-10-18 23:32:57 +02001485 TransparentEF('6fde', None, 'EF.SPNI', desc='Service Provider Name Icon', service=78),
1486 LinFixedEF('6fdf', None, 'EF.PNNI', desc='PLMN Network Name Icon', service=79),
Harald Welte6169c722022-02-12 09:05:15 +01001487 EF_NCP_IP(service=80),
Harald Welte509ecf82023-10-18 23:32:57 +02001488 EF_EPSLOCI('6fe3', 0x1e, 'EF.EPSLOCI', desc='EPS location information', service=85),
Harald Welte6169c722022-02-12 09:05:15 +01001489 EF_EPSNSC(service=85),
Harald Welte509ecf82023-10-18 23:32:57 +02001490 TransparentEF('6fe6', None, 'EF.UFC', desc='USAT Facility Control', size=(1, 16)),
1491 TransparentEF('6fe8', None, 'EF.NASCONFIG', desc='Non Access Stratum Configuration', service=96),
Harald Welte6169c722022-02-12 09:05:15 +01001492 # UICC IARI (only in cards that have no ISIM) service=95
1493 EF_PWS(service=97),
Harald Welte509ecf82023-10-18 23:32:57 +02001494 LinFixedEF('6fed', None, 'EF.FDNURI', desc='Fixed Dialling Numbers URI', service=(2, 99)),
1495 LinFixedEF('6fee', None, 'EF.BDNURI', desc='Barred Dialling Numbers URI', service=(6, 99)),
1496 LinFixedEF('6fef', None, 'EF.SDNURI', desc='Service Dialling Numbers URI', service=(4, 99)),
Harald Welte6169c722022-02-12 09:05:15 +01001497 # EF_IWL (IMEI(SV) White List)
Harald Weltec91085e2022-02-10 18:05:45 +01001498 EF_IPS(),
Harald Welte6169c722022-02-12 09:05:15 +01001499 EF_ePDGId(service=(106, 107)),
Harald Weltecdfe1c22023-12-08 12:30:21 +01001500 EF_ePDGSelection(service=(106, 107)),
Harald Welte5277b5c2023-12-08 12:22:28 +01001501 EF_ePDGId('6ff5', None, 'EF.ePDGIdEm', desc='Emergency ePDG Identifier', service=(110, 111)),
Harald Weltecdfe1c22023-12-08 12:30:21 +01001502 EF_ePDGSelection('6ff6', None, 'EF.ePDGSelectionEm',
1503 desc='ePDG Selection Information for Emergency Services', service=(110, 111)),
Harald Welte6169c722022-02-12 09:05:15 +01001504 EF_FromPreferred(service=114),
Harald Weltefc67de22023-05-23 20:29:49 +02001505 EF_eAKA(),
Harald Welte6169c722022-02-12 09:05:15 +01001506 # FIXME: DF_SoLSA service=23
Harald Weltede4c14c2022-07-16 11:53:59 +02001507 DF_PHONEBOOK(),
Harald Welted90ceb82022-07-17 22:10:58 +02001508 DF_GSM_ACCESS(),
Harald Welte6169c722022-02-12 09:05:15 +01001509 DF_WLAN(service=[59, 60, 61, 62, 63, 66, 81, 82, 83, 84, 88]),
1510 DF_HNB(service=[86, 90]),
1511 DF_ProSe(service=101),
1512 # FIXME: DF_ACDC service=108
1513 # FIXME: DF_TV service=116
1514 DF_USIM_5GS(service=[122, 123, 124, 125, 126, 127, 129, 130]),
Harald Weltefc67de22023-05-23 20:29:49 +02001515 DF_SNPN(service=[143,146]),
1516 DF_5G_ProSe(service=139),
Harald Welte2bee70c2023-05-25 09:14:28 +02001517 DF_SAIP(),
Harald Weltec91085e2022-02-10 18:05:45 +01001518 ]
Harald Welteb2edd142021-01-08 23:29:35 +01001519 self.add_files(files)
1520
1521 def decode_select_response(self, data_hex):
Philipp Maier5998a3a2021-11-16 15:16:39 +01001522 return pySim.ts_102_221.CardProfileUICC.decode_select_response(data_hex)
Harald Welteb2edd142021-01-08 23:29:35 +01001523
Harald Welte15fae982021-04-10 10:22:27 +02001524 @with_default_category('Application-Specific Commands')
1525 class AddlShellCommands(CommandSet):
1526 def __init__(self):
1527 super().__init__()
1528
1529 authenticate_parser = argparse.ArgumentParser()
1530 authenticate_parser.add_argument('rand', help='Random challenge')
1531 authenticate_parser.add_argument('autn', help='Authentication Nonce')
1532 #authenticate_parser.add_argument('--context', help='Authentication context', default='3G')
Harald Weltec91085e2022-02-10 18:05:45 +01001533
Harald Welte15fae982021-04-10 10:22:27 +02001534 @cmd2.with_argparser(authenticate_parser)
1535 def do_authenticate(self, opts):
1536 """Perform Authentication and Key Agreement (AKA)."""
Harald Welte46255122023-10-21 23:40:42 +02001537 (data, sw) = self._cmd.lchan.scc.authenticate(opts.rand, opts.autn)
Harald Welte15fae982021-04-10 10:22:27 +02001538 self._cmd.poutput_json(data)
1539
Harald Welte12af7932022-02-15 16:39:08 +01001540 term_prof_parser = argparse.ArgumentParser()
1541 term_prof_parser.add_argument('PROFILE', help='Hexstring of encoded terminal profile')
1542
1543 @cmd2.with_argparser(term_prof_parser)
Harald Welte51b3abb2022-07-30 16:30:33 +02001544 def do_terminal_profile(self, opts):
Harald Welte12af7932022-02-15 16:39:08 +01001545 """Send a TERMINAL PROFILE command to the card.
1546 This is used to inform the card about which optional
1547 features the terminal (modem/phone) supports, particularly
1548 in the context of SIM Toolkit, Proactive SIM and OTA. You
1549 must specify a hex-string with the encoded terminal profile
1550 you want to send to the card."""
Harald Welte46255122023-10-21 23:40:42 +02001551 (data, sw) = self._cmd.lchan.scc.terminal_profile(opts.PROFILE)
Harald Welte846a8982021-10-08 15:47:16 +02001552 self._cmd.poutput('SW: %s, data: %s' % (sw, data))
Harald Welte15fae982021-04-10 10:22:27 +02001553
Harald Welte12af7932022-02-15 16:39:08 +01001554 envelope_parser = argparse.ArgumentParser()
1555 envelope_parser.add_argument('PAYLOAD', help='Hexstring of encoded payload to ENVELOPE')
1556
1557 @cmd2.with_argparser(envelope_parser)
Harald Welte51b3abb2022-07-30 16:30:33 +02001558 def do_envelope(self, opts):
Harald Welte12af7932022-02-15 16:39:08 +01001559 """Send an ENVELOPE command to the card. This is how a
1560 variety of information is communicated from the terminal
1561 (modem/phone) to the card, particularly in the context of
1562 SIM Toolkit, Proactive SIM and OTA."""
Harald Welte46255122023-10-21 23:40:42 +02001563 (data, sw) = self._cmd.lchan.scc.envelope(opts.PAYLOAD)
Harald Welte7cb94e42021-10-08 15:47:57 +02001564 self._cmd.poutput('SW: %s, data: %s' % (sw, data))
1565
Harald Welte12af7932022-02-15 16:39:08 +01001566 envelope_sms_parser = argparse.ArgumentParser()
1567 envelope_sms_parser.add_argument('TPDU', help='Hexstring of encoded SMS TPDU')
1568
1569 @cmd2.with_argparser(envelope_sms_parser)
Harald Welte51b3abb2022-07-30 16:30:33 +02001570 def do_envelope_sms(self, opts):
Harald Welte12af7932022-02-15 16:39:08 +01001571 """Send an ENVELOPE(SMS-PP-Download) command to the card.
1572 This emulates a terminal (modem/phone) having received a SMS
1573 with a PID of 'SMS for the SIM card'. You can use this
1574 command in the context of testing OTA related features
Philipp Maier4e5aa302023-06-06 19:22:19 +02001575 without a modem/phone or a cellular network."""
Harald Welte7cb94e42021-10-08 15:47:57 +02001576 tpdu_ie = SMS_TPDU()
Harald Welte51b3abb2022-07-30 16:30:33 +02001577 tpdu_ie.from_bytes(h2b(opts.TPDU))
Harald Weltec91085e2022-02-10 18:05:45 +01001578 dev_ids = DeviceIdentities(
1579 decoded={'source_dev_id': 'network', 'dest_dev_id': 'uicc'})
Harald Welte7cb94e42021-10-08 15:47:57 +02001580 sms_dl = SMSPPDownload(children=[dev_ids, tpdu_ie])
Harald Welte46255122023-10-21 23:40:42 +02001581 (data, sw) = self._cmd.lchan.scc.envelope(b2h(sms_dl.to_tlv()))
Harald Welte7cb94e42021-10-08 15:47:57 +02001582 self._cmd.poutput('SW: %s, data: %s' % (sw, data))
1583
Harald Welte7ec82232023-06-06 18:15:52 +02001584 get_id_parser = argparse.ArgumentParser()
1585 get_id_parser.add_argument("--nswo-context", action='store_true')
1586
1587 @cmd2.with_argparser(get_id_parser)
1588 def do_get_identity(self, opts):
1589 """Send a GET IDENTITY command to the card. This is part of the
1590 procedure for "SUCI calculation performed on USIM" supported
1591 by USIM with support for both EF.UST service 124 and 125."""
1592 context = 0x01 # SUCI
1593 if opts.nswo_context:
1594 context = 0x02 # SUCI 5G NSWO
Harald Welte46255122023-10-21 23:40:42 +02001595 (data, sw) = self._cmd.lchan.scc.get_identity(context)
Harald Welte7ec82232023-06-06 18:15:52 +02001596 do = SUCI_TlvDataObject()
1597 do.from_tlv(h2b(data))
1598 do_d = do.to_dict()
1599 self._cmd.poutput('SUCI TLV Data Object: %s' % do_d['suci__tlv_data_object'])
1600
Harald Welte15fae982021-04-10 10:22:27 +02001601
Harald Welteb2edd142021-01-08 23:29:35 +01001602# TS 31.102 Section 7.3
1603sw_usim = {
1604 'Security management': {
1605 '9862': 'Authentication error, incorrect MAC',
1606 '9864': 'Authentication error, security context not supported',
1607 '9865': 'Key freshness failure',
1608 '9866': 'Authentication error, no memory space available',
1609 '9867': 'Authentication error, no memory space available in EF MUK',
1610 }
1611}
1612
Harald Weltec91085e2022-02-10 18:05:45 +01001613
Philipp Maier57f65ee2021-10-18 14:09:02 +02001614class CardApplicationUSIM(CardApplication):
1615 def __init__(self):
Harald Weltec91085e2022-02-10 18:05:45 +01001616 super().__init__('USIM', adf=ADF_USIM(), sw=sw_usim)