blob: 9722f43cdc38adb06cf974bdd2de2cc7052c606c [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
Pau Espin Pedrol4fbeefd2020-11-05 13:47:24 +010021 template CodingScheme cs_gprs_any := (CS_1, CS_2, CS_3, CS_4);
22 template CodingScheme mcs_egprs_any := (MCS_1, MCS_2, MCS_3, MCS_4, MCS_5,
23 MCS_6, MCS_7, MCS_8, MCS_9);
24
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +020025 /* TS 44.060 10.4.5 */
26 function f_rrbp_fn_delay(MacRrbp rrbp) return uint32_t {
27 select (rrbp) {
28 case (RRBP_Nplus13_mod_2715648) { return 13; }
29 case (RRBP_Nplus17_or_18_mod_2715648) { return 17; }
30 case (RRBP_Nplus21_or_22_mod_2715648) { return 21; }
31 case (RRBP_Nplus26_mod_2715648) { return 26; }
32 }
33 return 0;
34 }
35
Vadim Yanitskiy2742bcd2020-05-10 12:45:18 +070036 function f_rrbp_ack_fn(uint32_t current_fn, MacRrbp rrbp)
37 return uint32_t {
38 return (current_fn + f_rrbp_fn_delay(rrbp)) mod 2715648;
39 }
40
Pau Espin Pedrol27d6af52020-04-30 20:13:32 +020041 function f_rlcmac_mcs2headertype(CodingScheme mcs) return EgprsHeaderType {
42 select (mcs) {
43 case (MCS_0) { return RLCMAC_HDR_TYPE_3; }
44 case (MCS_1) { return RLCMAC_HDR_TYPE_3; }
45 case (MCS_2) { return RLCMAC_HDR_TYPE_3; }
46 case (MCS_3) { return RLCMAC_HDR_TYPE_3; }
47 case (MCS_4) { return RLCMAC_HDR_TYPE_3; }
48 case (MCS_5) { return RLCMAC_HDR_TYPE_2; }
49 case (MCS_6) { return RLCMAC_HDR_TYPE_2; }
50 case (MCS_7) { return RLCMAC_HDR_TYPE_1; }
51 case (MCS_8) { return RLCMAC_HDR_TYPE_1; }
52 case (MCS_9) { return RLCMAC_HDR_TYPE_1; }
53 }
54 return RLCMAC_HDR_TYPE_3;
55 }
56
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +020057 function f_rlcmac_cs_mcs2block_len(CodingScheme cs_mcs) return uint32_t {
58 select (cs_mcs) {
59 case (CS_1) { return 23; }
60 case (CS_2) { return 34; }
61 case (CS_3) { return 40; }
62 case (CS_4) { return 54; }
63 case (MCS_1) { return 27; }
64 case (MCS_2) { return 33; }
65 case (MCS_3) { return 42; }
66 case (MCS_4) { return 49; }
67 case (MCS_5) { return 61; }
68 case (MCS_6) { return 79; }
69 case (MCS_7) { return 119; }
70 case (MCS_8) { return 143; }
71 case (MCS_9) { return 155; }
72 }
73 return 0;
74 }
75
76 function f_rlcmac_block_len2cs_mcs(uint32_t len) return CodingScheme {
77 select (len) {
78 case (23) { return CS_1; }
79 case (34) { return CS_2; }
80 case (40) { return CS_3; }
81 case (54) { return CS_4; }
82 case (27) { return MCS_1; }
83 case (33) { return MCS_2; }
84 case (42) { return MCS_3; }
85 case (49) { return MCS_4; }
86 case (60) { return MCS_5; }
87 case (61) { return MCS_5; }
88 case (78) { return MCS_6; }
89 case (79) { return MCS_6; }
90 case (118) { return MCS_7; }
91 case (119) { return MCS_7; }
92 case (142) { return MCS_8; }
93 case (143) { return MCS_8; }
94 case (154) { return MCS_9; }
95 case (155) { return MCS_9; }
96 }
97 return CS_1;
98 }
99
Pau Espin Pedrol245bfcb2020-06-30 20:17:07 +0200100 /* Minimum CodingScheme required to fit RLCMAC block */
101 function f_rlcmac_block_len_required_cs_mcs(uint32_t len, boolean is_mcs) return CodingScheme {
102 if (is_mcs) {
103 if (len <= 27) { return MCS_1; }
104 if (len <= 33) { return MCS_2; }
105 if (len <= 42) { return MCS_3; }
106 if (len <= 49) { return MCS_4; }
107 if (len <= 60) { return MCS_5; }
108 if (len <= 61) { return MCS_5; }
109 if (len <= 79) { return MCS_6; }
110 if (len <= 119) { return MCS_7; }
111 if (len <= 143) { return MCS_8; }
112 if (len <= 155) { return MCS_9; }
113 return MCS_1; /* error! */
114 } else {
115 /* 3GPP TS 44.060 Table 10.2.1: RLC data block size, discounting padding in octet */
116 if (len <= 23) { return CS_1; }
117 if (len <= 33) { return CS_2; }
118 if (len <= 39) { return CS_3; }
119 if (len <= 53) { return CS_4; }
120 return CS_1; /* error! */
121 }
122 }
123
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +0200124 function f_rlcmac_block_ChCodingCommand2cs_mcs(ChCodingCommand chcc) return CodingScheme {
125 select (chcc) {
126 case (CH_CODING_CS1) { return CS_1; }
127 case (CH_CODING_CS2) { return CS_2; }
128 case (CH_CODING_CS3) { return CS_3; }
129 case (CH_CODING_CS4) { return CS_4; }
130 }
131 return CS_1;
132 }
133
134 function f_rlcmac_block_EgprsChCodingCommand2cs_mcs(EgprsChCodingCommand echcc) return CodingScheme {
135 select (echcc) {
136 case (CH_CODING_MCS1) { return MCS_1; }
137 case (CH_CODING_MCS2) { return MCS_2; }
138 case (CH_CODING_MCS3) { return MCS_3; }
139 case (CH_CODING_MCS4) { return MCS_4; }
140 case (CH_CODING_MCS5) { return MCS_5; }
141 case (CH_CODING_MCS6) { return MCS_6; }
142 case (CH_CODING_MCS7) { return MCS_7; }
143 case (CH_CODING_MCS8) { return MCS_8; }
144 case (CH_CODING_MCS9) { return MCS_9; }
145 /* CH_CODING_MCS5_7 */
146 /* CH_CODING_MCS6_9 */
147 }
148 return MCS_1;
149 }
150
151 /* 1 -> CS_1 / MCS_1, 2 -> CS_2 / MCS_2, etc. */
152 function f_rlcmac_block_int2cs_mcs(integer n, boolean is_mcs) return CodingScheme {
153 var CodingScheme cs_mcs;
154 if (not is_mcs) {
155 int2enum(n - 1, cs_mcs);
156 return cs_mcs;
157 } else {
158 cs_mcs := MCS_0;
159 int2enum(enum2int(cs_mcs) + n, cs_mcs);
160 return cs_mcs;
161 }
162 }
163
Pau Espin Pedrol27d6af52020-04-30 20:13:32 +0200164 /* Coding and Puncturing Scheme indicator field for Header type 1 in EGPRS TBF or EC TBF or downlink EGPRS2 TBF */
165 function f_rlcmac_cps_htype1_to_mcs(uint3_t cps) return CodingScheme {
166 var CodingSchemeArray egprs_Header_type1_coding_puncturing_scheme_to_mcs := {
167 MCS_9 /* 0x00, "(MCS-9/P1 ; MCS-9/P1)" */,
168 MCS_9 /* 0x01, "(MCS-9/P1 ; MCS-9/P2)" */,
169 MCS_9 /* 0x02, "(MCS-9/P1 ; MCS-9/P3)" */,
170 MCS_0 /* 0x03, "reserved" */,
171 MCS_9 /* 0x04, "(MCS-9/P2 ; MCS-9/P1)" */,
172 MCS_9 /* 0x05, "(MCS-9/P2 ; MCS-9/P2)" */,
173 MCS_9 /* 0x06, "(MCS-9/P2 ; MCS-9/P3)" */,
174 MCS_0 /* 0x07, "reserved" */,
175 MCS_9 /* 0x08, "(MCS-9/P3 ; MCS-9/P1)" */,
176 MCS_9 /* 0x09, "(MCS-9/P3 ; MCS-9/P2)" */,
177 MCS_9 /* 0x0A, "(MCS-9/P3 ; MCS-9/P3)" */,
178 MCS_8 /* 0x0B, "(MCS-8/P1 ; MCS-8/P1)" */,
179 MCS_8 /* 0x0C, "(MCS-8/P1 ; MCS-8/P2)" */,
180 MCS_8 /* 0x0D, "(MCS-8/P1 ; MCS-8/P3)" */,
181 MCS_8 /* 0x0E, "(MCS-8/P2 ; MCS-8/P1)" */,
182 MCS_8 /* 0x0F, "(MCS-8/P2 ; MCS-8/P2)" */,
183 MCS_8 /* 0x10, "(MCS-8/P2 ; MCS-8/P3)" */,
184 MCS_8 /* 0x11, "(MCS-8/P3 ; MCS-8/P1)" */,
185 MCS_8 /* 0x12, "(MCS-8/P3 ; MCS-8/P2)" */,
186 MCS_8 /* 0x13, "(MCS-8/P3 ; MCS-8/P3)" */,
187 MCS_7 /* 0x14, "(MCS-7/P1 ; MCS-7/P1)" */,
188 MCS_7 /* 0x15, "(MCS-7/P1 ; MCS-7/P2)" */,
189 MCS_7 /* 0x16, "(MCS-7/P1 ; MCS-7/P3)" */,
190 MCS_7 /* 0x17, "(MCS-7/P2 ; MCS-7/P1)" */,
191 MCS_7 /* 0x18, "(MCS-7/P2 ; MCS-7/P2)" */,
192 MCS_7 /* 0x19, "(MCS-7/P2 ; MCS-7/P3)" */,
193 MCS_7 /* 0x1A, "(MCS-7/P3 ; MCS-7/P1)" */,
194 MCS_7 /* 0x1B, "(MCS-7/P3 ; MCS-7/P2)" */,
195 MCS_7 /* 0x1C, "(MCS-7/P3 ; MCS-7/P3)" */,
196 MCS_0 /* 0x1D, "reserved" */,
197 MCS_0 /* 0x1E, "reserved" */,
198 MCS_0 /* 0x1F, "reserved" */
199 };
200 return egprs_Header_type1_coding_puncturing_scheme_to_mcs[cps];
201 }
202
203 /* Coding and Puncturing Scheme indicator field for Header type 2 in (EC-)EGPRS TBF or uplink EGPRS2-A TBF */
204 function f_rlcmac_cps_htype2_to_mcs(uint3_t cps) return CodingScheme {
205 var CodingSchemeArray egprs_Header_type2_coding_puncturing_scheme_to_mcs := {
206 MCS_6 /* {0x00, "MCS-6/P1"} */,
207 MCS_6 /* {0x01, "MCS-6/P2"} */,
208 MCS_6 /* {0x02, "MCS-6/P1 with 6 octet padding"} */,
209 MCS_6 /* {0x03, "MCS-6/P2 with 6 octet padding "} */,
210 MCS_5 /* {0x04, "MCS-5/P1"} */,
211 MCS_5 /* {0x05, "MCS-5/P2"} */,
212 MCS_5 /* {0x06, "MCS-6/P1 with 10 octet padding "} */,
213 MCS_5 /* {0x07, "MCS-6/P2 with 10 octet padding "} */
214 };
215 return egprs_Header_type2_coding_puncturing_scheme_to_mcs[cps];
216 }
217
218 /* Coding and Puncturing Scheme indicator field for Header type 3 */
219 function f_rlcmac_cps_htype3_to_mcs(uint3_t cps) return CodingScheme {
220 var CodingSchemeArray egprs_Header_type3_coding_puncturing_scheme_to_mcs := {
221 MCS_4 /* {0x00, "MCS-4/P1"} */,
222 MCS_4 /* {0x01, "MCS-4/P2"} */,
223 MCS_4 /* {0x02, "MCS-4/P3"} */,
224 MCS_3 /* {0x03, "MCS-3/P1"} */,
225 MCS_3 /* {0x04, "MCS-3/P2"} */,
226 MCS_3 /* {0x05, "MCS-3/P3"} */,
227 MCS_3 /* {0x06, "MCS-3/P1 with padding"} */,
228 MCS_3 /* {0x07, "MCS-3/P2 with padding"} */,
229 MCS_3 /* {0x08, "MCS-3/P3 with padding"} */,
230 MCS_2 /* {0x09, "MCS-2/P1"} */,
231 MCS_2 /* {0x0A, "MCS-2/P2"} */,
232 MCS_1 /* {0x0B, "MCS-1/P1"} */,
233 MCS_1 /* {0x0C, "MCS-1/P2"} */,
234 MCS_2 /* {0x0D, "MCS-2/P1 with padding"} */,
235 MCS_2 /* {0x0E, "MCS-2/P2 with padding"} */,
236 MCS_0 /* {0x0F, "MCS-0"} */
237 };
238 return egprs_Header_type3_coding_puncturing_scheme_to_mcs[cps];
239 }
240
241 function f_rlcmac_cps_htype_to_mcs(uint3_t cps, EgprsHeaderType htype) return CodingScheme {
242 select (htype) {
243 case (RLCMAC_HDR_TYPE_1) { return f_rlcmac_cps_htype1_to_mcs(cps); }
244 case (RLCMAC_HDR_TYPE_2) { return f_rlcmac_cps_htype2_to_mcs(cps); }
245 case (RLCMAC_HDR_TYPE_3) { return f_rlcmac_cps_htype3_to_mcs(cps); }
246 }
247 //TODO: return error here.
248 return CS_1;
249 }
250
251 function f_rlcmac_mcs_to_cps_htype1(CodingScheme mcs, uint2_t part, boolean with_padding) return uint5_t {
252 //TODO: implement similar to f_rlcmac_mcs_to_cps_htype3()
253 //TODO: return error here.
254 return 0;
255 }
256
257 function f_rlcmac_mcs_to_cps_htype2(CodingScheme mcs, uint2_t part, boolean with_padding) return uint5_t {
258 //TODO: implement similar to f_rlcmac_mcs_to_cps_htype3()
259 //TODO: return error here.
260 return 0;
261 }
262
263 function f_rlcmac_mcs_to_cps_htype3(CodingScheme mcs, uint2_t part, boolean with_padding) return uint5_t {
264 select (mcs) {
265 case (MCS_4) {
266 select (part) {
267 case (1) { return 0; /* {0x00, "MCS-4/P1"} */ }
268 case (2) { return 1; /* {0x01, "MCS-4/P2"} */ }
269 case (3) { return 2; /* {0x01, "MCS-4/P2"} */ }
270 }
271 }
272 case (MCS_3) {
273 if (not with_padding) {
274 select (part) {
275 case (1) { return 3; /* {0x03, "MCS-3/P1"} */ }
276 case (2) { return 4; /* {0x04, "MCS-3/P2"} */ }
277 case (3) { return 5; /* {0x05, "MCS-3/P3"} */ }
278 }
279 } else {
280 select (part) {
281 case (1) { return 6; /* {0x06, "MCS-3/P1 with padding"} */ }
282 case (2) { return 7; /* {0x07, "MCS-3/P2 with padding"} */ }
283 case (3) { return 8; /* {0x08, "MCS-3/P3 with padding"} */ }
284 }
285 }
286 }
287 case (MCS_2) {
288 if (not with_padding) {
289 select (part) {
290 case (1) { return 9; /* {0x09, "MCS-2/P1"} */ }
291 case (2) { return 10; /* {0x0A, "MCS-2/P2"} */ }
292 }
293 } else {
294 select (part) {
295 case (1) { return 13; /* {0x0D, "MCS-2/P1 with padding"} */ }
296 case (2) { return 14; /* {0x0E, "MCS-2/P2 with padding"} */}
297 }
298 }
299 }
300 case (MCS_1) {
301 select (part) {
302 case (1) { return 11; /* {0x0B, "MCS-1/P1"} */ }
303 case (2) { return 12; /* {0x0C, "MCS-1/P2"} */ }
304 }
305 }
306 case (MCS_0) { return 15; /* {0x0F, "MCS-0"} */ }
307 }
308 //TODO: return error here.
309 return 0;
310 }
311
312 function f_rlcmac_mcs_to_cps(CodingScheme mcs, uint2_t part, boolean with_padding := false) return uint5_t {
313
314 var EgprsHeaderType htype := f_rlcmac_mcs2headertype(mcs);
315 select (htype) {
316 case (RLCMAC_HDR_TYPE_1) { return f_rlcmac_mcs_to_cps_htype1(mcs, part, with_padding); }
317 case (RLCMAC_HDR_TYPE_2) { return f_rlcmac_mcs_to_cps_htype2(mcs, part, with_padding); }
318 case (RLCMAC_HDR_TYPE_3) { return f_rlcmac_mcs_to_cps_htype3(mcs, part, with_padding); }
319 }
320 //TODO: return error here.
321 return 0;
322 }
323
Vadim Yanitskiyf3cb4dd2020-07-21 01:52:33 +0700324 template (value) RlcmacUlBlock ts_RLC_UL_CTRL_ACK(template (value) RlcmacUlCtrlMsg ctrl,
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200325 MacPayloadType pt := MAC_PT_RLCMAC_NO_OPT,
326 boolean retry := false) := {
327 ctrl := {
328 mac_hdr := {
329 payload_type := pt,
330 spare := '00000'B,
331 retry := retry
332 },
333 payload := ctrl
334 }
335 }
336
337 /* Send Template for Downlink ACK/NACK */
338 template RlcmacUlBlock ts_RLCMAC_DL_ACK_NACK(template uint5_t tfi, AckNackDescription andesc, boolean retry := false) := {
339 ctrl := {
340 mac_hdr := {
341 payload_type := MAC_PT_RLCMAC_NO_OPT,
342 spare := '00000'B,
343 retry := retry
344 },
345 payload := {
346 msg_type := PACKET_DL_ACK_NACK,
347 u := {
348 dl_ack_nack := {
349 dl_tfi := tfi,
350 ack_nack_desc := andesc,
351 chreq_desc_presence := '0'B,
352 chreq_desc := omit,
353 ch_qual_rep := c_ChQualRep_default
354 }
355 }
356 }
357 }
358 }
359
Pau Espin Pedrol6791eb62020-05-20 18:27:10 +0200360 template RlcmacUlBlock ts_RLCMAC_DL_ACK_NACK_CHREQ(template uint5_t tfi,
361 AckNackDescription andesc,
362 boolean retry := false,
363 template ChannelReqDescription chreq_desc := c_ChReqDesc_default)
364 modifies ts_RLCMAC_DL_ACK_NACK := {
365 ctrl := {
366 payload := {
367 u := {
368 dl_ack_nack := {
369 chreq_desc_presence := '1'B,
370 chreq_desc := chreq_desc
371 }
372 }
373 }
374 }
375 }
376
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200377 /* Template for uplink Data block */
378 template RlcmacUlBlock t_RLCMAC_UL_DATA(template uint5_t tfi, template uint4_t cv, template uint7_t bsn,
379 template LlcBlocks blocks := {}, template boolean stall := false) := {
380 data := {
Pau Espin Pedrol5abfded2020-11-03 17:30:44 +0100381 cs := CS_1, /* TODO: make this available to template */
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200382 mac_hdr := {
383 payload_type := MAC_PT_RLC_DATA,
384 countdown := cv,
Pau Espin Pedrol80c1baa2020-11-10 17:45:31 +0100385 stall_ind := stall,
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200386 retry := false,
387 spare := '0'B,
388 pfi_ind := false,
389 tfi := tfi,
390 tlli_ind := false,
391 bsn := bsn,
392 e := false
393 },
394 tlli := omit,
395 pfi := omit,
396 blocks := blocks
397 }
398 }
399 template RlcmacUlBlock t_RLCMAC_UL_DATA_TLLI(template uint5_t tfi, template uint4_t cv, template uint7_t bsn,
400 template LlcBlocks blocks := {}, template boolean stall := false, template GprsTlli tlli) := {
401 data := {
Pau Espin Pedrol5abfded2020-11-03 17:30:44 +0100402 cs := CS_1, /* TODO: make this available to template */
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200403 mac_hdr := {
404 payload_type := MAC_PT_RLC_DATA,
405 countdown := cv,
Pau Espin Pedrol80c1baa2020-11-10 17:45:31 +0100406 stall_ind := stall,
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200407 retry := false,
408 spare := '0'B,
409 pfi_ind := false,
410 tfi := tfi,
411 tlli_ind := true,
412 bsn := bsn,
413 e := false
414 },
415 tlli := tlli,
416 pfi := omit,
417 blocks := blocks
418 }
419 }
420
Pau Espin Pedrol2456dad2020-04-30 20:22:38 +0200421 /* Template for uplink Data block */
422 template RlcmacUlBlock t_RLCMAC_UL_EGPRS_DATA(CodingScheme mcs,
423 template uint5_t tfi, template uint4_t cv,
Pau Espin Pedrol081b1682020-11-06 17:15:52 +0100424 template uint11_t bsn1, template uint8_t bsn2_offset := 0, template EgprsLlcBlocks blocks := {}) := {
Pau Espin Pedrol2456dad2020-04-30 20:22:38 +0200425 data_egprs := {
Pau Espin Pedrol5abfded2020-11-03 17:30:44 +0100426 mcs := mcs,
Pau Espin Pedrol2456dad2020-04-30 20:22:38 +0200427 mac_hdr := {
428 header_type := f_rlcmac_mcs2headertype(mcs),
429 tfi := tfi,
430 countdown := cv,
431 foi_si := '0'B,
432 r_ri := '0'B,
433 bsn1 := bsn1,
Pau Espin Pedrol081b1682020-11-06 17:15:52 +0100434 bsn2_offset := bsn2_offset,
Pau Espin Pedrol2456dad2020-04-30 20:22:38 +0200435 cps := f_rlcmac_mcs_to_cps(mcs, 1, false),
436 pfi_ind := false,
437 rsb := '0'B,
438 spb := '00'B
439 },
440 tlli_ind := false,
441 e := false,
442 tlli := omit,
443 pfi := omit,
444 blocks := blocks
445 }
446 }
447
Vadim Yanitskiy0a9b1482020-05-10 14:43:21 +0700448 template DlMacHeader t_RLCMAC_DlMacH(template (present) MacPayloadType pt,
449 template (present) boolean rrbp_valid,
450 template (present) MacRrbp rrbp,
451 template (present) uint3_t usf) := {
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200452 payload_type := pt,
453 rrbp := rrbp,
Vadim Yanitskiy0a9b1482020-05-10 14:43:21 +0700454 rrbp_valid := rrbp_valid,
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200455 usf := usf
456 }
457
458 template RlcmacDlBlock tr_RLCMAC_DUMMY_CTRL(template uint3_t usf := ?, template PageMode page_mode := ?) := {
459 ctrl := {
460 mac_hdr := {
461 payload_type := (MAC_PT_RLCMAC_NO_OPT, MAC_PT_RLCMAC_OPT),
462 rrbp:= ?,
463 rrbp_valid := ?,
464 usf := usf
465 },
466 opt := *,
467 payload := {
468 msg_type := PACKET_DL_DUMMY_CTRL,
469 u := {
470 dl_dummy := {
471 page_mode := page_mode,
472 persistence_levels_present := ?,
473 persistence_levels := *
474 }
475 }
476 }
477 }
478 }
479
480 template RlcmacDlBlock tr_RLCMAC_DL_PACKET_ASS(template uint3_t usf := ?) := {
481 ctrl := {
482 mac_hdr := {
483 payload_type := (MAC_PT_RLCMAC_NO_OPT, MAC_PT_RLCMAC_OPT),
484 rrbp:= ?,
485 rrbp_valid := ?,
486 usf := usf
487 },
488 opt := *,
489 payload := {
490 msg_type := PACKET_DL_ASSIGNMENT,
491 u := {
492 dl_assignment := {
493 page_mode := ?,
494 pres1 := ?,
495 persistence_levels := *,
Pau Espin Pedrol984d09f2020-05-19 18:51:58 +0200496 tfi_or_tlli := ?,
497 egprs2 := '0'B,
498 mac_mode := ?,
499 rlc_mode := ?,
500 control_ack := ?,
501 timeslot_alloc := ?,
502 pkt_ta := ?,
503 p0_present := ?,
504 p0 := *,
505 reserved := *,
506 pr_mode := *,
507 freq_par_present := ?,
508 freq_par := *,
509 dl_tfi_ass_present := ?,
510 dl_tfi_assignment := *,
511 pwr_ctrl_present := ?,
512 pwr_ctrl := *,
513 tbf_starting_time_present := ?,
514 tbf_starting_time := *,
Vadim Yanitskiy41b4dd82020-07-22 14:00:56 +0700515 spare := '0'B,
516 rel_additions := *
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200517 }
518 }
519 }
520 }
521 }
522
523 template RlcmacDlBlock tr_RLCMAC_UL_PACKET_ASS(template uint3_t usf := ?) := {
524 ctrl := {
525 mac_hdr := {
526 payload_type := (MAC_PT_RLCMAC_NO_OPT, MAC_PT_RLCMAC_OPT),
527 rrbp:= ?,
528 rrbp_valid := ?,
529 usf := usf
530 },
531 opt := *,
532 payload := {
533 msg_type := PACKET_UL_ASSIGNMENT,
534 u := {
535 ul_assignment := {
536 page_mode := ?,
537 persistence_levels_present := ?,
538 persistence_levels := *,
539 identity := ?,
540 is_egprs := ?, /* msg escape */
Pau Espin Pedrol45b664b2020-05-14 15:16:40 +0200541 gprs := *,
542 egprs := *
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200543 }
544 }
545 }
546 }
547 }
548
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +0200549 template RlcmacDlBlock tr_RLCMAC_UL_PACKET_ASS_GPRS(template uint3_t usf := ?, template PktUlAssGprs gprs := ?)
Vadim Yanitskiyc227ea92020-07-21 02:48:58 +0700550 modifies tr_RLCMAC_UL_PACKET_ASS := {
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +0200551 ctrl := {
552 payload := {
553 u := {
554 ul_assignment := {
555 is_egprs := '0'B,
Pau Espin Pedrol45b664b2020-05-14 15:16:40 +0200556 gprs := gprs,
557 egprs := omit
558 }
559 }
560 }
561 }
562 }
563
564 template RlcmacDlBlock tr_RLCMAC_UL_PACKET_ASS_EGPRS(template uint3_t usf := ?, template PktUlAssEgprs egprs := ?)
Vadim Yanitskiyc227ea92020-07-21 02:48:58 +0700565 modifies tr_RLCMAC_UL_PACKET_ASS := {
Pau Espin Pedrol45b664b2020-05-14 15:16:40 +0200566 ctrl := {
567 payload := {
568 u := {
569 ul_assignment := {
570 is_egprs := '1'B,
571 gprs := omit,
572 egprs := egprs
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +0200573 }
574 }
575 }
576 }
577 }
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200578
579 /* Receive Template for Uplink ACK/NACK */
Pau Espin Pedrol692222c2020-05-17 00:25:37 +0200580 template RlcmacDlBlock tr_RLCMAC_UL_ACK_NACK(template uint5_t ul_tfi) := {
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200581 ctrl := {
582 mac_hdr := {
583 payload_type := (MAC_PT_RLCMAC_NO_OPT, MAC_PT_RLCMAC_OPT),
584 rrbp:= ?,
585 rrbp_valid := ?,
586 usf := ?
587 },
588 opt := *,
589 payload := {
590 msg_type := PACKET_UL_ACK_NACK,
591 u := {
592 ul_ack_nack := {
593 page_mode := ?,
594 msg_excape := ?,
595 uplink_tfi := ul_tfi,
Pau Espin Pedrol692222c2020-05-17 00:25:37 +0200596 is_egprs := ?,
597 gprs := *,
598 egprs := *
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200599 }
600 }
601 }
602 }
Pau Espin Pedrol692222c2020-05-17 00:25:37 +0200603 };
604
605 template RlcmacDlBlock tr_RLCMAC_UL_ACK_NACK_GPRS(template uint5_t ul_tfi, template UlAckNackGprs gprs := tr_UlAckNackGprs(*))
606 modifies tr_RLCMAC_UL_ACK_NACK := {
607 ctrl := {
608 payload := {
609 u := {
610 ul_ack_nack := {
611 is_egprs := '0'B,
612 gprs := gprs,
613 egprs := omit
614 }
615 }
616 }
617 }
618 };
619
620 template RlcmacDlBlock tr_RLCMAC_UL_ACK_NACK_EGPRS(template uint5_t ul_tfi, template UlAckNackEgprs egprs := tr_UlAckNackEgprs(*))
621 modifies tr_RLCMAC_UL_ACK_NACK := {
622 ctrl := {
623 payload := {
624 u := {
625 ul_ack_nack := {
626 is_egprs := '1'B,
627 gprs := omit,
628 egprs := egprs
629 }
630 }
631 }
632 }
633 };
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200634
635 template RlcmacDlBlock tr_RLCMAC_PACKET_PAG_REQ(template uint3_t usf := ?) := {
636 ctrl := {
637 mac_hdr := {
638 payload_type := MAC_PT_RLCMAC_NO_OPT,
639 rrbp:= ?,
640 rrbp_valid := ?,
641 usf := usf
642 },
643 opt := *,
644 payload := {
645 msg_type := PACKET_PAGING_REQUEST,
646 u := {
647 paging := {
648 page_mode := ?,
649 persistence_levels_present := ?,
650 persistence_levels := *,
651 nln_present := ?,
652 nln := *,
Vadim Yanitskiye94164d2020-10-31 05:46:03 +0700653 repeated_pageinfo := *,
654 repeated_pageinfo_term := '0'B
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200655 }
656 }
657 }
658 }
659 }
660
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700661 /* Either GPRS or EGPRS data block with arbitrary contents */
662 template RlcmacDlBlock tr_RLCMAC_DATA := (tr_RLCMAC_DATA_GPRS, tr_RLCMAC_DATA_EGPRS);
663
Vadim Yanitskiyd4f22aa2020-05-10 13:13:46 +0700664 template RlcmacDlBlock tr_RLCMAC_DATA_GPRS(template (present) boolean rrbp_valid := ?,
665 template (present) MacRrbp rrbp := ?,
666 template (present) uint3_t usf := ?) := {
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200667 data := {
Pau Espin Pedrol5abfded2020-11-03 17:30:44 +0100668 cs := ?,
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200669 mac_hdr := {
670 mac_hdr := {
671 payload_type := MAC_PT_RLC_DATA,
Vadim Yanitskiyd4f22aa2020-05-10 13:13:46 +0700672 rrbp := rrbp,
673 rrbp_valid := rrbp_valid,
674 usf := usf
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200675 },
676 hdr_ext := ?
677 },
678 blocks := ?
679 }
680 }
681
682 template RlcmacDlBlock tr_RLCMAC_DATA_EGPRS := {
683 data_egprs := {
Pau Espin Pedrol5abfded2020-11-03 17:30:44 +0100684 mcs := ?,
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200685 mac_hdr := ?,
686 fbi := ?,
687 e := ?,
688 blocks := ?
689 }
690 }
691
692 /* Template for Uplink MAC Control Header */
693 template UlMacCtrlHeader t_RLCMAC_UlMacCtrlH(template MacPayloadType pt, template boolean retry := false) := {
694 payload_type := pt,
695 spare := '00000'B,
696 retry := retry
697 }
698
699 /* Template for Uplink Control ACK */
700 template RlcmacUlBlock ts_RLCMAC_CTRL_ACK(GprsTlli tlli, CtrlAck ack := MS_RCVD_TWO_RLC_SAME_RTI_DIFF_RBSN) := {
701 ctrl := {
702 mac_hdr := t_RLCMAC_UlMacCtrlH(MAC_PT_RLCMAC_NO_OPT),
703 payload := {
704 msg_type := PACKET_CONTROL_ACK,
705 u := {
706 ctrl_ack := {
707 tlli := tlli,
708 ctrl_ack := ack
709 }
710 }
711 }
712 }
713 }
714
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +0200715 template LlcBlockHdr t_RLCMAC_LLCBLOCK_HDR(uint16_t length_ind, boolean more, boolean e) := {
716 length_ind := length_ind,
717 more := more, /* 1 = new LLC PDU starts */
718 e := e /* 0 = another extension octet after LLC PDU, 1 = no more extension octets */
719 }
720
721 template EgprsLlcBlockHdr t_RLCMAC_LLCBLOCK_EGPRS_HDR(uint16_t length_ind, boolean e) := {
722 length_ind := length_ind,
723 e := e /* 0 = another extension octet after LLC PDU, 1 = no more extension octets */
724 }
725
726 /* Template for a LlcBlock (part of a LLC frame inside RlcMacDlDataBlock */
727 template LlcBlock t_RLCMAC_LLCBLOCK(octetstring data, template (omit) LlcBlockHdr llc_hdr := omit) := {
728 hdr := llc_hdr, /* omit = let encoder figure out the header */
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200729 payload := data
730 }
731
Pau Espin Pedrol2456dad2020-04-30 20:22:38 +0200732 /* Template for a LlcBlock (part of a LLC frame inside RlcMacEgprs?lDataBlock */
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +0200733 template EgprsLlcBlock t_RLCMAC_LLCBLOCK_EGPRS(octetstring data, template (omit) EgprsLlcBlockHdr llc_hdr := omit) := {
Pau Espin Pedrol2456dad2020-04-30 20:22:38 +0200734 /* let encoder figure out the header */
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +0200735 hdr := llc_hdr, /* omit = let encoder figure out the header */
Pau Espin Pedrol2456dad2020-04-30 20:22:38 +0200736 payload := data
737 }
738
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200739} with { encode "RAW"; variant "FIELDORDER(msb)" }