blob: 9fd7733cff170a738be0afd6dff083939f11bf6e [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;
18 import from RLCMAC_CSN1_Types all;
19
20 /* Table 10.4.1 of Section 10.4 / 3GPP TS 44.018 */
21 type enumerated RrMessageType {
22 ADDITIONAL_ASSIGNMENT ('00111011'B),
23 IMMEDIATE_ASSIGNMENT ('00111111'B),
24 IMMEDIATE_ASSIGNMENT_EXTENDED ('00111001'B),
25 IMMEDIATE_ASSIGNMENT_REJECT ('00111010'B),
26 IMMEDIATE_PACKET_ASSIGNMENT ('01101001'B),
27
28 CIPHERING_MODE_COMMAND ('00110101'B),
29 CIPHERING_MODE_COMPLETE ('00110010'B),
30
31 CONFIGURATION_CHANGE_COMMAND ('00110000'B),
32 CONFIGURATION_CHANGE_ACK ('00110001'B),
33 CONFIGURATION_CHANGE_REJECT ('00110011'B),
34
35 ASSIGNMENT_COMMAND ('00101110'B),
36 ASSIGNMENT_COMPLETE ('00101001'B),
37 ASSIGNMENT_FAILURE ('00101111'B),
38 HANDOVER_COMMAND ('00101011'B),
39 HANDOVER_COMPLETE ('00101100'B),
40 HANDOVER_FAILURE ('00101000'B),
41 PHYSICAL_INFORMATION ('00101101'B),
42
43 CHANNEL_RELEASE ('00001101'B),
44 PARTIAL_RELEASE ('00001010'B),
45 PARTIAL_RELEASE_COMPLETE ('00001111'B),
46
47 PAGING_REQUEST_TYPE_1 ('00100001'B),
48 PAGING_REQUEST_TYPE_2 ('00100010'B),
49 PAGING_REQUEST_TYPE_3 ('00100100'B),
50 PAGING_RESPONSE ('00100111'B),
51 NOTIFICATION_NCH ('00100000'B),
52 NOTIFICATION_RESPOSNE ('00100110'B),
53
54 SYSTEM_INFORMATION_TYPE_8 ('00011000'B),
55 SYSTEM_INFORMATION_TYPE_1 ('00011001'B),
56 SYSTEM_INFORMATION_TYPE_2 ('00011010'B),
57 SYSTEM_INFORMATION_TYPE_3 ('00011011'B),
58 SYSTEM_INFORMATION_TYPE_4 ('00011100'B),
59 SYSTEM_INFORMATION_TYPE_5 ('00011101'B),
60 SYSTEM_INFORMATION_TYPE_6 ('00011110'B),
61 SYSTEM_INFORMATION_TYPE_7 ('00011111'B),
62 SYSTEM_INFORMATION_TYPE_2bis ('00000010'B),
63 SYSTEM_INFORMATION_TYPE_2ter ('00000011'B),
64 SYSTEM_INFORMATION_TYPE_2quater ('00000111'B),
65 SYSTEM_INFORMATION_TYPE_5bis ('00000101'B),
66 SYSTEM_INFORMATION_TYPE_5ter ('00000110'B),
67 SYSTEM_INFORMATION_TYPE_9 ('00000100'B),
68 SYSTEM_INFORMATION_TYPE_13 ('00000000'B),
69
70 SYSTEM_INFORMATION_TYPE_16 ('00111101'B),
71 SYSTEM_INFORMATION_TYPE_17 ('00111110'B),
72
73 CHANNEL_MODE_MODIFY ('00010000'B),
74 RR_STATUS ('00010010'B),
75 CHANNEL_MODE_MODIFY_ACKNOWLEDGE ('00010111'B),
76 FREQUENCY_REDEFINITION ('00010100'B),
77 MEASUREMENT_REPORT ('00010101'B),
78 CLASSMARK_CHANGE ('00010110'B),
79 CLASSMARK_ENQUIRY ('00010011'B),
80 EXTENDED_MEASUREMENT_REPORT ('00110110'B),
81 EXTENDED_MEASUREMENT_ORDER ('00110111'B),
82 GPRS_SUSPENSION_REQUEST ('00110100'B),
83 //MBMS_ANNOUNCEMENT ('00010110'B), duplicate?
84 //SERVICE_INFORMATION ('00110110'B), duplicate?
85
86 APPLICATION_INFORMATION ('00111000'B),
87
88 SYSTEM_INFORMATION_TYPE_14 ('00000001'B),
89 SYSTEM_INFORMATION_TYPE_15 ('01000011'B),
90 SYSTEM_INFORMATION_TYPE_18 ('01000000'B),
91 SYSTEM_INFORMATION_TYPE_19 ('01000001'B),
92 SYSTEM_INFORMATION_TYPE_20 ('01000010'B),
93 SYSTEM_INFORMATION_TYPE_13alt ('01000100'B),
94 SYSTEM_INFORMATION_TYPE_2n ('01000101'B),
95 SYSTEM_INFORMATION_TYPE_21 ('01000110'B),
96 SYSTEM_INFORMATION_TYPE_22 ('01000111'B),
97 SYSTEM_INFORMATION_TYPE_23 ('01001111'B),
98
99 DTM_ASSIGNMENT_FAILURE ('01001000'B),
100 DTM_REJECT ('01001001'B),
101 DTM_REQUEST ('01001010'B),
102 PACKET_ASSIGNMENT ('01001011'B),
103 DTM_ASSIGNMENT_COMMAND ('01001100'B),
104 DTM_INFORMATION ('01001101'B),
105 PACKET_INFORMATION ('01001110'B),
106
107 UTRAN_CLASSMARK_CHANGE ('01100000'B),
108 CDMA2000_CLASSMARK_CHANGE ('01100010'B),
109 INTERSYS_TO_UTRAN_HO_CMD ('01100011'B),
110 INTERSYS_TO_CDMA2000_HO_CMD ('01100100'B),
111 GERAN_IU_MODE_CLASSMARK_CHG ('01100101'B),
112 INTERSYS_TO_EUTRAN_HO_CMD ('01100110'B)
113 } with { variant "FIELDLENGTH(8)" };
114
115 type octetstring RestOctets with { variant "PADDING(yes), PADDING_PATTERN('00101011'B)" };
116 type hexstring GsmBcdString with { variant "HEXORDER(low)" };
117 type GsmBcdString BcdMccMnc with { variant "FIELDLENGTH(6)" };
118
119 type record L2PseudoLength {
120 uint6_t l2_plen,
121 BIT2 zero_one
122 } with { variant "" };
123
Harald Weltef8df4cb2018-03-10 15:15:08 +0100124 template L2PseudoLength tr_L2Pseudolength(template uint6_t len) := {
125 l2_plen := len,
126 zero_one := '01'B
127 };
128
129 template (value) L2PseudoLength ts_L2Pseudolength(uint6_t len) := {
Harald Welte9419c8a2017-07-30 04:07:05 +0200130 l2_plen := len,
131 zero_one := '01'B
132 };
133
134 type record RrHeader {
135 L2PseudoLength l2_plen,
136 uint4_t skip_indicator,
137 uint4_t rr_protocol_discriminator,
138 RrMessageType message_type
139 } with { variant "" };
140
141 template RrHeader t_RrHeader(RrMessageType msg_type, template uint6_t len) := {
Harald Weltef8df4cb2018-03-10 15:15:08 +0100142 l2_plen := tr_L2Pseudolength(len),
Harald Welte9419c8a2017-07-30 04:07:05 +0200143 skip_indicator := 0,
144 rr_protocol_discriminator := 6,
145 message_type := msg_type
146 };
147
Harald Weltef8df4cb2018-03-10 15:15:08 +0100148 template (value) RrHeader ts_RrHeader(RrMessageType msg_type, uint6_t len) := {
149 l2_plen := ts_L2Pseudolength(len),
150 skip_indicator := 0,
151 rr_protocol_discriminator := 6,
152 message_type := msg_type
153 };
154
155
Harald Welte9419c8a2017-07-30 04:07:05 +0200156 type record RrL3Header {
157 uint4_t skip_indicator,
158 uint4_t rr_protocol_discriminator,
159 RrMessageType message_type
160 } with { variant "" };
161
Harald Weltecbc947f2018-02-22 00:26:55 +0100162 template RrL3Header t_RrL3Header(RrMessageType msg_type) := {
163 skip_indicator := 0,
164 rr_protocol_discriminator := 6,
165 message_type := msg_type
166 }
167
Pau Espin Pedrol0aad5962018-09-28 16:03:55 +0200168 /* TS 44.004 7.2.1 */
169 type record SacchL1Header {
170 uint2_t reserved,
171 boolean fpc,
172 uint5_t ms_power_lvl,
173 uint8_t actual_ta
174 } with { variant "FIELDORDER(msb)" };
175
176 template (value) SacchL1Header ts_SacchL1Header(uint5_t ms_power_lvl, boolean fpc, uint8_t actual_ta) := {
177 reserved := 0,
178 fpc := fpc,
179 ms_power_lvl := ms_power_lvl,
180 actual_ta := actual_ta
181 };
182
Harald Welte9419c8a2017-07-30 04:07:05 +0200183 type record MaioHsn {
184 } with { variant "" };
185
186 /* TS 24.008 10.5.1.1 */
187 type uint16_t CellIdentity;
188
189 /* TS 24.008 10.5.1.2 */
190 type uint4_t CipheringKeySeqNr (0..7);
191
192 /* 24.008 10.5.1.3 */
193 type record LocationAreaIdentification {
194 BcdMccMnc mcc_mnc,
195 uint16_t lac
196 } with { variant "" };
197
198 /* TS 24.008 10.5.1.4 */
199 type enumerated MobileIdentityType {
200 MI_TYPE_NONE (0),
201 MI_TYPE_IMSI,
202 MI_TYPE_IMEI,
203 MI_TYPE_IMEISV,
204 MI_TYPE_TMSI,
205 MI_TYPE_TMGI
206 } with { variant "FIELDLENGTH(3)" };
207
208 type record MobileIdentityBCD {
209 MobileIdentityType mi_type (MI_TYPE_IMSI, MI_TYPE_IMEI, MI_TYPE_IMEISV),
210 boolean odd,
211 hexstring digits
212 } with { variant "FIELDORDER(lsb)" };
213
214 type record MobileIdentityTMSI {
215 BIT4 pad ('1111'B),
216 boolean odd (false),
217 MobileIdentityType mi_type (MI_TYPE_TMSI),
218 GsmTmsi tmsi
219 } with { variant "FIELDORDER(lsb)" };
220
221 type record MobileIdentityNone {
222 BIT4 pad ('1111'B),
223 boolean odd (false),
224 MobileIdentityType mi_type (MI_TYPE_NONE)
225 } with { variant "FIELDORDER(lsb)" };
226
227 type union MobileIdentity {
228 MobileIdentityBCD imsi,
229 MobileIdentityBCD imei,
230 MobileIdentityBCD imeisv,
231 MobileIdentityTMSI tmsi,
232 MobileIdentityNone unused
233 } with { variant "TAG(imsi, mi_type = MI_TYPE_IMSI;
234 imei, mi_type = MI_TYPE_IMEI;
235 imeisv, mi_type = MI_TYPE_IMEISV;
236 tmsi, mi_type = MI_TYPE_TMSI;
237 unused, mi_type = MI_TYPE_NONE)"
238 variant "FIELDORDER(lsb)"
239 };
240
Stefan Sperling59c15d62018-10-10 11:09:25 +0200241 /* TS 24.008 10.5.1.4 "Mobile Identity" */
Harald Welte9419c8a2017-07-30 04:07:05 +0200242 type record MobileIdentityLV {
243 uint8_t len,
244 MobileIdentity mi
245 } with { variant (len) "LENGTHTO(mi)" };
246
247 type record MobileIdentityTLV {
248 uint8_t tag,
249 uint8_t len,
250 MobileIdentity mi
251 } with { variant (len) "LENGTHTO(mi)" };
252
253 /* TS 24.008 10.5.1.5 */
254 type record MsClassmark1 {
255 BIT1 spare,
256 uint2_t rev_level,
257 boolean es_ind,
258 boolean a51,
259 uint3_t rf_pwr_cap
260 } with { variant "" };
261
262 /* TS 24.008 10.5.1.6 */
263 type record MsClassmark2 {
264 BIT1 spare,
265 uint2_t rev_level,
266 boolean es_ind,
267 boolean a51,
268 uint3_t rf_pwr_cap,
269 BIT1 spare1,
270 boolean ps_cap,
271 uint2_t ss_screen_ind,
272 boolean sm_cap,
273 boolean vbs,
274 boolean vgcs,
275 boolean fc,
276 boolean cm3,
277 BIT1 spare2,
278 boolean lcsva_cap,
279 boolean ucs2,
280 boolean solsa,
281 boolean cmsp,
282 boolean a53,
283 boolean a52
284 } with { variant "" };
285 type record MsClassmark2LV {
286 uint8_t len,
287 MsClassmark2 cm2
288 } with { variant (len) "LENGTHTO(cm2)" };
289
290
291 /* 44.018 10.5.2.5 */
292 type record ChannelDescription {
293 RslChannelNr chan_nr,
294 uint3_t tsc,
295 boolean h,
296 uint12_t arfcn optional,
297 MaioHsn maio_hsn optional
298 } with { variant (arfcn) "PRESENCE(h = false)"
299 variant (maio_hsn) "PRESENCE(h = true)" };
300
301 type record ChannelDescriptionTV {
302 OCT1 iei,
303 ChannelDescription v
304 } with { variant "" };
305
306 /* 10.5.2.21 */
307 type record MobileAllocation {
308 uint8_t len,
309 bitstring ma
310 } with { variant (len) "LENGTHTO(ma)" };
311
312 /* 10.5.2.25a */
Harald Welte1b9b7702017-07-30 04:19:14 +0200313 type record PktChDesc0Ind {
314 uint6_t maio,
315 BIT1 ma_number_ind,
316 BIT1 change_mark1_valid,
317 BIT2 change_mark1
318 } with { variant "" };
319 type record PktChDesc0 {
320 BIT1 hopping,
321 BIT1 spare ('0'B),
322 uint10_t arfcn optional,
323 PktChDesc0Ind indirect optional
324 } with {
325 variant (arfcn) "PRESENCE(hopping = '0'B)"
326 variant (indirect) "PRESENCE(hopping = '1'B)"
327 };
328 type record PktChDesc1 {
329 uint6_t maio,
330 uint6_t hsn
331 } with { variant "" };
332 type record PacketChannelDescription {
333 uint5_t channel_Type_spare,
334 uint3_t tn,
335 uint3_t tsc,
336 BIT1 presence,
337 PktChDesc0 zero optional,
338 PktChDesc1 one optional
339 } with {
340 variant (zero) "PRESENCE(presence = '0'B)"
341 variant (one) "PRESENCE(presence = '1'B)"
342 };
Harald Welte9419c8a2017-07-30 04:07:05 +0200343
344 /* 10.5.2.25b */
345 type record DedicatedModeOrTbf {
346 BIT1 spare,
347 boolean tma,
348 boolean downlink,
349 boolean tbf
350 } with { variant "" };
351
352 /* 10.5.2.26 */
353 type enumerated PageMode {
354 PAGE_MODE_NORMAL,
355 PAGE_MODE_EXTENDED,
356 PAGE_MODE_REORGANIZATION,
357 PAGE_MODE_SAME_AS_BEFORE
358 } with { variant "FIELDLENGTH(4)" };
359
360 /* 10.5.2.30 */
361 type record RequestReference {
362 bitstring ra length(8),
363 uint5_t t1p,
364 uint6_t t3,
365 uint5_t t2
366 } with { variant "" };
367
368 template RequestReference t_RequestReference(template bitstring ra, template uint5_t t1p, template uint6_t t3, template uint5_t t2) := {
369 ra := ra,
370 t1p := t1p,
371 t3 := t3,
372 t2 := t2
373 }
374
375 /* compute the expected request reference for given RA + FN */
376 function f_compute_ReqRef(uint8_t ra, GsmFrameNumber fn) return RequestReference {
377 var RequestReference req_ref := { ra := int2bit(ra, 8) };
378 req_ref.t1p := (fn / 1326) mod 32;
379 req_ref.t2 := fn mod 26;
380 req_ref.t3 := fn mod 51;
381 return req_ref
382 }
Harald Weltee8d750e2018-06-10 21:41:35 +0200383 function tr_compute_ReqRef(template uint8_t ra, template GsmFrameNumber fn)
384 return template RequestReference {
385 var template RequestReference req_ref;
386 if (istemplatekind(ra, "?")) {
387 req_ref.ra := ?;
388 } else {
389 req_ref.ra := int2bit(valueof(ra), 8);
390 }
391 if (istemplatekind(fn, "?")) {
392 req_ref.t1p := ?;
393 req_ref.t2 := ?;
394 req_ref.t3 := ?;
395 } else {
396 var GsmFrameNumber fn_v := valueof(fn);
397 req_ref.t1p := (fn_v / 1326) mod 32;
398 req_ref.t2 := fn_v mod 26;
399 req_ref.t3 := fn_v mod 51;
400 }
401 return req_ref;
402 }
Harald Welte9419c8a2017-07-30 04:07:05 +0200403
404 /* 10.5.2.40 */
405 type integer TimingAdvance (0..219);
406
407 /* 10.5.2.43 */
408 type uint8_t WaitIndication;
409
410 /* 10.5.2.76 */
411 type record FeatureIndicator {
412 BIT2 spare,
413 boolean cs_ir,
414 boolean ps_ir
415 } with { variant "" };
416
417 /* 24.008 10.5.5.6 */
418 type record DrxParameter {
419 uint8_t split_pg_cycle_code,
420 uint4_t drx_cycle_len_coeff,
421 boolean split_on_ccch,
422 uint3_t non_drx_timer
423 } with { variant "" };
424
425 /* 24.008 10.5.5.15 */
426 type record RoutingAreaIdentification {
427 LocationAreaIdentification lai,
428 uint8_t rac
429 } with { variant "" };
430
Harald Welteb16516c2019-03-21 21:31:41 +0100431 external function enc_RoutingAreaIdentification(RoutingAreaIdentification rai) return octetstring
432 with { extension "prototype(convert)" extension "encode(RAW)" }
433
Harald Welte9419c8a2017-07-30 04:07:05 +0200434 /* 44.018 10.5.2.16 */
435 type record IaRestOctHL {
436 uint6_t freq_par_len,
437 BIT2 padding ('00'B) optional,
438 uint6_t maio optional,
439 octetstring mobile_allocation optional
440 } with {
441 variant (freq_par_len) "LENGTHTO(mobile_allocation,maio,padding)"
442/*
443 variant (padding) "PRESENCE(freq_par_len != 0)"
444 variant (maio) "PRESENCE(freq_par_len != 0)"
445 variant (mobile_allocation) "PRESENCE(freq_par_len != 0)"
446*/
447 };
Vadim Yanitskiy7091e8d2019-09-09 01:07:37 +0200448 type record SecondPartAssign {
449 BIT1 r99, /* H / L */
450 BIT1 presence optional,
451 BIT5 ext_ra optional
Harald Welte9419c8a2017-07-30 04:07:05 +0200452 } with {
Vadim Yanitskiy7091e8d2019-09-09 01:07:37 +0200453 /* TODO: use 'CSN.1 L/H' attribute here */
454 variant (presence) "PRESENCE(r99 = '1'B)" /* H */
455 variant (ext_ra) "PRESENCE(presence = '1'B)"
456 };
457 type union PacketUlDlAssignUnion {
458 PacketUlAssign ul,
459 PacketDlAssign dl
460 };
461 type record PacketUlDlAssign {
462 BIT1 ass_disc,
463 PacketUlDlAssignUnion ass
464 } with {
465 variant (ass) "CROSSTAG(dl, ass_disc = '1'B; ul, ass_disc = '0'B)"
466 };
467 type union PacketAssignUnion {
468 SecondPartAssign spa,
469 PacketUlDlAssign uldl
470 };
471 type record IaRestOctHH {
472 /* Packet Assignment discriminator:
473 * Packet Uplink / Downlink Assignment (0)
474 * Second Part Packet Assignment (1) */
475 BIT1 pa_disc,
476 PacketAssignUnion pa
477 } with {
478 variant (pa) "CROSSTAG(spa, pa_disc = '1'B; uldl, pa_disc = '0'B)"
Harald Welte9419c8a2017-07-30 04:07:05 +0200479 };
480 type record PacketUlAssignDyn {
481 uint5_t tfi_assignment,
482 BIT1 polling,
483 BIT1 spare ('0'B),
484 uint3_t usf,
485 BIT1 usf_granularity,
486 BIT1 p0_present,
487 uint4_t p0 optional,
488 BIT1 pr_mode optional,
489 ChCodingCommand ch_coding_cmd,
490 BIT1 tlli_block_chan_coding,
491 BIT1 alpha_present,
492 uint4_t alpha optional,
493 uint5_t gamma,
494 BIT1 ta_index_present,
495 uint4_t ta_index optional,
496 BIT1 tbf_starting_time_present,
497 uint16_t tbf_starting_time optional
498 } with {
499 variant (p0) "PRESENCE(p0_present = '1'B)"
500 variant (pr_mode) "PRESENCE(p0_present = '1'B)"
501 variant (alpha) "PRESENCE(alpha_present = '1'B)"
502 variant (ta_index) "PRESENCE(ta_index_present = '1'B)"
503 variant (tbf_starting_time) "PRESENCE(tbf_starting_time_present = '1'B)"
504 };
505 type record PacketUlAssignSgl {
506 BIT1 alpha_present,
507 uint4_t alpha optional,
508 uint5_t gamma,
509 BIT2 padding ('01'B),
510 uint16_t tbf_starting_time
511 /* TODO: P0 / PR_MODE */
512 } with {
513 variant (alpha) "PRESENCE(alpha_present = '1'B)"
514 };
515 type record PacketUlAssign {
516 BIT1 presence,
517 PacketUlAssignDyn dynamic optional,
518 PacketUlAssignSgl single optional
519 /* TODO: Estended RA, PFI */
520 } with {
521 variant (dynamic) "PRESENCE(presence = '1'B)"
522 variant (single) "PRESENCE(presence = '0'B)"
523 };
524 type record PacketDlAssG1 {
525 uint5_t tfi_assignment,
526 BIT1 rlc_mode,
527 BIT1 alpha_present,
528 uint4_t alpha optional,
529 uint5_t gamma,
530 BIT1 polling,
531 BIT1 ta_valid
532 } with { variant "" };
533 type record PacketDlAssign {
534 GprsTlli tlli,
535 BIT1 group1_present,
536 PacketDlAssG1 group1 optional,
537 BIT1 ta_index_present,
538 uint4_t ta_index optional,
539 BIT1 tbf_starting_time_present,
540 uint16_t tbf_starting_time optional,
541 BIT1 p0_present,
542 uint4_t p0 optional,
543 BIT1 pr_mode optional
544 /* TODO: EGPRS window size, etc. */
545 } with {
546 variant (group1) "PRESENCE(group1_present = '1'B)"
547 variant (ta_index) "PRESENCE(ta_index_present = '1'B)"
548 variant (tbf_starting_time) "PRESENCE(tbf_starting_time_present = '1'B)"
549 variant (p0) "PRESENCE(p0_present = '1'B)"
550 variant (pr_mode) "PRESENCE(p0_present = '1'B)"
551 };
552 type record IaRestOctLL {
553 BIT1 compressed_irat_ho_info_ind
554 } with { variant "" };
Pau Espin Pedrol461ed612019-12-30 20:18:34 +0100555
556
557 type record of AccessTechnologiesRequest
558 AccessTechnologiesRequestRepetition
559 with { variant "EXTENSION_BIT(reverse)" };
560
561 type record AccessTechnologiesRequest
562 {
563 BIT4 accessTechnType,
564 BIT1 extensionBit
565 } with { variant "FIELDORDER(msb)" };
566
567 type enumerated EgprsChCodingCommand {
568 CH_CODING_MCS1 ('0000'B),
569 CH_CODING_MCS2 ('0001'B),
570 CH_CODING_MCS3 ('0010'B),
571 CH_CODING_MCS4 ('0011'B),
572 CH_CODING_MCS5 ('0100'B),
573 CH_CODING_MCS6 ('0101'B),
574 CH_CODING_MCS7 ('0110'B),
575 CH_CODING_MCS8 ('0111'B),
576 CH_CODING_MCS9 ('1000'B),
577 CH_CODING_MCS5_7 ('1001'B),
578 CH_CODING_MCS6_9 ('1010'B)
579 } with { variant "FIELDLENGTH(4)" };
580
581 /* TS 44.060 Table 12.5.2.1 */
582 type enumerated EgprsWindowSize {
583 EGPRS_WS_64 ('00000'B),
584 EGPRS_WS_96 ('00001'B),
585 EGPRS_WS_128 ('00010'B),
586 EGPRS_WS_160 ('00011'B),
587 EGPRS_WS_192 ('00100'B),
588 EGPRS_WS_224 ('00101'B),
589 EGPRS_WS_256 ('00110'B),
590 EGPRS_WS_288 ('00111'B),
591 EGPRS_WS_320 ('01000'B),
592 EGPRS_WS_352 ('01001'B),
593 EGPRS_WS_384 ('01010'B),
594 EGPRS_WS_416 ('01011'B),
595 EGPRS_WS_448 ('01100'B),
596 EGPRS_WS_480 ('01101'B),
597 EGPRS_WS_512 ('01110'B),
598 EGPRS_WS_544 ('01111'B),
599 EGPRS_WS_576 ('10000'B),
600 EGPRS_WS_608 ('10001'B),
601 EGPRS_WS_640 ('10010'B),
602 EGPRS_WS_672 ('10011'B),
603 EGPRS_WS_704 ('10100'B),
604 EGPRS_WS_736 ('10101'B),
605 EGPRS_WS_768 ('10110'B),
606 EGPRS_WS_800 ('10111'B),
607 EGPRS_WS_832 ('11000'B),
608 EGPRS_WS_864 ('11001'B),
609 EGPRS_WS_896 ('11010'B),
610 EGPRS_WS_928 ('11011'B),
611 EGPRS_WS_960 ('11100'B),
612 EGPRS_WS_992 ('11101'B),
613 EGPRS_WS_1024 ('11110'B)
614 } with { variant "FIELDLENGTH(5)" };
615
616 type record EgprsUlAssignDyn {
617 uint5_t tfi_assignment,
618 BIT1 polling,
619 BIT1 spare ('0'B),
620 uint3_t usf,
621 BIT1 usf_granularity,
622 BIT1 p0_present,
623 uint4_t p0 optional,
624 BIT1 pr_mode optional,
625 EgprsChCodingCommand egprs_ch_coding_cmd,
626 BIT1 tlli_block_chan_coding,
627 BIT1 bep_period2_present,
628 BIT4 bep_period2 optional,
629 BIT1 resegment,
630 EgprsWindowSize egprs_window_size,
631 BIT1 alpha_present,
632 uint4_t alpha optional,
633 uint5_t gamma,
634 BIT1 ta_index_present,
635 uint4_t ta_index optional,
636 BIT1 tbf_starting_time_present,
637 uint16_t tbf_starting_time optional
638 /* TODO: Additions for Rel-7 */
639 } with {
640 variant (p0) "PRESENCE(p0_present = '1'B)"
641 variant (pr_mode) "PRESENCE(p0_present = '1'B)"
642 variant (bep_period2) "PRESENCE(bep_period2_present = '1'B)"
643 variant (alpha) "PRESENCE(alpha_present = '1'B)"
644 variant (ta_index) "PRESENCE(ta_index_present = '1'B)"
645 variant (tbf_starting_time) "PRESENCE(tbf_starting_time_present = '1'B)"
646 };
647 type record EgprsUlAssignMultiblock {
648 BIT1 alpha_present,
649 uint4_t alpha optional,
650 uint5_t gamma,
651 uint16_t tbf_starting_time,
652 BIT2 nr_radio_blocks_allocated,
653 BIT1 p0_present,
654 uint4_t p0 optional,
655 BIT1 spare ('0'B) optional,
656 BIT1 pr_mode optional
657 /* TDO: Additions for Rel-6 */
658 } with {
659 variant (alpha) "PRESENCE(alpha_present = '1'B)"
660 variant (p0) "PRESENCE(p0_present = '1'B)"
661 variant (spare) "PRESENCE(p0_present = '1'B)"
662 variant (pr_mode) "PRESENCE(p0_present = '1'B)"
663 };
664 /* 3GPP TS 44.018 version 13.3.2 10.5.2.16, "EGPRS Packet Uplink Assignment" */
665 type record EgprsUlAss {
666 BIT5 ext_ra,
667 BIT1 ats_present,
668 AccessTechnologiesRequestRepetition ats optional,
669 BIT1 presence,
670 EgprsUlAssignDyn dynamic optional,
671 EgprsUlAssignMultiblock multiblock optional
672 } with {
673 variant (ats) "PRESENCE(ats_present = '1'B)"
674 variant (dynamic) "PRESENCE(presence = '1'B)"
675 variant (multiblock) "PRESENCE(presence = '0'B)"
676 };
677
Harald Welte9419c8a2017-07-30 04:07:05 +0200678 type octetstring MblkDlAss; /* TODO */
679 type record IaRestOctLH {
680 BIT2 presence,
681 EgprsUlAss egprs_ul optional,
682 MblkDlAss multiblock_dl_ass optional
683 } with {
684 variant (egprs_ul) "PRESENCE(presence = '00'B)"
685 variant (multiblock_dl_ass) "PRESENCE(presence = '01'B)"
686 };
687 type record IaRestOctets {
688 BIT2 presence,
689 IaRestOctLL ll optional,
690 IaRestOctLH lh optional,
691 IaRestOctHL hl optional,
Vadim Yanitskiy9b2a3e82019-09-08 15:37:15 +0200692 IaRestOctHH hh optional
Harald Welte9419c8a2017-07-30 04:07:05 +0200693 } with {
694 variant (ll) "PRESENCE(presence = '00'B)"
695 variant (lh) "PRESENCE(presence = '01'B)"
696 variant (hl) "PRESENCE(presence = '10'B)"
697 variant (hh) "PRESENCE(presence = '11'B)"
Vadim Yanitskiy9b2a3e82019-09-08 15:37:15 +0200698 variant "PADDING(yes), PADDING_PATTERN('00101011'B)"
Harald Welte9419c8a2017-07-30 04:07:05 +0200699 };
700
Harald Weltecbc947f2018-02-22 00:26:55 +0100701 type record MeasurementResults {
702 BIT1 ba_used,
703 BIT1 dtx_used,
704 uint6_t rxlev_full_srv_cell,
705 BIT1 threeg_ba_used,
706 BIT1 meas_valid,
707 uint6_t rxlev_sub_srv_cell,
708 BIT1 si23_ba_used,
709 uint3_t rxqual_full_srv_cell,
710 uint3_t rxqual_sub_srv_cell,
711 uint3_t no_ncell_m,
712 NcellReports ncell_reports optional
713 } with { variant (no_ncell_m) "LENGTHTO(ncell_reports)"
714 variant (no_ncell_m) "UNIT(elements)"
715 variant "PADDING(yes)"
716 variant "FIELDLENGTH(16)"
717 };
718
719 type record NcellReport {
720 uint6_t rxlev,
721 uint5_t bcch_freq,
722 uint6_t bsic
723 } with { variant ""};
724 type record of NcellReport NcellReports;
725
Harald Welte9419c8a2017-07-30 04:07:05 +0200726
727 /* 9.1.18 */
728 type record ImmediateAssignment {
729 DedicatedModeOrTbf ded_or_tbf,
730 PageMode page_mode,
731 ChannelDescription chan_desc optional,
732 PacketChannelDescription pkt_chan_desc optional,
733 RequestReference req_ref,
734 TimingAdvance timing_advance,
735 MobileAllocation mobile_allocation,
736 /* TODO: starting time TLV */
Vadim Yanitskiyf10bb452019-09-05 13:53:01 +0200737 IaRestOctets rest_octets
Harald Welte9419c8a2017-07-30 04:07:05 +0200738 } with { variant (chan_desc) "PRESENCE(ded_or_tbf.tbf = false)"
Vadim Yanitskiya4aacc22019-09-09 04:41:12 +0200739 variant (pkt_chan_desc) "PRESENCE(ded_or_tbf.tbf = true)" };
Harald Welte9419c8a2017-07-30 04:07:05 +0200740
741 /* 9.1.20 */
742 type record ReqRefWaitInd {
743 RequestReference req_ref,
744 WaitIndication wait_ind
745 } with { variant "" };
746 type record length(4) of ReqRefWaitInd ReqRefWaitInd4;
747 type record ImmediateAssignmentReject {
748 FeatureIndicator feature_ind,
749 PageMode page_mode,
750 ReqRefWaitInd4 payload
751 } with { variant "" };
752
Harald Weltecbc947f2018-02-22 00:26:55 +0100753 /* 9.1.21 */
754 type record MeasurementReport {
755 MeasurementResults meas_res
756 } with { variant "" };
757
Harald Welte9419c8a2017-07-30 04:07:05 +0200758 /* 9.1.22 */
759 type record PagingRequestType1 {
760 ChannelNeeded12 chan_needed,
761 PageMode page_mode,
762 MobileIdentityLV mi1,
763 MobileIdentityTLV mi2 optional,
764 RestOctets rest_octets
765 } with { variant "TAG(mi2, tag = 23)" };
766
767 /* 9.1.23 */
768 type record PagingRequestType2 {
769 ChannelNeeded12 chan_needed,
770 PageMode page_mode,
771 GsmTmsi mi1,
772 GsmTmsi mi2,
773 MobileIdentityTLV mi3 optional,
774 RestOctets rest_octets
775 } with { variant "TAG(mi3, tag = 23)" };
776
777 /* 9.1.24 */
778 type record length(4) of GsmTmsi GsmTmsi4;
779 type record PagingRequestType3 {
780 ChannelNeeded12 chan_needed,
781 PageMode page_mode,
782 GsmTmsi4 mi,
783 RestOctets rest_octets
784 } with { variant "" };
785
Harald Welte9419c8a2017-07-30 04:07:05 +0200786 type union RrUnion {
787/*
788 SystemInformationType1 si1,
789 SystemInformationType2 si2,
790 SystemInformationType2bis si2bis,
791 SystemInformationType2ter si2ter,
Harald Welte82ccef72018-02-25 16:17:33 +0100792 SystemInformationType3 si3,
Harald Welte9419c8a2017-07-30 04:07:05 +0200793 SystemInformationType4 si4,
794 SystemInformationType5 si5,
795 SystemInformationType5bis si5bis,
796 SystemInformationType5ter si5ter,
797 SystemInformationType6 si6,
798*/
799 ImmediateAssignment imm_ass,
800 ImmediateAssignmentReject imm_ass_rej,
801 PagingRequestType1 pag_req_1,
802 PagingRequestType2 pag_req_2,
803 PagingRequestType3 pag_req_3,
804 octetstring other
805 } with { variant "" };
806
807 /* Special RR Message on BCCH / CCCH Dowlink */
808
809 type record GsmRrMessage {
810 RrHeader header,
811 RrUnion payload
812 } with { variant (payload) "CROSSTAG(
813/*
814 si1, header.message_type = SYSTEM_INFORMATION_TYPE_1;
815 si2, header.message_type = SYSTEM_INFORMATION_TYPE_2;
816 si2bis, header.message_type = SYSTEM_INFORMATION_TYPE_2bis;
817 si2ter, header.message_type = SYSTEM_INFORMATION_TYPE_2ter;
818 si3, header.message_type = SYSTEM_INFORMATION_TYPE_3;
819 si4, header.message_type = SYSTEM_INFORMATION_TYPE_4;
820 si5, header.message_type = SYSTEM_INFORMATION_TYPE_5;
821 si5bis, header.message_type = SYSTEM_INFORMATION_TYPE_5bis;
822 si5ter, header.message_type = SYSTEM_INFORMATION_TYPE_5ter;
823 si6, header.message_type = SYSTEM_INFORMATION_TYPE_6;
824*/
825 imm_ass, header.message_type = IMMEDIATE_ASSIGNMENT;
826 imm_ass_rej, header.message_type = IMMEDIATE_ASSIGNMENT_REJECT;
827 pag_req_1, header.message_type = PAGING_REQUEST_TYPE_1;
828 pag_req_2, header.message_type = PAGING_REQUEST_TYPE_2;
829 pag_req_3, header.message_type = PAGING_REQUEST_TYPE_3;
830 other, OTHERWISE;
Vadim Yanitskiya4aacc22019-09-09 04:41:12 +0200831 )"
832 /* Total message length: 184 = 23 * 8. Pad spare bits with '2B'O. */
833 variant "PADDING(184), PADDING_PATTERN('00101011'B)"
834 };
Harald Welte9419c8a2017-07-30 04:07:05 +0200835
836 external function enc_GsmRrMessage(in GsmRrMessage msg) return octetstring
837 with { extension "prototype(convert) encode(RAW)" };
838 external function dec_GsmRrMessage(in octetstring stream) return GsmRrMessage
839 with { extension "prototype(convert) decode(RAW)" };
840
841 /* Normal L3 Message on Dedicated Channel */
842
843 /* 9.1.25 Paging Response */
844 type record PagingResponse {
845 uint4_t spare_half_octet,
846 CipheringKeySeqNr cksn,
847 MsClassmark2LV cm2,
848 MobileIdentityLV mi,
849 uint8_t addl_upd_par optional
850 } with { variant "" };
851
852 type union RrL3Union {
853 PagingResponse paging_response,
Harald Weltecbc947f2018-02-22 00:26:55 +0100854 MeasurementReport meas_rep,
Harald Welte9419c8a2017-07-30 04:07:05 +0200855 octetstring other
856 };
857
858 type record GsmRrL3Message {
859 RrL3Header header,
860 RrL3Union payload
861 } with { variant (payload) "CROSSTAG(
862 paging_response, header.message_type = PAGING_RESPONSE;
Harald Weltecbc947f2018-02-22 00:26:55 +0100863 meas_rep, header.message_type = MEASUREMENT_REPORT;
Harald Welte9419c8a2017-07-30 04:07:05 +0200864 other, OTHERWISE;
865 )" }
866
Harald Weltecbc947f2018-02-22 00:26:55 +0100867 external function enc_GsmRrL3Message(in GsmRrL3Message msg) return octetstring
868 with { extension "prototype(convert) encode(RAW)" };
869 external function dec_GsmRrL3Message(in octetstring stream) return GsmRrL3Message
870 with { extension "prototype(convert) decode(RAW)" };
871
872
Vadim Yanitskiy7091e8d2019-09-09 01:07:37 +0200873 template PacketDlAssign tr_PacketDlAssign(template GprsTlli tlli) := {
874 tlli := tlli,
875 group1_present := ?,
876 group1 := *,
877 ta_index_present := ?,
878 ta_index := *,
879 tbf_starting_time_present := ?,
880 tbf_starting_time := *,
881 p0_present := ?,
882 p0 := *,
883 pr_mode := *
884 };
885
886 template IaRestOctets tr_IaRestOctets_DLAss(template PacketDlAssign dl_ass) := {
887 presence := '11'B, /* HH */
888 ll := omit, lh := omit, hl := omit,
889 hh := {
890 pa_disc := '0'B, /* Packet Assignment (0) */
891 pa := {
892 uldl := {
893 ass_disc := '1'B, /* Downlink Assignment (1) */
894 ass := { dl := dl_ass }
895 }
896 }
897 }
898 };
899
900 template PacketUlAssign tr_PacketUlDynAssign(template uint5_t tfi := ?,
901 template BIT1 polling := ?,
902 template uint3_t usf := ?,
903 template BIT1 usf_granularity := ?,
904 template ChCodingCommand cs := ?) := {
Vadim Yanitskiy06ca64d2019-09-29 20:17:10 +0700905 presence := '1'B, /* Dynamic Block Allocation */
Vadim Yanitskiy7091e8d2019-09-09 01:07:37 +0200906 dynamic := {
907 tfi_assignment := tfi,
908 polling := polling,
Vadim Yanitskiy06ca64d2019-09-29 20:17:10 +0700909 spare := '0'B, /* Dynamic Block Allocation (mandatory after Rel-4) */
Vadim Yanitskiy7091e8d2019-09-09 01:07:37 +0200910 usf := usf,
911 usf_granularity := usf_granularity,
912 p0_present := ?,
913 p0 := *,
914 pr_mode := *,
915 ch_coding_cmd := cs,
916 tlli_block_chan_coding := ?,
917 alpha_present := ?,
918 alpha := *,
919 gamma := ?,
920 /* TODO: add to parameters */
921 ta_index_present := ?,
922 ta_index := *,
923 tbf_starting_time_present := ?,
924 tbf_starting_time := *
925 },
926 single := omit
927 };
928
929 template PacketUlAssign tr_PacketUlSglAssign := {
Vadim Yanitskiy06ca64d2019-09-29 20:17:10 +0700930 presence := '0'B, /* Single Block Allocation */
Vadim Yanitskiy7091e8d2019-09-09 01:07:37 +0200931 dynamic := omit,
932 single := {
933 alpha_present := ?,
934 alpha := *,
935 gamma := ?,
936 padding := '01'B,
937 tbf_starting_time := ?
938 }
939 };
940
941 template IaRestOctets tr_IaRestOctets_ULAss(template PacketUlAssign ul_ass) := {
942 presence := '11'B, /* HH */
943 ll := omit, lh := omit, hl := omit,
944 hh := {
945 pa_disc := '0'B, /* Packet Assignment (0) */
946 pa := {
947 uldl := {
948 ass_disc := '0'B, /* Uplink Assignment (0) */
949 ass := { ul := ul_ass }
950 }
951 }
952 }
953 };
954
Harald Weltee8d750e2018-06-10 21:41:35 +0200955 template (value) GsmRrMessage ts_IMM_ASS(uint8_t ra, GsmFrameNumber fn, TimingAdvance ta,
Harald Weltecbc947f2018-02-22 00:26:55 +0100956 ChannelDescription ch_desc, MobileAllocation ma) := {
957 header := t_RrHeader(IMMEDIATE_ASSIGNMENT, 0),
958 payload := {
959 imm_ass := {
960 ded_or_tbf := {
961 spare := '0'B,
962 tma := false,
963 downlink := false,
964 tbf := false
965 },
966 page_mode := PAGE_MODE_NORMAL,
967 chan_desc := ch_desc,
968 pkt_chan_desc := omit,
969 req_ref := f_compute_ReqRef(ra, fn),
970 timing_advance := ta,
971 mobile_allocation := ma,
Vadim Yanitskiyf10bb452019-09-05 13:53:01 +0200972 rest_octets := {
973 presence := '00'B, /* LL */
974 ll := {
975 /* Compressed INTER RAT HO INFO: shall not be used (L)
976 * TODO: use variant "CSN.1 L/H" to avoid confusion. */
977 compressed_irat_ho_info_ind := '1'B
Vadim Yanitskiy9b2a3e82019-09-08 15:37:15 +0200978 },
979 lh := omit, hl := omit, hh := omit
Vadim Yanitskiyf10bb452019-09-05 13:53:01 +0200980 }
Harald Weltecbc947f2018-02-22 00:26:55 +0100981 }
982 }
983 };
984
Harald Weltee8d750e2018-06-10 21:41:35 +0200985 template GsmRrMessage tr_IMM_ASS(template uint8_t ra := ?, template GsmFrameNumber fn := ?,
986 template TimingAdvance ta := ?,
987 template ChannelDescription ch_desc := ?,
988 template MobileAllocation ma := ?) := {
Vadim Yanitskiyd4205c32019-09-09 16:15:37 +0200989 header := t_RrHeader(IMMEDIATE_ASSIGNMENT, ?),
Harald Weltee8d750e2018-06-10 21:41:35 +0200990 payload := {
991 imm_ass := {
992 ded_or_tbf := {
993 spare := '0'B,
994 tma := false,
995 downlink := false,
996 tbf := false
997 },
998 page_mode := PAGE_MODE_NORMAL,
999 chan_desc := ch_desc,
1000 pkt_chan_desc := omit,
1001 req_ref := tr_compute_ReqRef(ra, fn),
1002 timing_advance := ta,
1003 mobile_allocation := ma,
Vadim Yanitskiyf10bb452019-09-05 13:53:01 +02001004 rest_octets := ?
Harald Weltee8d750e2018-06-10 21:41:35 +02001005 }
1006 }
1007 };
1008
Vadim Yanitskiy6edd4f52019-09-09 01:51:09 +02001009 /* TODO: implement send version of this template */
1010 template GsmRrMessage tr_IMM_TBF_ASS(template boolean dl := ?,
1011 template uint8_t ra := ?,
1012 template GsmFrameNumber fn := ?,
1013 template TimingAdvance ta := ?,
1014 template PacketChannelDescription ch_desc := ?,
1015 template IaRestOctets rest := ?) := {
1016 header := t_RrHeader(IMMEDIATE_ASSIGNMENT, ?),
1017 payload := {
1018 imm_ass := {
1019 ded_or_tbf := {
1020 spare := ?,
1021 tma := ?,
1022 downlink := dl,
1023 tbf := true
1024 },
1025 page_mode := ?,
1026 chan_desc := omit,
1027 pkt_chan_desc := ch_desc,
1028 req_ref := tr_compute_ReqRef(ra, fn),
1029 timing_advance := ta,
1030 mobile_allocation := ?,
1031 rest_octets := rest
1032 }
1033 }
1034 };
Harald Weltee8d750e2018-06-10 21:41:35 +02001035
Pau Espin Pedrol88bf5372019-12-09 21:12:28 +01001036 template GsmRrMessage tr_PAG_REQ1(template MobileIdentityLV mi1 := ?) := {
1037 header := t_RrHeader(PAGING_REQUEST_TYPE_1, ?),
1038 payload := {
1039 pag_req_1 := {
1040 chan_needed := {
1041 second := ?,
1042 first := ?
1043 },
1044 page_mode := PAGE_MODE_NORMAL,
1045 mi1 := mi1,
1046 mi2 := omit,
1047 rest_octets := ?
1048 }
1049 }
1050 };
1051
Harald Weltecbc947f2018-02-22 00:26:55 +01001052 template (value) GsmRrL3Message ts_MEAS_REP(boolean valid, uint6_t rxl_f, uint6_t rxl_s,
1053 uint3_t rxq_f, uint3_t rxq_s,
1054 template (omit) NcellReports reps) := {
1055 header := t_RrL3Header(MEASUREMENT_REPORT),
1056 payload := {
1057 meas_rep := {
1058 meas_res := {
1059 ba_used := '0'B,
1060 dtx_used := '0'B,
1061 rxlev_full_srv_cell := rxl_f,
1062 threeg_ba_used := '0'B,
Harald Welteeb1e6812018-02-22 18:43:48 +01001063 meas_valid := bool2bit(not valid),
Harald Weltecbc947f2018-02-22 00:26:55 +01001064 rxlev_sub_srv_cell := rxl_s,
1065 si23_ba_used := '0'B,
1066 rxqual_full_srv_cell := rxq_f,
1067 rxqual_sub_srv_cell := rxq_s,
1068 no_ncell_m := 0,
1069 ncell_reports := reps
1070 }
1071 }
1072 }
1073 };
1074
Harald Welte9419c8a2017-07-30 04:07:05 +02001075} with { encode "RAW" ; variant "FIELDORDER(msb)" }