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