blob: e5c2464d829bebb7ce7cf3541329c933d7aa027c [file] [log] [blame]
Harald Welte484160b2017-07-28 13:30:24 +02001/* TITAN REW encode/decode definitions for 3GPP TS 44.060 RLC/MAC Blocks */
Harald Welte34b5a952019-05-27 11:54:11 +02002
3/* (C) 2017-2018 Harald Welte <laforge@gnumonks.org>
4 * All rights reserved.
5 *
6 * Released under the terms of GNU General Public License, Version 2 or
7 * (at your option) any later version.
8 *
9 * SPDX-License-Identifier: GPL-2.0-or-later
10 */
11
Harald Welte484160b2017-07-28 13:30:24 +020012module RLCMAC_Types {
13 import from General_Types all;
14 import from Osmocom_Types all;
15 import from GSM_Types all;
Harald Welte9d348522017-08-01 00:27:39 +020016 import from RLCMAC_CSN1_Types all;
Harald Welte484160b2017-07-28 13:30:24 +020017
18 /* TS 44.060 10.4.7 */
19 type enumerated MacPayloadType {
20 MAC_PT_RLC_DATA ('00'B),
21 MAC_PT_RLCMAC_NO_OPT ('01'B),
22 MAC_PT_RLCMAC_OPT ('10'B),
23 MAC_PT_RESERVED ('11'B)
24 } with { variant "FIELDLENGTH(2)" };
25
26 /* TS 44.060 10.4.5 */
27 type enumerated MacRrbp {
28 RRBP_Nplus13_mod_2715648 ('00'B),
29 RRBP_Nplus17_or_18_mod_2715648 ('01'B),
Harald Welte1cd673d2018-03-02 21:41:31 +010030 RRBP_Nplus21_or_22_mod_2715648 ('10'B),
Harald Welte484160b2017-07-28 13:30:24 +020031 RRBP_Nplus26_mod_2715648 ('11'B)
32 } with { variant "FIELDLENGTH(2)" };
33
Pau Espin Pedrol65bab9e2019-12-04 21:05:10 +010034 function f_rrbp_fn_delay(MacRrbp rrbp) return uint32_t {
35 select (rrbp) {
36 case (RRBP_Nplus13_mod_2715648) { return 13; }
37 case (RRBP_Nplus17_or_18_mod_2715648) { return 17; }
38 case (RRBP_Nplus21_or_22_mod_2715648) { return 21; }
39 case (RRBP_Nplus26_mod_2715648) { return 26; }
40 }
41 return 0;
42 }
43
Pau Espin Pedrol372af7a2020-04-27 17:32:01 +020044 type enumerated EgprsHeaderType {
45 RLCMAC_HDR_TYPE_1,
46 RLCMAC_HDR_TYPE_2,
47 RLCMAC_HDR_TYPE_3
48 };
49
Pau Espin Pedroldc9666f2020-03-18 20:30:16 +010050 type enumerated CodingScheme {
51 CS_1,
52 CS_2,
53 CS_3,
54 CS_4,
Pau Espin Pedrol372af7a2020-04-27 17:32:01 +020055 MCS_0,
Pau Espin Pedroldc9666f2020-03-18 20:30:16 +010056 MCS_1,
57 MCS_2,
58 MCS_3,
59 MCS_4,
60 MCS_5,
61 MCS_6,
62 MCS_7,
63 MCS_8,
64 MCS_9
65 //MCS5_7, ?
66 // MCS6_9 ?
67 };
68
69 function f_rlcmac_cs_mcs2block_len(CodingScheme cs_mcs) return uint32_t {
70 select (cs_mcs) {
71 case (CS_1) { return 23; }
72 case (CS_2) { return 34; }
73 case (CS_3) { return 40; }
74 case (CS_4) { return 54; }
75 case (MCS_1) { return 27; }
76 case (MCS_2) { return 33; }
77 case (MCS_3) { return 42; }
78 case (MCS_4) { return 49; }
79 case (MCS_5) { return 61; }
80 case (MCS_6) { return 79; }
81 case (MCS_7) { return 119; }
82 case (MCS_8) { return 143; }
83 case (MCS_9) { return 155; }
84 }
85 return 0;
86 }
87
88 function f_rlcmac_block_len2cs_mcs(uint32_t len) return CodingScheme {
89 select (len) {
90 case (23) { return CS_1; }
91 case (34) { return CS_2; }
92 case (40) { return CS_3; }
93 case (54) { return CS_4; }
94 case (27) { return MCS_1; }
95 case (33) { return MCS_2; }
96 case (42) { return MCS_3; }
97 case (49) { return MCS_4; }
98 case (60) { return MCS_5; }
99 case (61) { return MCS_5; }
100 case (78) { return MCS_6; }
101 case (79) { return MCS_6; }
102 case (118) { return MCS_7; }
103 case (119) { return MCS_7; }
104 case (142) { return MCS_8; }
105 case (143) { return MCS_8; }
106 case (154) { return MCS_9; }
107 case (155) { return MCS_9; }
108 }
109 return CS_1;
110 }
111
Harald Welte484160b2017-07-28 13:30:24 +0200112 /* Partof DL RLC data block and DL RLC/MAC ctrl block */
113 type record DlMacHeader {
114 MacPayloadType payload_type,
115 MacRrbp rrbp,
116 boolean rrbp_valid,
117 uint3_t usf
118 } with {
119 variant (rrbp_valid) "FIELDLENGTH(1)"
120 };
121
122 /* TS 44.060 10.4.10a */
123 type enumerated PowerReduction {
124 PWR_RED_0_to_3dB ('00'B),
125 PWR_RED_3_to_7dB ('01'B),
126 PWR_RED_7_to_10dB ('10'B),
127 PWR_RED_RESERVED ('11'B)
128 } with { variant "FIELDLENGTH(2)" };
129
130 /* TS 44.060 10.4.9d */
131 type enumerated DirectionBit {
132 DIR_UPLINK_TBF ('0'B),
133 DIR_DOWNLINK_TBF ('1'B)
134 } with { variant "FIELDLENGTH(1)" };
135
136 type record TfiOctet {
137 /* PR, TFI, D */
138 PowerReduction pr,
139 uint5_t tfi,
140 DirectionBit d
141 } with { variant "" };
142
143 type record RbsnExtOctet {
144 uint3_t rbsn_e,
145 BIT1 fs_e,
146 BIT4 spare
147 } with { variant "" };
148
149 type record DlCtrlOptOctets {
150 /* RBSN, RTI, FS, AC (optional, depending on mac_hdr.payload_type) */
151 BIT1 rbsn,
152 uint5_t rti,
153 boolean fs,
154 boolean tfi_octet_present,
155 TfiOctet tfi optional,
156 RbsnExtOctet rbsn_ext optional
157 } with {
158 variant (fs) "FIELDLENGTH(1)"
159 variant (tfi_octet_present) "FIELDLENGTH(1)"
160 variant (tfi) "PRESENCE(tfi_octet_present = true)"
161 variant (rbsn_ext) "PRESENCE(rbsn='1'B, fs=false)"
162 };
163
164 /* TS 44.060 10.3.1 Downlink RLC/MAC control block */
165 type record RlcmacDlCtrlBlock {
166 DlMacHeader mac_hdr,
167 DlCtrlOptOctets opt optional,
Harald Welte9d348522017-08-01 00:27:39 +0200168 RlcmacDlCtrlMsg payload
Harald Welte484160b2017-07-28 13:30:24 +0200169 } with {
170 variant (opt) "PRESENCE(mac_hdr.payload_type = MAC_PT_RLCMAC_OPT)"
171 };
172
173 external function enc_RlcmacDlCtrlBlock(in RlcmacDlCtrlBlock si) return octetstring
174 with { extension "prototype(convert) encode(RAW)" };
175 external function dec_RlcmacDlCtrlBlock(in octetstring stream) return RlcmacDlCtrlBlock
176 with { extension "prototype(convert) decode(RAW)" };
177
178 type record UlMacCtrlHeader {
Harald Welteefbc2fc2017-07-31 00:05:23 +0200179 MacPayloadType payload_type,
Harald Welte484160b2017-07-28 13:30:24 +0200180 BIT5 spare,
181 boolean retry
182 } with { variant (retry) "FIELDLENGTH(1)" };
183
184 /* TS 44.060 10.3.2 UplinkRLC/MAC control block */
185 type record RlcmacUlCtrlBlock {
186 UlMacCtrlHeader mac_hdr,
Harald Welte9d348522017-08-01 00:27:39 +0200187 RlcmacUlCtrlMsg payload
Harald Welte484160b2017-07-28 13:30:24 +0200188 } with { variant "" };
189
190 external function enc_RlcmacUlCtrlBlock(in RlcmacUlCtrlBlock si) return octetstring
191 with { extension "prototype(convert) encode(RAW)" };
192 external function dec_RlcmacUlCtrlBlock(in octetstring stream) return RlcmacUlCtrlBlock
193 with { extension "prototype(convert) decode(RAW)" };
194
195 /* a single RLC block / LLC-segment */
Harald Welte43e060a2017-07-30 22:38:03 +0200196 type record LlcBlockHdr {
Harald Welte484160b2017-07-28 13:30:24 +0200197 uint6_t length_ind,
198 /* 1 = new LLC PDU starts */
Harald Welte060e27a2018-03-03 20:38:19 +0100199 boolean more,
Harald Welte484160b2017-07-28 13:30:24 +0200200 /* 0 = another extension octet after LLC PDU, 1 = no more extension octets */
Harald Welte43e060a2017-07-30 22:38:03 +0200201 boolean e
Harald Welte484160b2017-07-28 13:30:24 +0200202 } with {
Harald Welte43e060a2017-07-30 22:38:03 +0200203 variant (e) "FIELDLENGTH(1)"
Harald Weltecc5c1152018-03-09 12:54:01 +0100204 encode "RAW"
Harald Welte484160b2017-07-28 13:30:24 +0200205 };
Harald Weltecc5c1152018-03-09 12:54:01 +0100206
207 external function enc_LlcBlockHdr(in LlcBlockHdr si) return octetstring
208 with { extension "prototype(convert) encode(RAW)" };
209 external function dec_LlcBlockHdr(in octetstring stream) return LlcBlockHdr
210 with { extension "prototype(convert) decode(RAW)" };
211
Harald Welte43e060a2017-07-30 22:38:03 +0200212 type record LlcBlock {
213 /* Header is only present if LI field was present */
Harald Welte060e27a2018-03-03 20:38:19 +0100214 LlcBlockHdr hdr optional,
Harald Welte43e060a2017-07-30 22:38:03 +0200215 octetstring payload
216 } with { variant "" };
217 type record of LlcBlock LlcBlocks;
Harald Welte484160b2017-07-28 13:30:24 +0200218
219 /* TS 44.060 10.2.1 Downlink RLC data block */
Harald Welte43e060a2017-07-30 22:38:03 +0200220 type record DlMacHdrDataExt {
Harald Welte484160b2017-07-28 13:30:24 +0200221 /* Octet 1 */
Harald Welte484160b2017-07-28 13:30:24 +0200222 PowerReduction pr,
223 BIT1 spare,
224 uint4_t tfi, /* 3 or 4? */
225 boolean fbi,
Harald Welte43e060a2017-07-30 22:38:03 +0200226 /* Octet 2 */
Harald Welte484160b2017-07-28 13:30:24 +0200227 uint7_t bsn,
Harald Welte43e060a2017-07-30 22:38:03 +0200228 boolean e
229 } with {
230 variant (e) "FIELDLENGTH(1)"
231 };
232 type record DlMacDataHeader {
233 DlMacHeader mac_hdr,
234 DlMacHdrDataExt hdr_ext
Harald Welte484160b2017-07-28 13:30:24 +0200235 } with { variant "" };
Harald Welte43e060a2017-07-30 22:38:03 +0200236 type record RlcmacDlDataBlock {
237 DlMacDataHeader mac_hdr,
238 /* Octet 3..M / N: manual C++ Decoder */
239 LlcBlocks blocks
240 } with {
241 variant ""
242 };
Harald Welte484160b2017-07-28 13:30:24 +0200243
Harald Welte43e060a2017-07-30 22:38:03 +0200244 external function enc_RlcmacDlDataBlock(in RlcmacDlDataBlock si) return octetstring;
245 external function dec_RlcmacDlDataBlock(in octetstring stream) return RlcmacDlDataBlock;
Harald Welte484160b2017-07-28 13:30:24 +0200246
247
Pau Espin Pedrol372af7a2020-04-27 17:32:01 +0200248 /* a single RLC block / LLC-segment */
249 type record EgprsLlcBlockHdr {
250 uint7_t length_ind,
251 /* 0 = another extension octet after LLC PDU, 1 = no more extension octets */
252 boolean e
253 } with {
254 variant (e) "FIELDLENGTH(1)"
255 encode "RAW"
256 };
257
258 external function enc_EgprsLlcBlockHdr(in EgprsLlcBlockHdr si) return octetstring
259 with { extension "prototype(convert) encode(RAW)" };
260 external function dec_EgprsLlcBlockHdr(in octetstring stream) return EgprsLlcBlockHdr
261 with { extension "prototype(convert) decode(RAW)" };
262
263 type record EgprsLlcBlock {
264 /* Header is only present if LI field was present */
265 EgprsLlcBlockHdr hdr optional,
266 octetstring payload
267 } with { variant "" };
268 type record of EgprsLlcBlock EgprsLlcBlocks;
269
270 /* TS 44.060 10.3a.1.1 EGPRS downlink RLC data block, manual c++ encoder/decoder */
271 type record EgprsDlMacDataHeader {
272 EgprsHeaderType header_type, /* Set internally by decoder */
273 uint5_t tfi,
274 MacRrbp rrbp,
275 BIT2 esp,
276 uint3_t usf,
277 uint14_t bsn1,
278 uint8_t bsn2_offset,
279 uint2_t pr, /* power reduction */
280 uint2_t spb,
281 uint4_t cps
282 } with { variant "" };
283 /* Manual C++ Decoder: */
284 type record RlcmacDlEgprsDataBlock {
285 EgprsDlMacDataHeader mac_hdr,
286 boolean fbi,
287 boolean e,
288 EgprsLlcBlocks blocks
289 } with {
290 variant (fbi) "FIELDLENGTH(1)"
291 variant (e) "FIELDLENGTH(1)"
292 };
293
Harald Welte484160b2017-07-28 13:30:24 +0200294 /* TS 44.060 10.2.2 */
295 type record UlMacDataHeader {
Harald Welte43e060a2017-07-30 22:38:03 +0200296 /* Octet 0 */
Harald Welteefbc2fc2017-07-31 00:05:23 +0200297 MacPayloadType payload_type,
Harald Welte484160b2017-07-28 13:30:24 +0200298 uint4_t countdown,
299 boolean stall_ind,
Harald Welte43e060a2017-07-30 22:38:03 +0200300 boolean retry,
301 /* Octet 1 */
302 BIT1 spare,
303 boolean pfi_ind,
304 uint5_t tfi,
305 boolean tlli_ind,
306 /* Octet 2 */
307 uint7_t bsn,
308 boolean e
Harald Welte484160b2017-07-28 13:30:24 +0200309 } with {
Harald Welte43e060a2017-07-30 22:38:03 +0200310 variant (stall_ind) "FIELDLENGTH(1)"
311 variant (retry) "FIELDLENGTH(1)"
312 variant (pfi_ind) "FIELDLENGTH(1)"
313 variant (tlli_ind) "FIELDLENGTH(1)"
314 variant (e) "FIELDLENGTH(1)"
Harald Welte484160b2017-07-28 13:30:24 +0200315 };
316
Harald Welte484160b2017-07-28 13:30:24 +0200317 type record RlcMacUlPfi {
318 uint7_t pfi,
319 boolean m
320 } with {
321 variant (m) "FIELDLENGTH(1)"
322 };
323
Pau Espin Pedrol372af7a2020-04-27 17:32:01 +0200324 /* TS 44.060 10.3a.1.1 10.3a.4 EGPRS Uplink RLC/MAC header, manual c++ encoder/decoder */
325 type record EgprsUlMacDataHeader {
326 EgprsHeaderType header_type, /* Set internally by decoder */
327 uint5_t tfi,
328 uint4_t countdown,
329 BIT1 foi_si,
330 BIT1 r_ri,
331 uint11_t bsn1,
332 uint4_t cps,
333 boolean pfi_ind,
334 BIT1 rsb,
335 BIT2 spb
336 } with {
337 variant (pfi_ind) "FIELDLENGTH(1)"
338 };
339 /* Manual C++ Decoder: 10.3a.2.1 EGPRS Uplink RLC data block */
340 type record RlcmacUlEgprsDataBlock {
341 EgprsUlMacDataHeader mac_hdr,
342 boolean tlli_ind,
343 boolean e,
344 /* Octet 3 ... M (optional): manual C++ Decoder */
345 GprsTlli tlli optional,
346 RlcMacUlPfi pfi optional,
347 EgprsLlcBlocks blocks
348 } with {
349 variant (tlli_ind) "FIELDLENGTH(1)"
350 variant (e) "FIELDLENGTH(1)"
351 };
352
Harald Welte484160b2017-07-28 13:30:24 +0200353 /* TS 44.060 10.2.2 */
354 type record RlcmacUlDataBlock {
355 /* MAC header */
356 UlMacDataHeader mac_hdr,
Harald Welte43e060a2017-07-30 22:38:03 +0200357 /* Octet 3 ... M (optional): manual C++ Decoder */
358 GprsTlli tlli optional,
359 RlcMacUlPfi pfi optional,
360 LlcBlocks blocks
Harald Welte484160b2017-07-28 13:30:24 +0200361 } with {
Harald Welte43e060a2017-07-30 22:38:03 +0200362 variant (tlli) "PRESENCE(mac_hdr.tlli_ind = true)"
363 variant (pfi) "PRESENCE(mac_hdr.pfi_ind = true)"
Harald Welte484160b2017-07-28 13:30:24 +0200364 };
365
Harald Welte43e060a2017-07-30 22:38:03 +0200366 external function enc_RlcmacUlDataBlock(in RlcmacUlDataBlock si) return octetstring;
367 external function dec_RlcmacUlDataBlock(in octetstring stream) return RlcmacUlDataBlock;
Harald Welte484160b2017-07-28 13:30:24 +0200368
Harald Welteefbc2fc2017-07-31 00:05:23 +0200369 type union RlcmacUlBlock {
370 RlcmacUlDataBlock data,
Pau Espin Pedrol372af7a2020-04-27 17:32:01 +0200371 RlcmacUlEgprsDataBlock data_egprs,
Harald Welteefbc2fc2017-07-31 00:05:23 +0200372 RlcmacUlCtrlBlock ctrl
373 } with {
374 variant "TAG(data, mac_hdr.payload_type = MAC_PT_RLC_DATA;
Pau Espin Pedrol372af7a2020-04-27 17:32:01 +0200375 ctrl, {mac_hdr.payload_type = MAC_PT_RLCMAC_NO_OPT,
376 mac_hdr.payload_type = MAC_PT_RLCMAC_OPT};
377 data_egprs, {mac_hdr.header_type = RLCMAC_HDR_TYPE_1,
378 mac_hdr.header_type = RLCMAC_HDR_TYPE_2,
379 mac_hdr.header_type = RLCMAC_HDR_TYPE_3}
380 )"
Harald Welteefbc2fc2017-07-31 00:05:23 +0200381 };
382
Harald Welte78a1af62017-07-31 17:33:56 +0200383 /* as the sub-types (RlcmacDl*Block) are not using the RAW coder, we cannot
384 * use auto-generated functions here, as they would decode those sub-types
385 * based on the RAW coder, not baed on the manual C++ functions */
386 external function enc_RlcmacUlBlock(in RlcmacUlBlock si) return octetstring;
387 external function dec_RlcmacUlBlock(in octetstring stream) return RlcmacUlBlock;
Harald Welteefbc2fc2017-07-31 00:05:23 +0200388
389 type union RlcmacDlBlock {
390 RlcmacDlDataBlock data,
Pau Espin Pedrol372af7a2020-04-27 17:32:01 +0200391 RlcmacDlEgprsDataBlock data_egprs,
Harald Welteefbc2fc2017-07-31 00:05:23 +0200392 RlcmacDlCtrlBlock ctrl
393 } with {
394 variant "TAG(data, mac_hdr.mac_hdr.payload_type = MAC_PT_RLC_DATA;
Pau Espin Pedrol372af7a2020-04-27 17:32:01 +0200395 ctrl, {mac_hdr.payload_type = MAC_PT_RLCMAC_NO_OPT,
396 mac_hdr.payload_type = MAC_PT_RLCMAC_OPT};
397 data_egprs, {mac_hdr.header_type = RLCMAC_HDR_TYPE_1,
398 mac_hdr.header_type = RLCMAC_HDR_TYPE_2,
399 mac_hdr.header_type = RLCMAC_HDR_TYPE_3}
400 )"
Harald Welteefbc2fc2017-07-31 00:05:23 +0200401 };
402
Harald Welte78a1af62017-07-31 17:33:56 +0200403 /* as the sub-types (RlcmacDl*Block) are not using the RAW coder, we cannot
404 * use auto-generated functions here, as they would decode those sub-types
405 * based on the RAW coder, not baed on the manual C++ functions */
406 external function enc_RlcmacDlBlock(in RlcmacDlBlock si) return octetstring;
407 external function dec_RlcmacDlBlock(in octetstring stream) return RlcmacDlBlock;
Harald Welteefbc2fc2017-07-31 00:05:23 +0200408
Harald Welte7024baa2018-03-02 23:37:51 +0100409 template (value) RlcmacUlBlock ts_RLC_UL_CTRL_ACK(RlcmacUlCtrlMsg ctrl,
410 MacPayloadType pt := MAC_PT_RLCMAC_NO_OPT,
411 boolean retry := false) := {
412 ctrl := {
413 mac_hdr := {
414 payload_type := pt,
415 spare := '00000'B,
416 retry := retry
417 },
418 payload := ctrl
419 }
420 }
421
Pau Espin Pedrola3f0a852019-12-02 19:16:26 +0100422 /* Send Template for Downlink ACK/NACK */
423 template RlcmacUlBlock ts_RLCMAC_DL_ACK_NACK(template uint5_t tfi, AckNackDescription andesc, boolean retry := false) := {
424 ctrl := {
425 mac_hdr := {
426 payload_type := MAC_PT_RLCMAC_NO_OPT,
427 spare := '00000'B,
428 retry := retry
429 },
430 payload := {
431 msg_type := PACKET_DL_ACK_NACK,
432 u := {
433 dl_ack_nack := {
434 dl_tfi := tfi,
435 ack_nack_desc := andesc,
436 chreq_desc_presence := '0'B,
437 chreq_desc := omit,
438 ch_qual_rep := c_ChQualRep_default
439 }
440 }
441 }
442 }
443 }
444
445 /* Template for uplink Data block */
Harald Welte060e27a2018-03-03 20:38:19 +0100446 template RlcmacUlBlock t_RLCMAC_UL_DATA(template uint5_t tfi, template uint4_t cv, template uint7_t bsn,
447 template LlcBlocks blocks := {}, template boolean stall := false) := {
448 data := {
449 mac_hdr := {
450 payload_type := MAC_PT_RLC_DATA,
451 countdown := cv,
452 stall_ind := false,
453 retry := false,
454 spare := '0'B,
455 pfi_ind := false,
456 tfi := tfi,
457 tlli_ind := false,
458 bsn := bsn,
459 e := false
460 },
461 tlli := omit,
462 pfi := omit,
463 blocks := blocks
464 }
465 }
466 template RlcmacUlBlock t_RLCMAC_UL_DATA_TLLI(template uint5_t tfi, template uint4_t cv, template uint7_t bsn,
467 template LlcBlocks blocks := {}, template boolean stall := false, template GprsTlli tlli) := {
468 data := {
469 mac_hdr := {
470 payload_type := MAC_PT_RLC_DATA,
471 countdown := cv,
472 stall_ind := false,
473 retry := false,
474 spare := '0'B,
475 pfi_ind := false,
476 tfi := tfi,
477 tlli_ind := true,
478 bsn := bsn,
479 e := false
480 },
481 tlli := tlli,
482 pfi := omit,
483 blocks := blocks
484 }
485 }
486
487 template DlMacHeader t_RLCMAC_DlMacH(template MacPayloadType pt, template MacRrbp rrbp, template
488uint3_t usf) := {
489 payload_type := pt,
490 rrbp := rrbp,
491 rrbp_valid := ispresent(rrbp),
492 usf := usf
493 }
494
Oliver Smith8f9daab2019-10-09 09:27:19 +0200495 template RlcmacDlBlock tr_RLCMAC_DUMMY_CTRL(template uint3_t usf := ?, template PageMode page_mode := ?) := {
Pau Espin Pedrol596faa42019-10-04 19:31:29 +0200496 ctrl := {
497 mac_hdr := {
498 payload_type := (MAC_PT_RLCMAC_NO_OPT, MAC_PT_RLCMAC_OPT),
499 rrbp:= ?,
500 rrbp_valid := ?,
501 usf := usf
502 },
503 opt := *,
504 payload := {
505 msg_type := PACKET_DL_DUMMY_CTRL,
506 u := {
507 dl_dummy := {
Oliver Smith8f9daab2019-10-09 09:27:19 +0200508 page_mode := page_mode,
Pau Espin Pedrol596faa42019-10-04 19:31:29 +0200509 persistence_levels_present := ?,
510 persistence_levels := *
511 }
512 }
513 }
514 }
515 }
516
Pau Espin Pedrolff8da192019-12-05 17:23:58 +0100517 template RlcmacDlBlock tr_RLCMAC_DL_PACKET_ASS(template uint3_t usf := ?) := {
518 ctrl := {
519 mac_hdr := {
520 payload_type := (MAC_PT_RLCMAC_NO_OPT, MAC_PT_RLCMAC_OPT),
521 rrbp:= ?,
522 rrbp_valid := ?,
523 usf := usf
524 },
525 opt := *,
526 payload := {
527 msg_type := PACKET_DL_ASSIGNMENT,
528 u := {
529 dl_assignment := {
530 page_mode := ?,
531 pres1 := ?,
532 persistence_levels := *,
533 tfi_or_tlli := ?
534 }
535 }
536 }
537 }
538 }
539
Pau Espin Pedrol8f245712020-04-24 18:47:30 +0200540 template RlcmacDlBlock tr_RLCMAC_UL_PACKET_ASS(template uint3_t usf := ?) := {
541 ctrl := {
542 mac_hdr := {
543 payload_type := (MAC_PT_RLCMAC_NO_OPT, MAC_PT_RLCMAC_OPT),
544 rrbp:= ?,
545 rrbp_valid := ?,
546 usf := usf
547 },
548 opt := *,
549 payload := {
550 msg_type := PACKET_UL_ASSIGNMENT,
551 u := {
552 ul_assignment := {
553 page_mode := ?,
554 persistence_levels_present := ?,
555 persistence_levels := *,
556 identity := ?,
557 is_egprs := ?, /* msg escape */
558 gprs := *
559 }
560 }
561 }
562 }
563 }
564
565
Pau Espin Pedrol21659632019-12-02 19:12:08 +0100566 /* Receive Template for Uplink ACK/NACK */
567 template RlcmacDlBlock tr_RLCMAC_UL_ACK_NACK(template uint5_t ul_tfi, template GprsTlli tlli := ?) := {
Harald Welte060e27a2018-03-03 20:38:19 +0100568 ctrl := {
569 mac_hdr := {
570 payload_type := (MAC_PT_RLCMAC_NO_OPT, MAC_PT_RLCMAC_OPT),
571 rrbp:= ?,
Vadim Yanitskiy0eb26622019-09-14 20:35:28 +0200572 rrbp_valid := ?,
Harald Welte060e27a2018-03-03 20:38:19 +0100573 usf := ?
574 },
575 opt := *,
576 payload := {
577 msg_type := PACKET_UL_ACK_NACK,
578 u := {
579 ul_ack_nack := {
580 page_mode := ?,
581 msg_excape := ?,
582 uplink_tfi := ul_tfi,
583 is_egprs := '0'B,
584 gprs := {
585 ch_coding_cmd := ?,
586 ack_nack_desc := ?,
587 cont_res_tlli_present := ?,
588 cont_res_tlli := tlli,
589 pkt_ta_present := ?,
590 pkt_ta := *,
591 pwr_ctrl_present := ?,
592 pwr_ctrl := *
593 }
594 }
595 }
596 }
597 }
598 }
599
Oliver Smith8f9daab2019-10-09 09:27:19 +0200600 template RlcmacDlBlock tr_RLCMAC_PACKET_PAG_REQ(template uint3_t usf := ?) := {
601 ctrl := {
602 mac_hdr := {
603 payload_type := MAC_PT_RLCMAC_NO_OPT,
604 rrbp:= ?,
605 rrbp_valid := ?,
606 usf := usf
607 },
608 opt := *,
609 payload := {
610 msg_type := PACKET_PAGING_REQUEST,
611 u := {
612 paging := {
613 page_mode := ?,
614 persistence_levels_present := ?,
615 persistence_levels := *,
616 nln_present := ?,
617 nln := *,
618 repeated_pageinfo_present := ?,
619 repeated_pageinfo := *
620 }
621 }
622 }
623 }
624 }
625
Harald Welteb669ee02018-03-09 12:50:02 +0100626 template RlcmacDlBlock tr_RLCMAC_DATA_RRBP := {
627 data := {
628 mac_hdr := {
629 mac_hdr := {
630 payload_type := MAC_PT_RLC_DATA,
631 rrbp := ?,
632 rrbp_valid := true,
633 usf := ?
634 },
635 hdr_ext := ?
636 },
637 blocks := ?
638 }
639 }
640
Pau Espin Pedrol372af7a2020-04-27 17:32:01 +0200641 template RlcmacDlBlock tr_RLCMAC_DATA_EGPRS := {
642 data_egprs := {
643 mac_hdr := ?,
644 fbi := ?,
645 e := ?,
646 blocks := ?
647 }
648 }
649
Harald Welte060e27a2018-03-03 20:38:19 +0100650 /* Template for Uplink MAC Control Header */
651 template UlMacCtrlHeader t_RLCMAC_UlMacCtrlH(template MacPayloadType pt, template boolean retry := false) := {
652 payload_type := pt,
653 spare := '00000'B,
654 retry := retry
655 }
656
Pau Espin Pedrol21659632019-12-02 19:12:08 +0100657 /* Template for Uplink Control ACK */
Harald Welte060e27a2018-03-03 20:38:19 +0100658 template RlcmacUlBlock ts_RLCMAC_CTRL_ACK(GprsTlli tlli, CtrlAck ack := MS_RCVD_TWO_RLC_SAME_RTI_DIFF_RBSN) := {
659 ctrl := {
660 mac_hdr := t_RLCMAC_UlMacCtrlH(MAC_PT_RLCMAC_NO_OPT),
661 payload := {
662 msg_type := PACKET_CONTROL_ACK,
663 u := {
664 ctrl_ack := {
665 tlli := tlli,
666 ctrl_ack := ack
667 }
668 }
669 }
670 }
671 }
672
673 /* Template for a LlcBlock (part of a LLC frame inside RlcMac?lDataBlock */
674 template LlcBlock t_RLCMAC_LLCBLOCK(octetstring data, boolean more := false, boolean e := true) := {
675 /* let encoder figure out the header */
676 hdr := omit,
677 payload := data
678 }
679
Pau Espin Pedrolfe3ae512020-04-28 18:05:59 +0200680/************************
681 * PTCCH/D (Packet Timing Advance Control Channel) message.
682 * TODO: add a spec. reference to the message format definition.
683 *************************/
Vadim Yanitskiy1bd8ec52019-10-01 05:44:52 +0700684 type record PTCCHTimingAdvanceIE {
685 BIT1 spare ('0'B),
686 uint7_t ta_val
687 } with { variant "" };
688 type record of PTCCHTimingAdvanceIE PTCCHTimingAdvanceIEs;
689 type record PTCCHDownlinkMsg {
690 PTCCHTimingAdvanceIEs ta_idx length(16),
691 octetstring padding length(7)
692 } with { variant "" };
693
694 external function enc_PTCCHDownlinkMsg(in PTCCHDownlinkMsg si) return octetstring
695 with { extension "prototype(convert) encode(RAW)" };
696 external function dec_PTCCHDownlinkMsg(in octetstring stream) return PTCCHDownlinkMsg
697 with { extension "prototype(convert) decode(RAW)" };
698
699 template PTCCHDownlinkMsg tr_PTCCHDownlinkMsg(
700 template (present) uint7_t tai0_ta := ?,
701 template (present) uint7_t tai1_ta := ?,
702 template (present) uint7_t tai2_ta := ?,
703 template (present) uint7_t tai3_ta := ?,
704 template (present) uint7_t tai4_ta := ?,
705 template (present) uint7_t tai5_ta := ?,
706 template (present) uint7_t tai6_ta := ?,
707 template (present) uint7_t tai7_ta := ?,
708 template (present) uint7_t tai8_ta := ?,
709 template (present) uint7_t tai9_ta := ?,
710 template (present) uint7_t tai10_ta := ?,
711 template (present) uint7_t tai11_ta := ?,
712 template (present) uint7_t tai12_ta := ?,
713 template (present) uint7_t tai13_ta := ?,
714 template (present) uint7_t tai14_ta := ?,
715 template (present) uint7_t tai15_ta := ?
716 ) := {
717 ta_idx := {
718 { spare := '0'B, ta_val := tai0_ta },
719 { spare := '0'B, ta_val := tai1_ta },
720 { spare := '0'B, ta_val := tai2_ta },
721 { spare := '0'B, ta_val := tai3_ta },
722 { spare := '0'B, ta_val := tai4_ta },
723 { spare := '0'B, ta_val := tai5_ta },
724 { spare := '0'B, ta_val := tai6_ta },
725 { spare := '0'B, ta_val := tai7_ta },
726 { spare := '0'B, ta_val := tai8_ta },
727 { spare := '0'B, ta_val := tai9_ta },
728 { spare := '0'B, ta_val := tai10_ta },
729 { spare := '0'B, ta_val := tai11_ta },
730 { spare := '0'B, ta_val := tai12_ta },
731 { spare := '0'B, ta_val := tai13_ta },
732 { spare := '0'B, ta_val := tai14_ta },
733 { spare := '0'B, ta_val := tai15_ta }
734 },
735 padding := '2B2B2B2B2B2B2B'O
736 }
737
Harald Welte060e27a2018-03-03 20:38:19 +0100738
Harald Welte484160b2017-07-28 13:30:24 +0200739} with { encode "RAW"; variant "FIELDORDER(msb)" }