blob: d41e03514a427b9abbe9f0999b48cb0ae33304dc [file] [log] [blame]
Harald Welte9419c8a2017-07-30 04:07:05 +02001/* Encoding/Decoding routines for GSM System Information messages
Harald Welte34b5a952019-05-27 11:54:11 +02002 * according to 3GPP TS 44.018 Version 12.3.0 Release 12
3 *
4 * (C) 2017-2019 Harald Welte <laforge@gnumonks.org>
5 * All rights reserved.
6 *
7 * Released under the terms of GNU General Public License, Version 2 or
8 * (at your option) any later version.
9 *
10 * SPDX-License-Identifier: GPL-2.0-or-later
11 */
Harald Welte9419c8a2017-07-30 04:07:05 +020012
13module GSM_RR_Types {
14
15 import from General_Types all;
16 import from Osmocom_Types all;
17 import from GSM_Types all;
Vadim Yanitskiy150d6d12022-10-20 19:10:04 +070018 import from GSM_RestOctets all;
Harald Welte9419c8a2017-07-30 04:07:05 +020019 import from RLCMAC_CSN1_Types all;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +070020 import from MobileL3_CommonIE_Types all;
Vadim Yanitskiy27b38012020-09-01 05:14:46 +070021 import from MobileL3_RRM_Types all;
Harald Welte9419c8a2017-07-30 04:07:05 +020022
23 /* Table 10.4.1 of Section 10.4 / 3GPP TS 44.018 */
24 type enumerated RrMessageType {
25 ADDITIONAL_ASSIGNMENT ('00111011'B),
26 IMMEDIATE_ASSIGNMENT ('00111111'B),
27 IMMEDIATE_ASSIGNMENT_EXTENDED ('00111001'B),
28 IMMEDIATE_ASSIGNMENT_REJECT ('00111010'B),
29 IMMEDIATE_PACKET_ASSIGNMENT ('01101001'B),
30
31 CIPHERING_MODE_COMMAND ('00110101'B),
32 CIPHERING_MODE_COMPLETE ('00110010'B),
33
34 CONFIGURATION_CHANGE_COMMAND ('00110000'B),
35 CONFIGURATION_CHANGE_ACK ('00110001'B),
36 CONFIGURATION_CHANGE_REJECT ('00110011'B),
37
38 ASSIGNMENT_COMMAND ('00101110'B),
39 ASSIGNMENT_COMPLETE ('00101001'B),
40 ASSIGNMENT_FAILURE ('00101111'B),
41 HANDOVER_COMMAND ('00101011'B),
42 HANDOVER_COMPLETE ('00101100'B),
43 HANDOVER_FAILURE ('00101000'B),
44 PHYSICAL_INFORMATION ('00101101'B),
45
46 CHANNEL_RELEASE ('00001101'B),
47 PARTIAL_RELEASE ('00001010'B),
48 PARTIAL_RELEASE_COMPLETE ('00001111'B),
49
50 PAGING_REQUEST_TYPE_1 ('00100001'B),
51 PAGING_REQUEST_TYPE_2 ('00100010'B),
52 PAGING_REQUEST_TYPE_3 ('00100100'B),
53 PAGING_RESPONSE ('00100111'B),
54 NOTIFICATION_NCH ('00100000'B),
55 NOTIFICATION_RESPOSNE ('00100110'B),
56
57 SYSTEM_INFORMATION_TYPE_8 ('00011000'B),
58 SYSTEM_INFORMATION_TYPE_1 ('00011001'B),
59 SYSTEM_INFORMATION_TYPE_2 ('00011010'B),
60 SYSTEM_INFORMATION_TYPE_3 ('00011011'B),
61 SYSTEM_INFORMATION_TYPE_4 ('00011100'B),
62 SYSTEM_INFORMATION_TYPE_5 ('00011101'B),
63 SYSTEM_INFORMATION_TYPE_6 ('00011110'B),
64 SYSTEM_INFORMATION_TYPE_7 ('00011111'B),
65 SYSTEM_INFORMATION_TYPE_2bis ('00000010'B),
66 SYSTEM_INFORMATION_TYPE_2ter ('00000011'B),
67 SYSTEM_INFORMATION_TYPE_2quater ('00000111'B),
68 SYSTEM_INFORMATION_TYPE_5bis ('00000101'B),
69 SYSTEM_INFORMATION_TYPE_5ter ('00000110'B),
70 SYSTEM_INFORMATION_TYPE_9 ('00000100'B),
71 SYSTEM_INFORMATION_TYPE_13 ('00000000'B),
72
73 SYSTEM_INFORMATION_TYPE_16 ('00111101'B),
74 SYSTEM_INFORMATION_TYPE_17 ('00111110'B),
75
76 CHANNEL_MODE_MODIFY ('00010000'B),
77 RR_STATUS ('00010010'B),
78 CHANNEL_MODE_MODIFY_ACKNOWLEDGE ('00010111'B),
79 FREQUENCY_REDEFINITION ('00010100'B),
80 MEASUREMENT_REPORT ('00010101'B),
81 CLASSMARK_CHANGE ('00010110'B),
82 CLASSMARK_ENQUIRY ('00010011'B),
83 EXTENDED_MEASUREMENT_REPORT ('00110110'B),
84 EXTENDED_MEASUREMENT_ORDER ('00110111'B),
85 GPRS_SUSPENSION_REQUEST ('00110100'B),
86 //MBMS_ANNOUNCEMENT ('00010110'B), duplicate?
87 //SERVICE_INFORMATION ('00110110'B), duplicate?
88
89 APPLICATION_INFORMATION ('00111000'B),
90
91 SYSTEM_INFORMATION_TYPE_14 ('00000001'B),
92 SYSTEM_INFORMATION_TYPE_15 ('01000011'B),
93 SYSTEM_INFORMATION_TYPE_18 ('01000000'B),
94 SYSTEM_INFORMATION_TYPE_19 ('01000001'B),
95 SYSTEM_INFORMATION_TYPE_20 ('01000010'B),
96 SYSTEM_INFORMATION_TYPE_13alt ('01000100'B),
97 SYSTEM_INFORMATION_TYPE_2n ('01000101'B),
98 SYSTEM_INFORMATION_TYPE_21 ('01000110'B),
99 SYSTEM_INFORMATION_TYPE_22 ('01000111'B),
100 SYSTEM_INFORMATION_TYPE_23 ('01001111'B),
101
102 DTM_ASSIGNMENT_FAILURE ('01001000'B),
103 DTM_REJECT ('01001001'B),
104 DTM_REQUEST ('01001010'B),
105 PACKET_ASSIGNMENT ('01001011'B),
106 DTM_ASSIGNMENT_COMMAND ('01001100'B),
107 DTM_INFORMATION ('01001101'B),
108 PACKET_INFORMATION ('01001110'B),
109
110 UTRAN_CLASSMARK_CHANGE ('01100000'B),
111 CDMA2000_CLASSMARK_CHANGE ('01100010'B),
112 INTERSYS_TO_UTRAN_HO_CMD ('01100011'B),
113 INTERSYS_TO_CDMA2000_HO_CMD ('01100100'B),
114 GERAN_IU_MODE_CLASSMARK_CHG ('01100101'B),
115 INTERSYS_TO_EUTRAN_HO_CMD ('01100110'B)
116 } with { variant "FIELDLENGTH(8)" };
117
Max6c00a382023-01-30 16:29:55 +0300118 /* Table 10.4.2 of Section 10.4 / 3GPP TS 44.018 */
119 type enumerated RrShortDisc {
120 SYSTEM_INFORMATION_TYPE_10 ('00000'B),
121 NOTIFICATION_FACCH ('00001'B),
122 UPLINK_FREE ('00010'B),
123 ENHAN_MEAS_REP_UL ('00100'B),
124 MEAS_INFO_DL ('00101'B),
125 VBS_VGCS_RECON ('00110'B),
126 VBS_VGCS_RECON2 ('00111'B),
127 VGCS_ADD_INFO ('01000'B),
128 VGCS_SMS_INFO ('01001'B),
129 SYSTEM_INFORMATION_TYPE_10bis ('01010'B),
130 SYSTEM_INFORMATION_TYPE_10ter ('01011'B),
131 VGCS_NEIGH_CELL_INFO ('01100'B),
132 NOTIFY_APP_DATA ('01101'B)
133 } with { variant "FIELDLENGTH(5)" };
134
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +0200135 type enumerated RR_Cause {
136 GSM48_RR_CAUSE_NORMAL ('00'O),
137 GSM48_RR_CAUSE_ABNORMAL_UNSPEC ('01'O),
138 GSM48_RR_CAUSE_ABNORMAL_UNACCT ('02'O),
139 GSM48_RR_CAUSE_ABNORMAL_TIMER ('03'O),
140 GSM48_RR_CAUSE_ABNORMAL_NOACT ('04'O),
141 GSM48_RR_CAUSE_PREMPTIVE_REL ('05'O),
142 GSM48_RR_CAUSE_HNDOVER_IMP ('08'O),
143 GSM48_RR_CAUSE_CHAN_MODE_UNACCT ('09'O),
144 GSM48_RR_CAUSE_FREQ_NOT_IMPL ('0a'O),
145 GSM48_RR_CAUSE_CALL_CLEARED ('41'O),
146 GSM48_RR_CAUSE_SEMANT_INCORR ('5f'O),
147 GSM48_RR_CAUSE_INVALID_MAND_INF ('60'O),
148 GSM48_RR_CAUSE_MSG_TYPE_N ('61'O),
149 GSM48_RR_CAUSE_MSG_TYPE_N_COMPAT('62'O),
150 GSM48_RR_CAUSE_COND_IE_ERROR ('64'O),
151 GSM48_RR_CAUSE_NO_CELL_ALLOC_A ('65'O),
152 GSM48_RR_CAUSE_PROT_ERROR_UNSPC ('6f'O)
153 } with { variant "FIELDLENGTH(8)" };
154
Harald Welte9419c8a2017-07-30 04:07:05 +0200155 type octetstring RestOctets with { variant "PADDING(yes), PADDING_PATTERN('00101011'B)" };
Harald Welte9419c8a2017-07-30 04:07:05 +0200156
157 type record L2PseudoLength {
158 uint6_t l2_plen,
159 BIT2 zero_one
160 } with { variant "" };
161
Harald Weltef8df4cb2018-03-10 15:15:08 +0100162 template L2PseudoLength tr_L2Pseudolength(template uint6_t len) := {
163 l2_plen := len,
164 zero_one := '01'B
165 };
166
167 template (value) L2PseudoLength ts_L2Pseudolength(uint6_t len) := {
Harald Welte9419c8a2017-07-30 04:07:05 +0200168 l2_plen := len,
169 zero_one := '01'B
170 };
171
172 type record RrHeader {
173 L2PseudoLength l2_plen,
174 uint4_t skip_indicator,
175 uint4_t rr_protocol_discriminator,
176 RrMessageType message_type
177 } with { variant "" };
178
179 template RrHeader t_RrHeader(RrMessageType msg_type, template uint6_t len) := {
Harald Weltef8df4cb2018-03-10 15:15:08 +0100180 l2_plen := tr_L2Pseudolength(len),
Harald Welte9419c8a2017-07-30 04:07:05 +0200181 skip_indicator := 0,
182 rr_protocol_discriminator := 6,
183 message_type := msg_type
184 };
185
Harald Weltef8df4cb2018-03-10 15:15:08 +0100186 template (value) RrHeader ts_RrHeader(RrMessageType msg_type, uint6_t len) := {
187 l2_plen := ts_L2Pseudolength(len),
188 skip_indicator := 0,
189 rr_protocol_discriminator := 6,
190 message_type := msg_type
191 };
192
193
Harald Welte9419c8a2017-07-30 04:07:05 +0200194 type record RrL3Header {
195 uint4_t skip_indicator,
196 uint4_t rr_protocol_discriminator,
197 RrMessageType message_type
198 } with { variant "" };
199
Harald Weltecbc947f2018-02-22 00:26:55 +0100200 template RrL3Header t_RrL3Header(RrMessageType msg_type) := {
201 skip_indicator := 0,
202 rr_protocol_discriminator := 6,
203 message_type := msg_type
204 }
205
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200206 /* TS 44.004 7.2.1 */
207 type record SacchL1Header {
208 uint2_t reserved,
209 boolean fpc,
210 uint5_t ms_power_lvl,
211 uint8_t actual_ta
212 } with { variant "FIELDORDER(msb)" };
213
Vadim Yanitskiy79da4ce2020-10-17 15:48:47 +0700214 external function enc_SacchL1Header(in SacchL1Header hdr) return octetstring
215 with { extension "prototype(convert) encode(RAW)" };
216 external function dec_SacchL1Header(in octetstring stream) return SacchL1Header
217 with { extension "prototype(convert) decode(RAW)" };
218
Vadim Yanitskiy68c4cff2022-07-30 23:45:02 +0700219 template (value) SacchL1Header
220 ts_SacchL1Header(uint5_t ms_power_lvl,
221 uint8_t actual_ta,
222 boolean fpc := false) := {
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200223 reserved := 0,
224 fpc := fpc,
225 ms_power_lvl := ms_power_lvl,
226 actual_ta := actual_ta
227 };
228
Harald Welte9419c8a2017-07-30 04:07:05 +0200229 type record MaioHsn {
Vadim Yanitskiyff0072c2020-05-27 01:35:39 +0700230 uint6_t maio,
231 uint6_t hsn
Harald Welte9419c8a2017-07-30 04:07:05 +0200232 } with { variant "" };
233
Vadim Yanitskiy5bcd9192020-07-06 20:18:11 +0700234 /* It's more handy to pass HSN first, so the arguments' order is reversed. */
235 template (value) MaioHsn ts_HsnMaio(template (value) uint6_t hsn,
236 template (value) uint6_t maio) := {
237 maio := maio,
238 hsn := hsn
239 };
240 template MaioHsn tr_HsnMaio(template (present) uint6_t hsn,
241 template (present) uint6_t maio) := {
242 maio := maio,
243 hsn := hsn
244 };
245
Harald Welte9419c8a2017-07-30 04:07:05 +0200246 /* TS 24.008 10.5.1.2 */
247 type uint4_t CipheringKeySeqNr (0..7);
248
Harald Welte9419c8a2017-07-30 04:07:05 +0200249 /* TS 24.008 10.5.1.4 */
250 type enumerated MobileIdentityType {
251 MI_TYPE_NONE (0),
252 MI_TYPE_IMSI,
253 MI_TYPE_IMEI,
254 MI_TYPE_IMEISV,
255 MI_TYPE_TMSI,
256 MI_TYPE_TMGI
257 } with { variant "FIELDLENGTH(3)" };
258
Harald Welte9419c8a2017-07-30 04:07:05 +0200259 /* TS 24.008 10.5.1.5 */
260 type record MsClassmark1 {
261 BIT1 spare,
262 uint2_t rev_level,
263 boolean es_ind,
264 boolean a51,
265 uint3_t rf_pwr_cap
266 } with { variant "" };
267
268 /* TS 24.008 10.5.1.6 */
269 type record MsClassmark2 {
270 BIT1 spare,
271 uint2_t rev_level,
272 boolean es_ind,
273 boolean a51,
274 uint3_t rf_pwr_cap,
275 BIT1 spare1,
276 boolean ps_cap,
277 uint2_t ss_screen_ind,
278 boolean sm_cap,
279 boolean vbs,
280 boolean vgcs,
281 boolean fc,
282 boolean cm3,
283 BIT1 spare2,
284 boolean lcsva_cap,
285 boolean ucs2,
286 boolean solsa,
287 boolean cmsp,
288 boolean a53,
289 boolean a52
290 } with { variant "" };
291 type record MsClassmark2LV {
292 uint8_t len,
293 MsClassmark2 cm2
294 } with { variant (len) "LENGTHTO(cm2)" };
295
296
297 /* 44.018 10.5.2.5 */
298 type record ChannelDescription {
299 RslChannelNr chan_nr,
300 uint3_t tsc,
301 boolean h,
302 uint12_t arfcn optional,
303 MaioHsn maio_hsn optional
304 } with { variant (arfcn) "PRESENCE(h = false)"
305 variant (maio_hsn) "PRESENCE(h = true)" };
306
307 type record ChannelDescriptionTV {
308 OCT1 iei,
309 ChannelDescription v
310 } with { variant "" };
311
312 /* 10.5.2.21 */
Vadim Yanitskiy3b464a92020-08-25 03:55:32 +0700313 type record MobileAllocationLV {
Harald Welte9419c8a2017-07-30 04:07:05 +0200314 uint8_t len,
Vadim Yanitskiy7d6eef32020-08-29 02:56:58 +0700315 bitstring ma length (0..64)
Vadim Yanitskiy3ddb3ab2020-07-20 04:29:53 +0700316 } with {
317 variant (len) "LENGTHTO(ma)"
Vadim Yanitskiye2a6fdf2020-07-23 04:53:02 +0700318 variant (ma) "BYTEORDER(first), BITORDER(msb)"
Vadim Yanitskiy3ddb3ab2020-07-20 04:29:53 +0700319 };
Harald Welte9419c8a2017-07-30 04:07:05 +0200320
Vadim Yanitskiy74e1f6b2020-08-25 03:59:45 +0700321 type record MobileAllocationTLV {
322 OCT1 iei ('72'O),
323 MobileAllocationLV v
324 } with { variant "" };
325
Harald Welte9419c8a2017-07-30 04:07:05 +0200326 /* 10.5.2.25a */
Harald Welte1b9b7702017-07-30 04:19:14 +0200327 type record PktChDesc0Ind {
328 uint6_t maio,
329 BIT1 ma_number_ind,
330 BIT1 change_mark1_valid,
331 BIT2 change_mark1
332 } with { variant "" };
333 type record PktChDesc0 {
334 BIT1 hopping,
335 BIT1 spare ('0'B),
336 uint10_t arfcn optional,
337 PktChDesc0Ind indirect optional
338 } with {
339 variant (arfcn) "PRESENCE(hopping = '0'B)"
340 variant (indirect) "PRESENCE(hopping = '1'B)"
341 };
342 type record PktChDesc1 {
343 uint6_t maio,
344 uint6_t hsn
345 } with { variant "" };
346 type record PacketChannelDescription {
347 uint5_t channel_Type_spare,
348 uint3_t tn,
349 uint3_t tsc,
350 BIT1 presence,
351 PktChDesc0 zero optional,
352 PktChDesc1 one optional
353 } with {
354 variant (zero) "PRESENCE(presence = '0'B)"
355 variant (one) "PRESENCE(presence = '1'B)"
356 };
Harald Welte9419c8a2017-07-30 04:07:05 +0200357
358 /* 10.5.2.25b */
359 type record DedicatedModeOrTbf {
360 BIT1 spare,
361 boolean tma,
362 boolean downlink,
363 boolean tbf
364 } with { variant "" };
365
366 /* 10.5.2.26 */
367 type enumerated PageMode {
368 PAGE_MODE_NORMAL,
369 PAGE_MODE_EXTENDED,
370 PAGE_MODE_REORGANIZATION,
371 PAGE_MODE_SAME_AS_BEFORE
372 } with { variant "FIELDLENGTH(4)" };
373
374 /* 10.5.2.30 */
375 type record RequestReference {
376 bitstring ra length(8),
377 uint5_t t1p,
378 uint6_t t3,
379 uint5_t t2
380 } with { variant "" };
381
382 template RequestReference t_RequestReference(template bitstring ra, template uint5_t t1p, template uint6_t t3, template uint5_t t2) := {
383 ra := ra,
384 t1p := t1p,
385 t3 := t3,
386 t2 := t2
387 }
388
389 /* compute the expected request reference for given RA + FN */
390 function f_compute_ReqRef(uint8_t ra, GsmFrameNumber fn) return RequestReference {
391 var RequestReference req_ref := { ra := int2bit(ra, 8) };
392 req_ref.t1p := (fn / 1326) mod 32;
393 req_ref.t2 := fn mod 26;
394 req_ref.t3 := fn mod 51;
395 return req_ref
396 }
Harald Weltee8d750e2018-06-10 21:41:35 +0200397 function tr_compute_ReqRef(template uint8_t ra, template GsmFrameNumber fn)
398 return template RequestReference {
399 var template RequestReference req_ref;
400 if (istemplatekind(ra, "?")) {
401 req_ref.ra := ?;
402 } else {
403 req_ref.ra := int2bit(valueof(ra), 8);
404 }
405 if (istemplatekind(fn, "?")) {
406 req_ref.t1p := ?;
407 req_ref.t2 := ?;
408 req_ref.t3 := ?;
409 } else {
410 var GsmFrameNumber fn_v := valueof(fn);
411 req_ref.t1p := (fn_v / 1326) mod 32;
412 req_ref.t2 := fn_v mod 26;
413 req_ref.t3 := fn_v mod 51;
414 }
415 return req_ref;
416 }
Harald Welte9419c8a2017-07-30 04:07:05 +0200417
418 /* 10.5.2.40 */
419 type integer TimingAdvance (0..219);
420
421 /* 10.5.2.43 */
422 type uint8_t WaitIndication;
423
424 /* 10.5.2.76 */
425 type record FeatureIndicator {
Vadim Yanitskiyc3cebd32020-05-22 02:43:22 +0700426 BIT2 peo_bcch_change_mark,
427 boolean cs_ir,
428 boolean ps_ir
429 } with {
430 variant (cs_ir) "FIELDLENGTH(1)"
431 variant (ps_ir) "FIELDLENGTH(1)"
432 };
Harald Welte9419c8a2017-07-30 04:07:05 +0200433
434 /* 24.008 10.5.5.6 */
435 type record DrxParameter {
436 uint8_t split_pg_cycle_code,
437 uint4_t drx_cycle_len_coeff,
438 boolean split_on_ccch,
439 uint3_t non_drx_timer
440 } with { variant "" };
441
Harald Weltecbc947f2018-02-22 00:26:55 +0100442 type record MeasurementResults {
443 BIT1 ba_used,
444 BIT1 dtx_used,
445 uint6_t rxlev_full_srv_cell,
446 BIT1 threeg_ba_used,
447 BIT1 meas_valid,
448 uint6_t rxlev_sub_srv_cell,
449 BIT1 si23_ba_used,
450 uint3_t rxqual_full_srv_cell,
451 uint3_t rxqual_sub_srv_cell,
452 uint3_t no_ncell_m,
453 NcellReports ncell_reports optional
454 } with { variant (no_ncell_m) "LENGTHTO(ncell_reports)"
455 variant (no_ncell_m) "UNIT(elements)"
Vadim Yanitskiy9cbb86f2021-11-04 18:50:22 +0300456 /* FIXME: pad to 16 octets */
Harald Weltecbc947f2018-02-22 00:26:55 +0100457 };
458
459 type record NcellReport {
460 uint6_t rxlev,
461 uint5_t bcch_freq,
462 uint6_t bsic
463 } with { variant ""};
464 type record of NcellReport NcellReports;
465
Harald Welte9419c8a2017-07-30 04:07:05 +0200466
Vadim Yanitskiy27b38012020-09-01 05:14:46 +0700467 /* 3GPP TS 44.018, section 9.1.2 (minimalistic implementation) */
468 type record AssignmentCommand {
469 ChannelDescription chan_desc,
470 PowerCommand_V power_cmd,
471 FrequencyList_TLV freq_list_at optional,
472 CellChannelDescription_TV cell_chan_desc optional,
473 /* TODO: Multislot Allocation IE */
474 ChannelMode_TV chan1_mode optional,
475 ChannelMode_TV chan2_mode optional,
476 /* TODO: Mode of Channel Set 3..8 IE */
477 MobileAllocationTLV mobile_allocation optional
478 /* TODO: more optional IEs... */
479 } with {
480 variant "TAG(
481 freq_list_at, elementIdentifier = '05'O;
482 cell_chan_desc, elementIdentifier = '62'O;
483 chan1_mode, elementIdentifier = '63'O;
484 chan2_mode, elementIdentifier = '11'O;
485 mobile_allocation, iei = '72'O;
486 )"
487 };
488
Vadim Yanitskiy5fec37c2020-09-02 17:19:47 +0700489 /* 3GPP TS 44.018, section 9.1.15 (minimalistic implementation) */
490 type record HandoverCommand {
491 CellDescriptionV cell_desc,
492 ChannelDescription chan_desc,
493 OCT1 ho_ref,
494 PowerCommandAndAccesstype_V power_cmd_acc_type,
495 FrequencyList_TLV freq_list_at optional,
496 CellChannelDescription_TV cell_chan_desc optional,
497 ChannelMode_TV chan1_mode optional,
498 ChannelMode_TV chan2_mode optional,
499 /* TODO: Mode of Channel Set 3..8 IE */
500 MobileAllocationTLV mobile_allocation optional
501 /* TODO: more optional IEs... */
502 } with {
503 variant "TAG(
504 freq_list_at, elementIdentifier = '05'O;
505 cell_chan_desc, elementIdentifier = '62'O;
506 chan1_mode, elementIdentifier = '63'O;
507 chan2_mode, elementIdentifier = '11'O;
508 mobile_allocation, iei = '72'O;
509 )"
510 };
511
512 /* 10.5.2.2 Cell Description IE */
513 type record CellDescriptionV {
514 uint3_t bcc, /* PLMN colour code */
515 uint3_t ncc, /* BS colour code */
516 uint10_t bcch_arfcn
517 } with { variant "FIELDORDER(lsb)" };
518
Vadim Yanitskiy27b38012020-09-01 05:14:46 +0700519
Harald Welte9419c8a2017-07-30 04:07:05 +0200520 /* 9.1.18 */
521 type record ImmediateAssignment {
522 DedicatedModeOrTbf ded_or_tbf,
523 PageMode page_mode,
524 ChannelDescription chan_desc optional,
525 PacketChannelDescription pkt_chan_desc optional,
526 RequestReference req_ref,
527 TimingAdvance timing_advance,
Vadim Yanitskiy3b464a92020-08-25 03:55:32 +0700528 MobileAllocationLV mobile_allocation,
Harald Welte9419c8a2017-07-30 04:07:05 +0200529 /* TODO: starting time TLV */
Vadim Yanitskiyf10bb452019-09-05 13:53:01 +0200530 IaRestOctets rest_octets
Harald Welte9419c8a2017-07-30 04:07:05 +0200531 } with { variant (chan_desc) "PRESENCE(ded_or_tbf.tbf = false)"
Vadim Yanitskiya4aacc22019-09-09 04:41:12 +0200532 variant (pkt_chan_desc) "PRESENCE(ded_or_tbf.tbf = true)" };
Harald Welte9419c8a2017-07-30 04:07:05 +0200533
534 /* 9.1.20 */
535 type record ReqRefWaitInd {
536 RequestReference req_ref,
537 WaitIndication wait_ind
538 } with { variant "" };
539 type record length(4) of ReqRefWaitInd ReqRefWaitInd4;
540 type record ImmediateAssignmentReject {
541 FeatureIndicator feature_ind,
542 PageMode page_mode,
Vadim Yanitskiy7ef121d2020-05-22 03:04:22 +0700543 ReqRefWaitInd4 payload,
544 IARRestOctets rest_octets
Harald Welte9419c8a2017-07-30 04:07:05 +0200545 } with { variant "" };
546
Harald Weltecbc947f2018-02-22 00:26:55 +0100547 /* 9.1.21 */
548 type record MeasurementReport {
549 MeasurementResults meas_res
550 } with { variant "" };
551
Harald Welte9419c8a2017-07-30 04:07:05 +0200552 /* 9.1.22 */
553 type record PagingRequestType1 {
554 ChannelNeeded12 chan_needed,
555 PageMode page_mode,
556 MobileIdentityLV mi1,
557 MobileIdentityTLV mi2 optional,
558 RestOctets rest_octets
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700559 } with { variant "TAG(mi2, elementIdentifier = '0010111'B)" };
Harald Welte9419c8a2017-07-30 04:07:05 +0200560
561 /* 9.1.23 */
562 type record PagingRequestType2 {
563 ChannelNeeded12 chan_needed,
564 PageMode page_mode,
565 GsmTmsi mi1,
566 GsmTmsi mi2,
567 MobileIdentityTLV mi3 optional,
568 RestOctets rest_octets
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +0700569 } with { variant "TAG(mi3, elementIdentifier = '0010111'B)" };
Harald Welte9419c8a2017-07-30 04:07:05 +0200570
571 /* 9.1.24 */
572 type record length(4) of GsmTmsi GsmTmsi4;
573 type record PagingRequestType3 {
574 ChannelNeeded12 chan_needed,
575 PageMode page_mode,
576 GsmTmsi4 mi,
577 RestOctets rest_octets
578 } with { variant "" };
579
Harald Welte9419c8a2017-07-30 04:07:05 +0200580 type union RrUnion {
581/*
582 SystemInformationType1 si1,
583 SystemInformationType2 si2,
584 SystemInformationType2bis si2bis,
585 SystemInformationType2ter si2ter,
Harald Welte82ccef72018-02-25 16:17:33 +0100586 SystemInformationType3 si3,
Harald Welte9419c8a2017-07-30 04:07:05 +0200587 SystemInformationType4 si4,
588 SystemInformationType5 si5,
589 SystemInformationType5bis si5bis,
590 SystemInformationType5ter si5ter,
591 SystemInformationType6 si6,
592*/
593 ImmediateAssignment imm_ass,
594 ImmediateAssignmentReject imm_ass_rej,
595 PagingRequestType1 pag_req_1,
596 PagingRequestType2 pag_req_2,
597 PagingRequestType3 pag_req_3,
598 octetstring other
599 } with { variant "" };
600
601 /* Special RR Message on BCCH / CCCH Dowlink */
602
603 type record GsmRrMessage {
604 RrHeader header,
605 RrUnion payload
606 } with { variant (payload) "CROSSTAG(
607/*
608 si1, header.message_type = SYSTEM_INFORMATION_TYPE_1;
609 si2, header.message_type = SYSTEM_INFORMATION_TYPE_2;
610 si2bis, header.message_type = SYSTEM_INFORMATION_TYPE_2bis;
611 si2ter, header.message_type = SYSTEM_INFORMATION_TYPE_2ter;
612 si3, header.message_type = SYSTEM_INFORMATION_TYPE_3;
613 si4, header.message_type = SYSTEM_INFORMATION_TYPE_4;
614 si5, header.message_type = SYSTEM_INFORMATION_TYPE_5;
615 si5bis, header.message_type = SYSTEM_INFORMATION_TYPE_5bis;
616 si5ter, header.message_type = SYSTEM_INFORMATION_TYPE_5ter;
617 si6, header.message_type = SYSTEM_INFORMATION_TYPE_6;
618*/
619 imm_ass, header.message_type = IMMEDIATE_ASSIGNMENT;
620 imm_ass_rej, header.message_type = IMMEDIATE_ASSIGNMENT_REJECT;
621 pag_req_1, header.message_type = PAGING_REQUEST_TYPE_1;
622 pag_req_2, header.message_type = PAGING_REQUEST_TYPE_2;
623 pag_req_3, header.message_type = PAGING_REQUEST_TYPE_3;
624 other, OTHERWISE;
Vadim Yanitskiya4aacc22019-09-09 04:41:12 +0200625 )"
626 /* Total message length: 184 = 23 * 8. Pad spare bits with '2B'O. */
627 variant "PADDING(184), PADDING_PATTERN('00101011'B)"
628 };
Harald Welte9419c8a2017-07-30 04:07:05 +0200629
630 external function enc_GsmRrMessage(in GsmRrMessage msg) return octetstring
631 with { extension "prototype(convert) encode(RAW)" };
632 external function dec_GsmRrMessage(in octetstring stream) return GsmRrMessage
633 with { extension "prototype(convert) decode(RAW)" };
634
635 /* Normal L3 Message on Dedicated Channel */
636
637 /* 9.1.25 Paging Response */
638 type record PagingResponse {
639 uint4_t spare_half_octet,
640 CipheringKeySeqNr cksn,
641 MsClassmark2LV cm2,
642 MobileIdentityLV mi,
643 uint8_t addl_upd_par optional
644 } with { variant "" };
645
646 type union RrL3Union {
Vadim Yanitskiy480c2ac2020-09-01 05:43:06 +0700647 PagingResponse paging_response,
648 MeasurementReport meas_rep,
649 AssignmentCommand ass_cmd,
Vadim Yanitskiy5fec37c2020-09-02 17:19:47 +0700650 HandoverCommand ho_cmd,
Vadim Yanitskiy480c2ac2020-09-01 05:43:06 +0700651 octetstring other
Harald Welte9419c8a2017-07-30 04:07:05 +0200652 };
653
654 type record GsmRrL3Message {
655 RrL3Header header,
656 RrL3Union payload
657 } with { variant (payload) "CROSSTAG(
658 paging_response, header.message_type = PAGING_RESPONSE;
Harald Weltecbc947f2018-02-22 00:26:55 +0100659 meas_rep, header.message_type = MEASUREMENT_REPORT;
Vadim Yanitskiy27b38012020-09-01 05:14:46 +0700660 ass_cmd, header.message_type = ASSIGNMENT_COMMAND;
Vadim Yanitskiy5fec37c2020-09-02 17:19:47 +0700661 ho_cmd, header.message_type = HANDOVER_COMMAND;
Harald Welte9419c8a2017-07-30 04:07:05 +0200662 other, OTHERWISE;
663 )" }
664
Harald Weltecbc947f2018-02-22 00:26:55 +0100665 external function enc_GsmRrL3Message(in GsmRrL3Message msg) return octetstring
666 with { extension "prototype(convert) encode(RAW)" };
667 external function dec_GsmRrL3Message(in octetstring stream) return GsmRrL3Message
668 with { extension "prototype(convert) decode(RAW)" };
669
670
Harald Weltee8d750e2018-06-10 21:41:35 +0200671 template (value) GsmRrMessage ts_IMM_ASS(uint8_t ra, GsmFrameNumber fn, TimingAdvance ta,
Vadim Yanitskiy3b464a92020-08-25 03:55:32 +0700672 ChannelDescription ch_desc, MobileAllocationLV ma) := {
Harald Weltebae6be82020-08-21 12:42:18 +0200673 header := ts_RrHeader(IMMEDIATE_ASSIGNMENT, 0),
Harald Weltecbc947f2018-02-22 00:26:55 +0100674 payload := {
675 imm_ass := {
676 ded_or_tbf := {
677 spare := '0'B,
678 tma := false,
679 downlink := false,
680 tbf := false
681 },
682 page_mode := PAGE_MODE_NORMAL,
683 chan_desc := ch_desc,
684 pkt_chan_desc := omit,
685 req_ref := f_compute_ReqRef(ra, fn),
686 timing_advance := ta,
687 mobile_allocation := ma,
Vadim Yanitskiyf10bb452019-09-05 13:53:01 +0200688 rest_octets := {
689 presence := '00'B, /* LL */
690 ll := {
Vadim Yanitskiyb021ed42020-04-27 23:25:13 +0700691 compressed_irat_ho_info_ind := '0'B /* L */
Vadim Yanitskiy9b2a3e82019-09-08 15:37:15 +0200692 },
693 lh := omit, hl := omit, hh := omit
Vadim Yanitskiyf10bb452019-09-05 13:53:01 +0200694 }
Harald Weltecbc947f2018-02-22 00:26:55 +0100695 }
696 }
697 };
698
Harald Weltee8d750e2018-06-10 21:41:35 +0200699 template GsmRrMessage tr_IMM_ASS(template uint8_t ra := ?, template GsmFrameNumber fn := ?,
700 template TimingAdvance ta := ?,
701 template ChannelDescription ch_desc := ?,
Neels Hofmeyrb07b2952021-08-07 04:23:14 +0200702 template MobileAllocationLV ma := ?,
703 template PageMode page_mode := PAGE_MODE_NORMAL) := {
Vadim Yanitskiyd4205c32019-09-09 16:15:37 +0200704 header := t_RrHeader(IMMEDIATE_ASSIGNMENT, ?),
Harald Weltee8d750e2018-06-10 21:41:35 +0200705 payload := {
706 imm_ass := {
707 ded_or_tbf := {
708 spare := '0'B,
709 tma := false,
710 downlink := false,
711 tbf := false
712 },
Neels Hofmeyrb07b2952021-08-07 04:23:14 +0200713 page_mode := page_mode,
Harald Weltee8d750e2018-06-10 21:41:35 +0200714 chan_desc := ch_desc,
715 pkt_chan_desc := omit,
716 req_ref := tr_compute_ReqRef(ra, fn),
717 timing_advance := ta,
718 mobile_allocation := ma,
Vadim Yanitskiyf10bb452019-09-05 13:53:01 +0200719 rest_octets := ?
Harald Weltee8d750e2018-06-10 21:41:35 +0200720 }
721 }
722 };
723
Vadim Yanitskiy6edd4f52019-09-09 01:51:09 +0200724 /* TODO: implement send version of this template */
725 template GsmRrMessage tr_IMM_TBF_ASS(template boolean dl := ?,
726 template uint8_t ra := ?,
727 template GsmFrameNumber fn := ?,
728 template TimingAdvance ta := ?,
729 template PacketChannelDescription ch_desc := ?,
Vadim Yanitskiy3b464a92020-08-25 03:55:32 +0700730 template MobileAllocationLV ma := ?,
Vadim Yanitskiy6edd4f52019-09-09 01:51:09 +0200731 template IaRestOctets rest := ?) := {
732 header := t_RrHeader(IMMEDIATE_ASSIGNMENT, ?),
733 payload := {
734 imm_ass := {
735 ded_or_tbf := {
736 spare := ?,
737 tma := ?,
738 downlink := dl,
739 tbf := true
740 },
741 page_mode := ?,
742 chan_desc := omit,
743 pkt_chan_desc := ch_desc,
744 req_ref := tr_compute_ReqRef(ra, fn),
745 timing_advance := ta,
Vadim Yanitskiycf1ed3f2020-07-20 04:01:43 +0700746 mobile_allocation := ma,
Vadim Yanitskiy6edd4f52019-09-09 01:51:09 +0200747 rest_octets := rest
748 }
749 }
750 };
Harald Weltee8d750e2018-06-10 21:41:35 +0200751
Vadim Yanitskiy9781ecb2020-03-28 03:59:41 +0700752 template GsmRrMessage tr_PAG_REQ1(template MobileIdentityLV mi1 := ?,
753 template MobileIdentityTLV mi2 := omit) := {
Pau Espin Pedrol88bf5372019-12-09 21:12:28 +0100754 header := t_RrHeader(PAGING_REQUEST_TYPE_1, ?),
755 payload := {
756 pag_req_1 := {
757 chan_needed := {
758 second := ?,
759 first := ?
760 },
761 page_mode := PAGE_MODE_NORMAL,
762 mi1 := mi1,
Vadim Yanitskiy9781ecb2020-03-28 03:59:41 +0700763 mi2 := mi2,
Pau Espin Pedrol88bf5372019-12-09 21:12:28 +0100764 rest_octets := ?
765 }
766 }
767 };
768
Vadim Yanitskiyf9e31d22021-11-06 18:43:28 +0300769 template (value) MeasurementResults
770 ts_MeasurementResults(template (value) uint6_t rxl_f := 63,
771 template (value) uint6_t rxl_s := 63,
772 template (value) uint3_t rxq_f := 0,
773 template (value) uint3_t rxq_s := 0,
774 boolean dtx_used := false,
775 boolean valid := true,
776 template (omit) NcellReports reps := omit) := {
777 ba_used := '0'B,
778 dtx_used := bool2bit(dtx_used),
779 rxlev_full_srv_cell := rxl_f,
780 threeg_ba_used := '0'B,
781 meas_valid := bool2bit(not valid),
782 rxlev_sub_srv_cell := rxl_s,
783 si23_ba_used := '0'B,
784 rxqual_full_srv_cell := rxq_f,
785 rxqual_sub_srv_cell := rxq_s,
786 no_ncell_m := 0,
787 ncell_reports := reps
788 };
789
Vadim Yanitskiybc8ebce2020-11-11 19:31:56 +0700790 template (value) GsmRrL3Message ts_MEAS_REP(boolean valid,
791 template (value) uint6_t rxl_f,
792 template (value) uint6_t rxl_s,
793 template (value) uint3_t rxq_f := 0,
794 template (value) uint3_t rxq_s := 0,
795 template (omit) NcellReports reps := omit) := {
Harald Weltecbc947f2018-02-22 00:26:55 +0100796 header := t_RrL3Header(MEASUREMENT_REPORT),
797 payload := {
798 meas_rep := {
799 meas_res := {
800 ba_used := '0'B,
801 dtx_used := '0'B,
802 rxlev_full_srv_cell := rxl_f,
803 threeg_ba_used := '0'B,
Harald Welteeb1e6812018-02-22 18:43:48 +0100804 meas_valid := bool2bit(not valid),
Harald Weltecbc947f2018-02-22 00:26:55 +0100805 rxlev_sub_srv_cell := rxl_s,
806 si23_ba_used := '0'B,
807 rxqual_full_srv_cell := rxq_f,
808 rxqual_sub_srv_cell := rxq_s,
809 no_ncell_m := 0,
810 ncell_reports := reps
811 }
812 }
813 }
814 };
815
Vadim Yanitskiy16e24aa2020-05-22 03:32:00 +0700816 template GsmRrMessage tr_IMM_ASS_REJ(template FeatureIndicator feature_ind := ?,
817 template ReqRefWaitInd4 rr_wi_list := ?,
818 template IARRestOctets rest_octets := ?) := {
819 header := t_RrHeader(IMMEDIATE_ASSIGNMENT_REJECT, ?),
820 payload := {
821 imm_ass_rej := {
822 feature_ind := feature_ind,
823 page_mode := ?,
824 payload := rr_wi_list,
825 rest_octets := rest_octets
826 }
827 }
828 };
829
830 template ReqRefWaitInd tr_ReqRefWaitInd(template RequestReference ref := ?,
831 template WaitIndication wi := ?) := {
832 req_ref := ref,
833 wait_ind := wi
834 };
835
Vadim Yanitskiyf7181ed2020-07-14 20:12:02 +0700836 template (value) ChannelDescription ts_ChanDescH0(template (value) RslChannelNr chan_nr,
837 template (value) uint12_t arfcn,
838 template (value) uint3_t tsc := 7) := {
839 chan_nr := chan_nr,
840 tsc := tsc,
841 h := false,
842 arfcn := arfcn,
843 maio_hsn := omit
844 }
Vadim Yanitskiyc3156ed2020-08-29 17:49:27 +0700845 template ChannelDescription tr_ChanDescH0(template (present) RslChannelNr chan_nr := ?,
846 template (present) uint12_t arfcn := ?,
847 template (present) uint3_t tsc := ?) := {
848 chan_nr := chan_nr,
849 tsc := tsc,
850 h := false,
851 arfcn := arfcn,
852 maio_hsn := omit
853 }
Vadim Yanitskiyf7181ed2020-07-14 20:12:02 +0700854
855 template (value) ChannelDescription ts_ChanDescH1(template (value) RslChannelNr chan_nr,
856 template (value) MaioHsn maio_hsn,
857 template (value) uint3_t tsc := 7) := {
858 chan_nr := chan_nr,
859 tsc := tsc,
860 h := true,
861 arfcn := omit,
862 maio_hsn := maio_hsn
863 }
Vadim Yanitskiyc3156ed2020-08-29 17:49:27 +0700864 template ChannelDescription tr_ChanDescH1(template (present) RslChannelNr chan_nr := ?,
865 template (present) MaioHsn maio_hsn := ?,
866 template (present) uint3_t tsc := ?) := {
867 chan_nr := chan_nr,
868 tsc := tsc,
869 h := true,
870 arfcn := omit,
871 maio_hsn := maio_hsn
872 }
Vadim Yanitskiyf7181ed2020-07-14 20:12:02 +0700873
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +0200874
875 /* Templates for the RR Channel Release message's "Cell selection indicator after release of all TCH and SDCCH" IE.
876 * See 3GPP TS 44.018 9.1.7 and 10.5.2.1e */
877
878 /* 3GPP TS 44.018 10.5.2.1e, Cell Selection Indicator after release of all TCH and SDCCH value part */
879 type record CellSelIndValue {
880 BIT3 discr,
881 CellSelIndValueEnum value_list,
882 BIT1 value_list_term ('0'B)
883 } with {
884 variant (value_list) "CROSSTAG(
885 gsm, discr='000'B;
886 utran_fdd, discr='001'B;
887 utran_tdd, discr='010'B;
888 eutran, discr='011'B;
889 )"
890 };
891
892 /* 3GPP TS 44.018 10.5.2.1e, Cell Selection Indicator after release of all TCH and SDCCH value part */
893 private type union CellSelIndValueEnum {
894 CellSelIndValue_GSM_Descrs gsm,
895 CellSelIndValue_UTRAN_Descrs utran_fdd,
896 CellSelIndValue_UTRAN_Descrs utran_tdd,
897 CellSelIndValue_EUTRAN_Descrs eutran
898 } with { variant "" };
899
900 type record of CellSelIndValue_GSM_Descr CellSelIndValue_GSM_Descrs;
901 /* 3GPP TS 44.018 10.5.2.1e, GSM Description struct */
902 type record CellSelIndValue_GSM_Descr {
903 BIT1 item_ind ('1'B),
904 BIT1 band_indicator,
905 uint10_t arfcn,
906 uint6_t bsic
907 } with {
908 variant "PRESENCE(item_ind = '1'B)"
909 };
910
911 type record of CellSelIndValue_UTRAN_Descr CellSelIndValue_UTRAN_Descrs;
912 /* 3GPP TS 44.018 10.5.2.1e, UTRAN {FDD,TDD} Description struct */
913 type record CellSelIndValue_UTRAN_Descr {
914 BIT1 item_ind ('1'B),
915 BIT1 bandwidth_presence,
916 uint3_t bandwidth optional,
917 uint14_t arfcn,
918 BIT1 cell_info_presence,
919 UTRAN_CellInfo cell_info optional
920 } with {
921 variant "PRESENCE(item_ind = '1'B)"
922 variant (bandwidth) "PRESENCE(bandwidth_presence = '1'B)"
923 variant (cell_info) "PRESENCE(cell_info_presence = '1'B)"
924 };
925 type record UTRAN_CellInfo {
926 BIT1 indic0,
927 uint5_t nr_of_cells,
928 // TODO: define cell_information_field
929 octetstring cell_information_field
930 } with { variant "" };
931
932 type record of CellSelIndValue_EUTRAN_Descr CellSelIndValue_EUTRAN_Descrs;
933 /* 3GPP TS 44.018 10.5.2.1e, E-UTRAN Description struct */
934 type record CellSelIndValue_EUTRAN_Descr {
935 BIT1 item_ind ('1'B),
936 uint16_t earfcn,
937 BIT1 meas_bw_presence,
938 uint3_t meas_bw optional,
939 BIT1 not_allowed_cells_presence,
940 // define not_allowed_cells
941 octetstring not_allowed_cells optional,
942 BIT1 target_pcid_presence,
943 uint9_t target_pcid optional
944 } with {
945 variant "PRESENCE(item_ind = '1'B)"
946 variant (meas_bw) "PRESENCE(meas_bw_presence = '1'B)"
947 variant (not_allowed_cells) "PRESENCE(not_allowed_cells_presence = '1'B)"
948 variant (target_pcid) "PRESENCE(target_pcid_presence = '1'B)"
949 };
950
951 template CellSelIndValue tr_CellSelIndValue_EUTRAN(
952 template CellSelIndValue_EUTRAN_Descrs cells := {})
953 := {
954 discr := '011'B,
955 value_list := {
956 eutran := cells
957 },
958 value_list_term := '0'B
959 };
960
961 template CellSelIndValue_EUTRAN_Descr tr_CellSelIndValue_EUTRAN_Descr(
962 template (present) uint16_t earfcn,
963 template (present) BIT1 meas_bw_presence := ?,
964 template uint3_t meas_bw := *)
965 := {
966 item_ind := '1'B,
967 earfcn := earfcn,
968 meas_bw_presence := meas_bw_presence,
969 meas_bw := meas_bw,
970 not_allowed_cells_presence := '0'B,
971 not_allowed_cells := omit,
972 target_pcid_presence := '0'B,
973 target_pcid := omit
974 };
975
976 external function enc_CellSelIndValue(in CellSelIndValue ro) return octetstring
977 with { extension "prototype(convert) encode(RAW)" };
978 external function dec_CellSelIndValue(in octetstring stream) return CellSelIndValue
979 with { extension "prototype(convert) decode(RAW)" };
980
Vadim Yanitskiye05d7162020-05-02 16:58:46 +0700981} with { encode "RAW" ; variant "FIELDORDER(msb)" }