blob: f7bd5703a24ac11c6027175f36371ba0fcacd0d7 [file] [log] [blame]
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +02001/* TITAN REW encode/decode definitions for 3GPP TS 44.060 RLC/MAC Blocks */
2
3/* (C) 2017-2018 Harald Welte <laforge@gnumonks.org>
4 * (C) 2020 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
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 */
12
13module RLCMAC_Templates {
14 import from General_Types all;
15 import from Osmocom_Types all;
16 import from GSM_Types all;
17 import from RLCMAC_CSN1_Types all;
18 import from RLCMAC_CSN1_Templates all;
19 import from RLCMAC_Types all;
20
21 /* TS 44.060 10.4.5 */
22 function f_rrbp_fn_delay(MacRrbp rrbp) return uint32_t {
23 select (rrbp) {
24 case (RRBP_Nplus13_mod_2715648) { return 13; }
25 case (RRBP_Nplus17_or_18_mod_2715648) { return 17; }
26 case (RRBP_Nplus21_or_22_mod_2715648) { return 21; }
27 case (RRBP_Nplus26_mod_2715648) { return 26; }
28 }
29 return 0;
30 }
31
Vadim Yanitskiy2742bcd2020-05-10 12:45:18 +070032 function f_rrbp_ack_fn(uint32_t current_fn, MacRrbp rrbp)
33 return uint32_t {
34 return (current_fn + f_rrbp_fn_delay(rrbp)) mod 2715648;
35 }
36
Pau Espin Pedrol27d6af52020-04-30 20:13:32 +020037 function f_rlcmac_mcs2headertype(CodingScheme mcs) return EgprsHeaderType {
38 select (mcs) {
39 case (MCS_0) { return RLCMAC_HDR_TYPE_3; }
40 case (MCS_1) { return RLCMAC_HDR_TYPE_3; }
41 case (MCS_2) { return RLCMAC_HDR_TYPE_3; }
42 case (MCS_3) { return RLCMAC_HDR_TYPE_3; }
43 case (MCS_4) { return RLCMAC_HDR_TYPE_3; }
44 case (MCS_5) { return RLCMAC_HDR_TYPE_2; }
45 case (MCS_6) { return RLCMAC_HDR_TYPE_2; }
46 case (MCS_7) { return RLCMAC_HDR_TYPE_1; }
47 case (MCS_8) { return RLCMAC_HDR_TYPE_1; }
48 case (MCS_9) { return RLCMAC_HDR_TYPE_1; }
49 }
50 return RLCMAC_HDR_TYPE_3;
51 }
52
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +020053 function f_rlcmac_cs_mcs2block_len(CodingScheme cs_mcs) return uint32_t {
54 select (cs_mcs) {
55 case (CS_1) { return 23; }
56 case (CS_2) { return 34; }
57 case (CS_3) { return 40; }
58 case (CS_4) { return 54; }
59 case (MCS_1) { return 27; }
60 case (MCS_2) { return 33; }
61 case (MCS_3) { return 42; }
62 case (MCS_4) { return 49; }
63 case (MCS_5) { return 61; }
64 case (MCS_6) { return 79; }
65 case (MCS_7) { return 119; }
66 case (MCS_8) { return 143; }
67 case (MCS_9) { return 155; }
68 }
69 return 0;
70 }
71
72 function f_rlcmac_block_len2cs_mcs(uint32_t len) return CodingScheme {
73 select (len) {
74 case (23) { return CS_1; }
75 case (34) { return CS_2; }
76 case (40) { return CS_3; }
77 case (54) { return CS_4; }
78 case (27) { return MCS_1; }
79 case (33) { return MCS_2; }
80 case (42) { return MCS_3; }
81 case (49) { return MCS_4; }
82 case (60) { return MCS_5; }
83 case (61) { return MCS_5; }
84 case (78) { return MCS_6; }
85 case (79) { return MCS_6; }
86 case (118) { return MCS_7; }
87 case (119) { return MCS_7; }
88 case (142) { return MCS_8; }
89 case (143) { return MCS_8; }
90 case (154) { return MCS_9; }
91 case (155) { return MCS_9; }
92 }
93 return CS_1;
94 }
95
Pau Espin Pedrol245bfcb2020-06-30 20:17:07 +020096 /* Minimum CodingScheme required to fit RLCMAC block */
97 function f_rlcmac_block_len_required_cs_mcs(uint32_t len, boolean is_mcs) return CodingScheme {
98 if (is_mcs) {
99 if (len <= 27) { return MCS_1; }
100 if (len <= 33) { return MCS_2; }
101 if (len <= 42) { return MCS_3; }
102 if (len <= 49) { return MCS_4; }
103 if (len <= 60) { return MCS_5; }
104 if (len <= 61) { return MCS_5; }
105 if (len <= 79) { return MCS_6; }
106 if (len <= 119) { return MCS_7; }
107 if (len <= 143) { return MCS_8; }
108 if (len <= 155) { return MCS_9; }
109 return MCS_1; /* error! */
110 } else {
111 /* 3GPP TS 44.060 Table 10.2.1: RLC data block size, discounting padding in octet */
112 if (len <= 23) { return CS_1; }
113 if (len <= 33) { return CS_2; }
114 if (len <= 39) { return CS_3; }
115 if (len <= 53) { return CS_4; }
116 return CS_1; /* error! */
117 }
118 }
119
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +0200120 function f_rlcmac_block_ChCodingCommand2cs_mcs(ChCodingCommand chcc) return CodingScheme {
121 select (chcc) {
122 case (CH_CODING_CS1) { return CS_1; }
123 case (CH_CODING_CS2) { return CS_2; }
124 case (CH_CODING_CS3) { return CS_3; }
125 case (CH_CODING_CS4) { return CS_4; }
126 }
127 return CS_1;
128 }
129
130 function f_rlcmac_block_EgprsChCodingCommand2cs_mcs(EgprsChCodingCommand echcc) return CodingScheme {
131 select (echcc) {
132 case (CH_CODING_MCS1) { return MCS_1; }
133 case (CH_CODING_MCS2) { return MCS_2; }
134 case (CH_CODING_MCS3) { return MCS_3; }
135 case (CH_CODING_MCS4) { return MCS_4; }
136 case (CH_CODING_MCS5) { return MCS_5; }
137 case (CH_CODING_MCS6) { return MCS_6; }
138 case (CH_CODING_MCS7) { return MCS_7; }
139 case (CH_CODING_MCS8) { return MCS_8; }
140 case (CH_CODING_MCS9) { return MCS_9; }
141 /* CH_CODING_MCS5_7 */
142 /* CH_CODING_MCS6_9 */
143 }
144 return MCS_1;
145 }
146
147 /* 1 -> CS_1 / MCS_1, 2 -> CS_2 / MCS_2, etc. */
148 function f_rlcmac_block_int2cs_mcs(integer n, boolean is_mcs) return CodingScheme {
149 var CodingScheme cs_mcs;
150 if (not is_mcs) {
151 int2enum(n - 1, cs_mcs);
152 return cs_mcs;
153 } else {
154 cs_mcs := MCS_0;
155 int2enum(enum2int(cs_mcs) + n, cs_mcs);
156 return cs_mcs;
157 }
158 }
159
Pau Espin Pedrol27d6af52020-04-30 20:13:32 +0200160 /* Coding and Puncturing Scheme indicator field for Header type 1 in EGPRS TBF or EC TBF or downlink EGPRS2 TBF */
161 function f_rlcmac_cps_htype1_to_mcs(uint3_t cps) return CodingScheme {
162 var CodingSchemeArray egprs_Header_type1_coding_puncturing_scheme_to_mcs := {
163 MCS_9 /* 0x00, "(MCS-9/P1 ; MCS-9/P1)" */,
164 MCS_9 /* 0x01, "(MCS-9/P1 ; MCS-9/P2)" */,
165 MCS_9 /* 0x02, "(MCS-9/P1 ; MCS-9/P3)" */,
166 MCS_0 /* 0x03, "reserved" */,
167 MCS_9 /* 0x04, "(MCS-9/P2 ; MCS-9/P1)" */,
168 MCS_9 /* 0x05, "(MCS-9/P2 ; MCS-9/P2)" */,
169 MCS_9 /* 0x06, "(MCS-9/P2 ; MCS-9/P3)" */,
170 MCS_0 /* 0x07, "reserved" */,
171 MCS_9 /* 0x08, "(MCS-9/P3 ; MCS-9/P1)" */,
172 MCS_9 /* 0x09, "(MCS-9/P3 ; MCS-9/P2)" */,
173 MCS_9 /* 0x0A, "(MCS-9/P3 ; MCS-9/P3)" */,
174 MCS_8 /* 0x0B, "(MCS-8/P1 ; MCS-8/P1)" */,
175 MCS_8 /* 0x0C, "(MCS-8/P1 ; MCS-8/P2)" */,
176 MCS_8 /* 0x0D, "(MCS-8/P1 ; MCS-8/P3)" */,
177 MCS_8 /* 0x0E, "(MCS-8/P2 ; MCS-8/P1)" */,
178 MCS_8 /* 0x0F, "(MCS-8/P2 ; MCS-8/P2)" */,
179 MCS_8 /* 0x10, "(MCS-8/P2 ; MCS-8/P3)" */,
180 MCS_8 /* 0x11, "(MCS-8/P3 ; MCS-8/P1)" */,
181 MCS_8 /* 0x12, "(MCS-8/P3 ; MCS-8/P2)" */,
182 MCS_8 /* 0x13, "(MCS-8/P3 ; MCS-8/P3)" */,
183 MCS_7 /* 0x14, "(MCS-7/P1 ; MCS-7/P1)" */,
184 MCS_7 /* 0x15, "(MCS-7/P1 ; MCS-7/P2)" */,
185 MCS_7 /* 0x16, "(MCS-7/P1 ; MCS-7/P3)" */,
186 MCS_7 /* 0x17, "(MCS-7/P2 ; MCS-7/P1)" */,
187 MCS_7 /* 0x18, "(MCS-7/P2 ; MCS-7/P2)" */,
188 MCS_7 /* 0x19, "(MCS-7/P2 ; MCS-7/P3)" */,
189 MCS_7 /* 0x1A, "(MCS-7/P3 ; MCS-7/P1)" */,
190 MCS_7 /* 0x1B, "(MCS-7/P3 ; MCS-7/P2)" */,
191 MCS_7 /* 0x1C, "(MCS-7/P3 ; MCS-7/P3)" */,
192 MCS_0 /* 0x1D, "reserved" */,
193 MCS_0 /* 0x1E, "reserved" */,
194 MCS_0 /* 0x1F, "reserved" */
195 };
196 return egprs_Header_type1_coding_puncturing_scheme_to_mcs[cps];
197 }
198
199 /* Coding and Puncturing Scheme indicator field for Header type 2 in (EC-)EGPRS TBF or uplink EGPRS2-A TBF */
200 function f_rlcmac_cps_htype2_to_mcs(uint3_t cps) return CodingScheme {
201 var CodingSchemeArray egprs_Header_type2_coding_puncturing_scheme_to_mcs := {
202 MCS_6 /* {0x00, "MCS-6/P1"} */,
203 MCS_6 /* {0x01, "MCS-6/P2"} */,
204 MCS_6 /* {0x02, "MCS-6/P1 with 6 octet padding"} */,
205 MCS_6 /* {0x03, "MCS-6/P2 with 6 octet padding "} */,
206 MCS_5 /* {0x04, "MCS-5/P1"} */,
207 MCS_5 /* {0x05, "MCS-5/P2"} */,
208 MCS_5 /* {0x06, "MCS-6/P1 with 10 octet padding "} */,
209 MCS_5 /* {0x07, "MCS-6/P2 with 10 octet padding "} */
210 };
211 return egprs_Header_type2_coding_puncturing_scheme_to_mcs[cps];
212 }
213
214 /* Coding and Puncturing Scheme indicator field for Header type 3 */
215 function f_rlcmac_cps_htype3_to_mcs(uint3_t cps) return CodingScheme {
216 var CodingSchemeArray egprs_Header_type3_coding_puncturing_scheme_to_mcs := {
217 MCS_4 /* {0x00, "MCS-4/P1"} */,
218 MCS_4 /* {0x01, "MCS-4/P2"} */,
219 MCS_4 /* {0x02, "MCS-4/P3"} */,
220 MCS_3 /* {0x03, "MCS-3/P1"} */,
221 MCS_3 /* {0x04, "MCS-3/P2"} */,
222 MCS_3 /* {0x05, "MCS-3/P3"} */,
223 MCS_3 /* {0x06, "MCS-3/P1 with padding"} */,
224 MCS_3 /* {0x07, "MCS-3/P2 with padding"} */,
225 MCS_3 /* {0x08, "MCS-3/P3 with padding"} */,
226 MCS_2 /* {0x09, "MCS-2/P1"} */,
227 MCS_2 /* {0x0A, "MCS-2/P2"} */,
228 MCS_1 /* {0x0B, "MCS-1/P1"} */,
229 MCS_1 /* {0x0C, "MCS-1/P2"} */,
230 MCS_2 /* {0x0D, "MCS-2/P1 with padding"} */,
231 MCS_2 /* {0x0E, "MCS-2/P2 with padding"} */,
232 MCS_0 /* {0x0F, "MCS-0"} */
233 };
234 return egprs_Header_type3_coding_puncturing_scheme_to_mcs[cps];
235 }
236
237 function f_rlcmac_cps_htype_to_mcs(uint3_t cps, EgprsHeaderType htype) return CodingScheme {
238 select (htype) {
239 case (RLCMAC_HDR_TYPE_1) { return f_rlcmac_cps_htype1_to_mcs(cps); }
240 case (RLCMAC_HDR_TYPE_2) { return f_rlcmac_cps_htype2_to_mcs(cps); }
241 case (RLCMAC_HDR_TYPE_3) { return f_rlcmac_cps_htype3_to_mcs(cps); }
242 }
243 //TODO: return error here.
244 return CS_1;
245 }
246
247 function f_rlcmac_mcs_to_cps_htype1(CodingScheme mcs, uint2_t part, boolean with_padding) return uint5_t {
248 //TODO: implement similar to f_rlcmac_mcs_to_cps_htype3()
249 //TODO: return error here.
250 return 0;
251 }
252
253 function f_rlcmac_mcs_to_cps_htype2(CodingScheme mcs, uint2_t part, boolean with_padding) return uint5_t {
254 //TODO: implement similar to f_rlcmac_mcs_to_cps_htype3()
255 //TODO: return error here.
256 return 0;
257 }
258
259 function f_rlcmac_mcs_to_cps_htype3(CodingScheme mcs, uint2_t part, boolean with_padding) return uint5_t {
260 select (mcs) {
261 case (MCS_4) {
262 select (part) {
263 case (1) { return 0; /* {0x00, "MCS-4/P1"} */ }
264 case (2) { return 1; /* {0x01, "MCS-4/P2"} */ }
265 case (3) { return 2; /* {0x01, "MCS-4/P2"} */ }
266 }
267 }
268 case (MCS_3) {
269 if (not with_padding) {
270 select (part) {
271 case (1) { return 3; /* {0x03, "MCS-3/P1"} */ }
272 case (2) { return 4; /* {0x04, "MCS-3/P2"} */ }
273 case (3) { return 5; /* {0x05, "MCS-3/P3"} */ }
274 }
275 } else {
276 select (part) {
277 case (1) { return 6; /* {0x06, "MCS-3/P1 with padding"} */ }
278 case (2) { return 7; /* {0x07, "MCS-3/P2 with padding"} */ }
279 case (3) { return 8; /* {0x08, "MCS-3/P3 with padding"} */ }
280 }
281 }
282 }
283 case (MCS_2) {
284 if (not with_padding) {
285 select (part) {
286 case (1) { return 9; /* {0x09, "MCS-2/P1"} */ }
287 case (2) { return 10; /* {0x0A, "MCS-2/P2"} */ }
288 }
289 } else {
290 select (part) {
291 case (1) { return 13; /* {0x0D, "MCS-2/P1 with padding"} */ }
292 case (2) { return 14; /* {0x0E, "MCS-2/P2 with padding"} */}
293 }
294 }
295 }
296 case (MCS_1) {
297 select (part) {
298 case (1) { return 11; /* {0x0B, "MCS-1/P1"} */ }
299 case (2) { return 12; /* {0x0C, "MCS-1/P2"} */ }
300 }
301 }
302 case (MCS_0) { return 15; /* {0x0F, "MCS-0"} */ }
303 }
304 //TODO: return error here.
305 return 0;
306 }
307
308 function f_rlcmac_mcs_to_cps(CodingScheme mcs, uint2_t part, boolean with_padding := false) return uint5_t {
309
310 var EgprsHeaderType htype := f_rlcmac_mcs2headertype(mcs);
311 select (htype) {
312 case (RLCMAC_HDR_TYPE_1) { return f_rlcmac_mcs_to_cps_htype1(mcs, part, with_padding); }
313 case (RLCMAC_HDR_TYPE_2) { return f_rlcmac_mcs_to_cps_htype2(mcs, part, with_padding); }
314 case (RLCMAC_HDR_TYPE_3) { return f_rlcmac_mcs_to_cps_htype3(mcs, part, with_padding); }
315 }
316 //TODO: return error here.
317 return 0;
318 }
319
Vadim Yanitskiyf3cb4dd2020-07-21 01:52:33 +0700320 template (value) RlcmacUlBlock ts_RLC_UL_CTRL_ACK(template (value) RlcmacUlCtrlMsg ctrl,
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200321 MacPayloadType pt := MAC_PT_RLCMAC_NO_OPT,
322 boolean retry := false) := {
323 ctrl := {
324 mac_hdr := {
325 payload_type := pt,
326 spare := '00000'B,
327 retry := retry
328 },
329 payload := ctrl
330 }
331 }
332
333 /* Send Template for Downlink ACK/NACK */
334 template RlcmacUlBlock ts_RLCMAC_DL_ACK_NACK(template uint5_t tfi, AckNackDescription andesc, boolean retry := false) := {
335 ctrl := {
336 mac_hdr := {
337 payload_type := MAC_PT_RLCMAC_NO_OPT,
338 spare := '00000'B,
339 retry := retry
340 },
341 payload := {
342 msg_type := PACKET_DL_ACK_NACK,
343 u := {
344 dl_ack_nack := {
345 dl_tfi := tfi,
346 ack_nack_desc := andesc,
347 chreq_desc_presence := '0'B,
348 chreq_desc := omit,
349 ch_qual_rep := c_ChQualRep_default
350 }
351 }
352 }
353 }
354 }
355
Pau Espin Pedrol6791eb62020-05-20 18:27:10 +0200356 template RlcmacUlBlock ts_RLCMAC_DL_ACK_NACK_CHREQ(template uint5_t tfi,
357 AckNackDescription andesc,
358 boolean retry := false,
359 template ChannelReqDescription chreq_desc := c_ChReqDesc_default)
360 modifies ts_RLCMAC_DL_ACK_NACK := {
361 ctrl := {
362 payload := {
363 u := {
364 dl_ack_nack := {
365 chreq_desc_presence := '1'B,
366 chreq_desc := chreq_desc
367 }
368 }
369 }
370 }
371 }
372
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200373 /* Template for uplink Data block */
374 template RlcmacUlBlock t_RLCMAC_UL_DATA(template uint5_t tfi, template uint4_t cv, template uint7_t bsn,
375 template LlcBlocks blocks := {}, template boolean stall := false) := {
376 data := {
Pau Espin Pedrol5abfded2020-11-03 17:30:44 +0100377 cs := CS_1, /* TODO: make this available to template */
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200378 mac_hdr := {
379 payload_type := MAC_PT_RLC_DATA,
380 countdown := cv,
381 stall_ind := false,
382 retry := false,
383 spare := '0'B,
384 pfi_ind := false,
385 tfi := tfi,
386 tlli_ind := false,
387 bsn := bsn,
388 e := false
389 },
390 tlli := omit,
391 pfi := omit,
392 blocks := blocks
393 }
394 }
395 template RlcmacUlBlock t_RLCMAC_UL_DATA_TLLI(template uint5_t tfi, template uint4_t cv, template uint7_t bsn,
396 template LlcBlocks blocks := {}, template boolean stall := false, template GprsTlli tlli) := {
397 data := {
Pau Espin Pedrol5abfded2020-11-03 17:30:44 +0100398 cs := CS_1, /* TODO: make this available to template */
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200399 mac_hdr := {
400 payload_type := MAC_PT_RLC_DATA,
401 countdown := cv,
402 stall_ind := false,
403 retry := false,
404 spare := '0'B,
405 pfi_ind := false,
406 tfi := tfi,
407 tlli_ind := true,
408 bsn := bsn,
409 e := false
410 },
411 tlli := tlli,
412 pfi := omit,
413 blocks := blocks
414 }
415 }
416
Pau Espin Pedrol2456dad2020-04-30 20:22:38 +0200417 /* Template for uplink Data block */
418 template RlcmacUlBlock t_RLCMAC_UL_EGPRS_DATA(CodingScheme mcs,
419 template uint5_t tfi, template uint4_t cv,
420 template uint11_t bsn1, template EgprsLlcBlocks blocks := {}) := {
421 data_egprs := {
Pau Espin Pedrol5abfded2020-11-03 17:30:44 +0100422 mcs := mcs,
Pau Espin Pedrol2456dad2020-04-30 20:22:38 +0200423 mac_hdr := {
424 header_type := f_rlcmac_mcs2headertype(mcs),
425 tfi := tfi,
426 countdown := cv,
427 foi_si := '0'B,
428 r_ri := '0'B,
429 bsn1 := bsn1,
430 cps := f_rlcmac_mcs_to_cps(mcs, 1, false),
431 pfi_ind := false,
432 rsb := '0'B,
433 spb := '00'B
434 },
435 tlli_ind := false,
436 e := false,
437 tlli := omit,
438 pfi := omit,
439 blocks := blocks
440 }
441 }
442
Vadim Yanitskiy0a9b1482020-05-10 14:43:21 +0700443 template DlMacHeader t_RLCMAC_DlMacH(template (present) MacPayloadType pt,
444 template (present) boolean rrbp_valid,
445 template (present) MacRrbp rrbp,
446 template (present) uint3_t usf) := {
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200447 payload_type := pt,
448 rrbp := rrbp,
Vadim Yanitskiy0a9b1482020-05-10 14:43:21 +0700449 rrbp_valid := rrbp_valid,
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200450 usf := usf
451 }
452
453 template RlcmacDlBlock tr_RLCMAC_DUMMY_CTRL(template uint3_t usf := ?, template PageMode page_mode := ?) := {
454 ctrl := {
455 mac_hdr := {
456 payload_type := (MAC_PT_RLCMAC_NO_OPT, MAC_PT_RLCMAC_OPT),
457 rrbp:= ?,
458 rrbp_valid := ?,
459 usf := usf
460 },
461 opt := *,
462 payload := {
463 msg_type := PACKET_DL_DUMMY_CTRL,
464 u := {
465 dl_dummy := {
466 page_mode := page_mode,
467 persistence_levels_present := ?,
468 persistence_levels := *
469 }
470 }
471 }
472 }
473 }
474
475 template RlcmacDlBlock tr_RLCMAC_DL_PACKET_ASS(template uint3_t usf := ?) := {
476 ctrl := {
477 mac_hdr := {
478 payload_type := (MAC_PT_RLCMAC_NO_OPT, MAC_PT_RLCMAC_OPT),
479 rrbp:= ?,
480 rrbp_valid := ?,
481 usf := usf
482 },
483 opt := *,
484 payload := {
485 msg_type := PACKET_DL_ASSIGNMENT,
486 u := {
487 dl_assignment := {
488 page_mode := ?,
489 pres1 := ?,
490 persistence_levels := *,
Pau Espin Pedrol984d09f2020-05-19 18:51:58 +0200491 tfi_or_tlli := ?,
492 egprs2 := '0'B,
493 mac_mode := ?,
494 rlc_mode := ?,
495 control_ack := ?,
496 timeslot_alloc := ?,
497 pkt_ta := ?,
498 p0_present := ?,
499 p0 := *,
500 reserved := *,
501 pr_mode := *,
502 freq_par_present := ?,
503 freq_par := *,
504 dl_tfi_ass_present := ?,
505 dl_tfi_assignment := *,
506 pwr_ctrl_present := ?,
507 pwr_ctrl := *,
508 tbf_starting_time_present := ?,
509 tbf_starting_time := *,
Vadim Yanitskiy41b4dd82020-07-22 14:00:56 +0700510 spare := '0'B,
511 rel_additions := *
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200512 }
513 }
514 }
515 }
516 }
517
518 template RlcmacDlBlock tr_RLCMAC_UL_PACKET_ASS(template uint3_t usf := ?) := {
519 ctrl := {
520 mac_hdr := {
521 payload_type := (MAC_PT_RLCMAC_NO_OPT, MAC_PT_RLCMAC_OPT),
522 rrbp:= ?,
523 rrbp_valid := ?,
524 usf := usf
525 },
526 opt := *,
527 payload := {
528 msg_type := PACKET_UL_ASSIGNMENT,
529 u := {
530 ul_assignment := {
531 page_mode := ?,
532 persistence_levels_present := ?,
533 persistence_levels := *,
534 identity := ?,
535 is_egprs := ?, /* msg escape */
Pau Espin Pedrol45b664b2020-05-14 15:16:40 +0200536 gprs := *,
537 egprs := *
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200538 }
539 }
540 }
541 }
542 }
543
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +0200544 template RlcmacDlBlock tr_RLCMAC_UL_PACKET_ASS_GPRS(template uint3_t usf := ?, template PktUlAssGprs gprs := ?)
Vadim Yanitskiyc227ea92020-07-21 02:48:58 +0700545 modifies tr_RLCMAC_UL_PACKET_ASS := {
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +0200546 ctrl := {
547 payload := {
548 u := {
549 ul_assignment := {
550 is_egprs := '0'B,
Pau Espin Pedrol45b664b2020-05-14 15:16:40 +0200551 gprs := gprs,
552 egprs := omit
553 }
554 }
555 }
556 }
557 }
558
559 template RlcmacDlBlock tr_RLCMAC_UL_PACKET_ASS_EGPRS(template uint3_t usf := ?, template PktUlAssEgprs egprs := ?)
Vadim Yanitskiyc227ea92020-07-21 02:48:58 +0700560 modifies tr_RLCMAC_UL_PACKET_ASS := {
Pau Espin Pedrol45b664b2020-05-14 15:16:40 +0200561 ctrl := {
562 payload := {
563 u := {
564 ul_assignment := {
565 is_egprs := '1'B,
566 gprs := omit,
567 egprs := egprs
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +0200568 }
569 }
570 }
571 }
572 }
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200573
574 /* Receive Template for Uplink ACK/NACK */
Pau Espin Pedrol692222c2020-05-17 00:25:37 +0200575 template RlcmacDlBlock tr_RLCMAC_UL_ACK_NACK(template uint5_t ul_tfi) := {
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200576 ctrl := {
577 mac_hdr := {
578 payload_type := (MAC_PT_RLCMAC_NO_OPT, MAC_PT_RLCMAC_OPT),
579 rrbp:= ?,
580 rrbp_valid := ?,
581 usf := ?
582 },
583 opt := *,
584 payload := {
585 msg_type := PACKET_UL_ACK_NACK,
586 u := {
587 ul_ack_nack := {
588 page_mode := ?,
589 msg_excape := ?,
590 uplink_tfi := ul_tfi,
Pau Espin Pedrol692222c2020-05-17 00:25:37 +0200591 is_egprs := ?,
592 gprs := *,
593 egprs := *
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200594 }
595 }
596 }
597 }
Pau Espin Pedrol692222c2020-05-17 00:25:37 +0200598 };
599
600 template RlcmacDlBlock tr_RLCMAC_UL_ACK_NACK_GPRS(template uint5_t ul_tfi, template UlAckNackGprs gprs := tr_UlAckNackGprs(*))
601 modifies tr_RLCMAC_UL_ACK_NACK := {
602 ctrl := {
603 payload := {
604 u := {
605 ul_ack_nack := {
606 is_egprs := '0'B,
607 gprs := gprs,
608 egprs := omit
609 }
610 }
611 }
612 }
613 };
614
615 template RlcmacDlBlock tr_RLCMAC_UL_ACK_NACK_EGPRS(template uint5_t ul_tfi, template UlAckNackEgprs egprs := tr_UlAckNackEgprs(*))
616 modifies tr_RLCMAC_UL_ACK_NACK := {
617 ctrl := {
618 payload := {
619 u := {
620 ul_ack_nack := {
621 is_egprs := '1'B,
622 gprs := omit,
623 egprs := egprs
624 }
625 }
626 }
627 }
628 };
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200629
630 template RlcmacDlBlock tr_RLCMAC_PACKET_PAG_REQ(template uint3_t usf := ?) := {
631 ctrl := {
632 mac_hdr := {
633 payload_type := MAC_PT_RLCMAC_NO_OPT,
634 rrbp:= ?,
635 rrbp_valid := ?,
636 usf := usf
637 },
638 opt := *,
639 payload := {
640 msg_type := PACKET_PAGING_REQUEST,
641 u := {
642 paging := {
643 page_mode := ?,
644 persistence_levels_present := ?,
645 persistence_levels := *,
646 nln_present := ?,
647 nln := *,
Vadim Yanitskiye94164d2020-10-31 05:46:03 +0700648 repeated_pageinfo := *,
649 repeated_pageinfo_term := '0'B
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200650 }
651 }
652 }
653 }
654 }
655
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700656 /* Either GPRS or EGPRS data block with arbitrary contents */
657 template RlcmacDlBlock tr_RLCMAC_DATA := (tr_RLCMAC_DATA_GPRS, tr_RLCMAC_DATA_EGPRS);
658
Vadim Yanitskiyd4f22aa2020-05-10 13:13:46 +0700659 template RlcmacDlBlock tr_RLCMAC_DATA_GPRS(template (present) boolean rrbp_valid := ?,
660 template (present) MacRrbp rrbp := ?,
661 template (present) uint3_t usf := ?) := {
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200662 data := {
Pau Espin Pedrol5abfded2020-11-03 17:30:44 +0100663 cs := ?,
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200664 mac_hdr := {
665 mac_hdr := {
666 payload_type := MAC_PT_RLC_DATA,
Vadim Yanitskiyd4f22aa2020-05-10 13:13:46 +0700667 rrbp := rrbp,
668 rrbp_valid := rrbp_valid,
669 usf := usf
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200670 },
671 hdr_ext := ?
672 },
673 blocks := ?
674 }
675 }
676
677 template RlcmacDlBlock tr_RLCMAC_DATA_EGPRS := {
678 data_egprs := {
Pau Espin Pedrol5abfded2020-11-03 17:30:44 +0100679 mcs := ?,
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200680 mac_hdr := ?,
681 fbi := ?,
682 e := ?,
683 blocks := ?
684 }
685 }
686
687 /* Template for Uplink MAC Control Header */
688 template UlMacCtrlHeader t_RLCMAC_UlMacCtrlH(template MacPayloadType pt, template boolean retry := false) := {
689 payload_type := pt,
690 spare := '00000'B,
691 retry := retry
692 }
693
694 /* Template for Uplink Control ACK */
695 template RlcmacUlBlock ts_RLCMAC_CTRL_ACK(GprsTlli tlli, CtrlAck ack := MS_RCVD_TWO_RLC_SAME_RTI_DIFF_RBSN) := {
696 ctrl := {
697 mac_hdr := t_RLCMAC_UlMacCtrlH(MAC_PT_RLCMAC_NO_OPT),
698 payload := {
699 msg_type := PACKET_CONTROL_ACK,
700 u := {
701 ctrl_ack := {
702 tlli := tlli,
703 ctrl_ack := ack
704 }
705 }
706 }
707 }
708 }
709
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +0200710 template LlcBlockHdr t_RLCMAC_LLCBLOCK_HDR(uint16_t length_ind, boolean more, boolean e) := {
711 length_ind := length_ind,
712 more := more, /* 1 = new LLC PDU starts */
713 e := e /* 0 = another extension octet after LLC PDU, 1 = no more extension octets */
714 }
715
716 template EgprsLlcBlockHdr t_RLCMAC_LLCBLOCK_EGPRS_HDR(uint16_t length_ind, boolean e) := {
717 length_ind := length_ind,
718 e := e /* 0 = another extension octet after LLC PDU, 1 = no more extension octets */
719 }
720
721 /* Template for a LlcBlock (part of a LLC frame inside RlcMacDlDataBlock */
722 template LlcBlock t_RLCMAC_LLCBLOCK(octetstring data, template (omit) LlcBlockHdr llc_hdr := omit) := {
723 hdr := llc_hdr, /* omit = let encoder figure out the header */
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200724 payload := data
725 }
726
Pau Espin Pedrol2456dad2020-04-30 20:22:38 +0200727 /* Template for a LlcBlock (part of a LLC frame inside RlcMacEgprs?lDataBlock */
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +0200728 template EgprsLlcBlock t_RLCMAC_LLCBLOCK_EGPRS(octetstring data, template (omit) EgprsLlcBlockHdr llc_hdr := omit) := {
Pau Espin Pedrol2456dad2020-04-30 20:22:38 +0200729 /* let encoder figure out the header */
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +0200730 hdr := llc_hdr, /* omit = let encoder figure out the header */
Pau Espin Pedrol2456dad2020-04-30 20:22:38 +0200731 payload := data
732 }
733
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200734} with { encode "RAW"; variant "FIELDORDER(msb)" }