blob: 5e27341358179cba5fcf280196f1097e179a71b6 [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 Pedrolcb00c522020-11-06 19:52:05 +010041 function f_rlcmac_cs_mcs_is_mcs(CodingScheme cs_mcs) return boolean {
42 if (cs_mcs >= MCS_0) {
43 return true;
44 }
45 return false;
46 }
47
Pau Espin Pedrol27d6af52020-04-30 20:13:32 +020048 function f_rlcmac_mcs2headertype(CodingScheme mcs) return EgprsHeaderType {
49 select (mcs) {
50 case (MCS_0) { return RLCMAC_HDR_TYPE_3; }
51 case (MCS_1) { return RLCMAC_HDR_TYPE_3; }
52 case (MCS_2) { return RLCMAC_HDR_TYPE_3; }
53 case (MCS_3) { return RLCMAC_HDR_TYPE_3; }
54 case (MCS_4) { return RLCMAC_HDR_TYPE_3; }
55 case (MCS_5) { return RLCMAC_HDR_TYPE_2; }
56 case (MCS_6) { return RLCMAC_HDR_TYPE_2; }
57 case (MCS_7) { return RLCMAC_HDR_TYPE_1; }
58 case (MCS_8) { return RLCMAC_HDR_TYPE_1; }
59 case (MCS_9) { return RLCMAC_HDR_TYPE_1; }
60 }
61 return RLCMAC_HDR_TYPE_3;
62 }
63
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +020064 function f_rlcmac_cs_mcs2block_len(CodingScheme cs_mcs) return uint32_t {
65 select (cs_mcs) {
66 case (CS_1) { return 23; }
67 case (CS_2) { return 34; }
68 case (CS_3) { return 40; }
69 case (CS_4) { return 54; }
70 case (MCS_1) { return 27; }
71 case (MCS_2) { return 33; }
72 case (MCS_3) { return 42; }
73 case (MCS_4) { return 49; }
74 case (MCS_5) { return 61; }
75 case (MCS_6) { return 79; }
76 case (MCS_7) { return 119; }
77 case (MCS_8) { return 143; }
78 case (MCS_9) { return 155; }
79 }
80 return 0;
81 }
82
83 function f_rlcmac_block_len2cs_mcs(uint32_t len) return CodingScheme {
84 select (len) {
85 case (23) { return CS_1; }
86 case (34) { return CS_2; }
87 case (40) { return CS_3; }
88 case (54) { return CS_4; }
89 case (27) { return MCS_1; }
90 case (33) { return MCS_2; }
91 case (42) { return MCS_3; }
92 case (49) { return MCS_4; }
93 case (60) { return MCS_5; }
94 case (61) { return MCS_5; }
95 case (78) { return MCS_6; }
96 case (79) { return MCS_6; }
97 case (118) { return MCS_7; }
98 case (119) { return MCS_7; }
99 case (142) { return MCS_8; }
100 case (143) { return MCS_8; }
101 case (154) { return MCS_9; }
102 case (155) { return MCS_9; }
103 }
104 return CS_1;
105 }
106
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +0100107 function f_rlcmac_cs_mcs2block_len_no_spare_bits(CodingScheme cs_mcs) return uint32_t {
108 select (cs_mcs) {
109 /* 3GPP TS 44.060 Table 10.2.1: RLC data block size, discounting padding in octet */
110 case (CS_1) { return 23; }
111 case (CS_2) { return 33; }
112 case (CS_3) { return 39; }
113 case (CS_4) { return 53; }
114 case (MCS_1) { return 27; }
115 case (MCS_2) { return 33; }
116 case (MCS_3) { return 42; }
117 case (MCS_4) { return 49; }
118 case (MCS_5) { return 61; }
119 case (MCS_6) { return 79; }
120 case (MCS_7) { return 119; }
121 case (MCS_8) { return 143; }
122 case (MCS_9) { return 155; }
123 }
124 return 0;
125 }
126
127 /* Minimum CodingScheme required to fit RLCMAC block. Spare bits not counted. */
Pau Espin Pedrol245bfcb2020-06-30 20:17:07 +0200128 function f_rlcmac_block_len_required_cs_mcs(uint32_t len, boolean is_mcs) return CodingScheme {
129 if (is_mcs) {
130 if (len <= 27) { return MCS_1; }
131 if (len <= 33) { return MCS_2; }
132 if (len <= 42) { return MCS_3; }
133 if (len <= 49) { return MCS_4; }
134 if (len <= 60) { return MCS_5; }
135 if (len <= 61) { return MCS_5; }
136 if (len <= 79) { return MCS_6; }
137 if (len <= 119) { return MCS_7; }
138 if (len <= 143) { return MCS_8; }
139 if (len <= 155) { return MCS_9; }
140 return MCS_1; /* error! */
141 } else {
142 /* 3GPP TS 44.060 Table 10.2.1: RLC data block size, discounting padding in octet */
143 if (len <= 23) { return CS_1; }
144 if (len <= 33) { return CS_2; }
145 if (len <= 39) { return CS_3; }
146 if (len <= 53) { return CS_4; }
147 return CS_1; /* error! */
148 }
149 }
150
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +0200151 function f_rlcmac_block_ChCodingCommand2cs_mcs(ChCodingCommand chcc) return CodingScheme {
152 select (chcc) {
153 case (CH_CODING_CS1) { return CS_1; }
154 case (CH_CODING_CS2) { return CS_2; }
155 case (CH_CODING_CS3) { return CS_3; }
156 case (CH_CODING_CS4) { return CS_4; }
157 }
158 return CS_1;
159 }
160
161 function f_rlcmac_block_EgprsChCodingCommand2cs_mcs(EgprsChCodingCommand echcc) return CodingScheme {
162 select (echcc) {
163 case (CH_CODING_MCS1) { return MCS_1; }
164 case (CH_CODING_MCS2) { return MCS_2; }
165 case (CH_CODING_MCS3) { return MCS_3; }
166 case (CH_CODING_MCS4) { return MCS_4; }
167 case (CH_CODING_MCS5) { return MCS_5; }
168 case (CH_CODING_MCS6) { return MCS_6; }
169 case (CH_CODING_MCS7) { return MCS_7; }
170 case (CH_CODING_MCS8) { return MCS_8; }
171 case (CH_CODING_MCS9) { return MCS_9; }
172 /* CH_CODING_MCS5_7 */
173 /* CH_CODING_MCS6_9 */
174 }
175 return MCS_1;
176 }
177
178 /* 1 -> CS_1 / MCS_1, 2 -> CS_2 / MCS_2, etc. */
179 function f_rlcmac_block_int2cs_mcs(integer n, boolean is_mcs) return CodingScheme {
180 var CodingScheme cs_mcs;
181 if (not is_mcs) {
182 int2enum(n - 1, cs_mcs);
183 return cs_mcs;
184 } else {
185 cs_mcs := MCS_0;
186 int2enum(enum2int(cs_mcs) + n, cs_mcs);
187 return cs_mcs;
188 }
189 }
190
Pau Espin Pedrol27d6af52020-04-30 20:13:32 +0200191 /* Coding and Puncturing Scheme indicator field for Header type 1 in EGPRS TBF or EC TBF or downlink EGPRS2 TBF */
192 function f_rlcmac_cps_htype1_to_mcs(uint3_t cps) return CodingScheme {
193 var CodingSchemeArray egprs_Header_type1_coding_puncturing_scheme_to_mcs := {
194 MCS_9 /* 0x00, "(MCS-9/P1 ; MCS-9/P1)" */,
195 MCS_9 /* 0x01, "(MCS-9/P1 ; MCS-9/P2)" */,
196 MCS_9 /* 0x02, "(MCS-9/P1 ; MCS-9/P3)" */,
197 MCS_0 /* 0x03, "reserved" */,
198 MCS_9 /* 0x04, "(MCS-9/P2 ; MCS-9/P1)" */,
199 MCS_9 /* 0x05, "(MCS-9/P2 ; MCS-9/P2)" */,
200 MCS_9 /* 0x06, "(MCS-9/P2 ; MCS-9/P3)" */,
201 MCS_0 /* 0x07, "reserved" */,
202 MCS_9 /* 0x08, "(MCS-9/P3 ; MCS-9/P1)" */,
203 MCS_9 /* 0x09, "(MCS-9/P3 ; MCS-9/P2)" */,
204 MCS_9 /* 0x0A, "(MCS-9/P3 ; MCS-9/P3)" */,
205 MCS_8 /* 0x0B, "(MCS-8/P1 ; MCS-8/P1)" */,
206 MCS_8 /* 0x0C, "(MCS-8/P1 ; MCS-8/P2)" */,
207 MCS_8 /* 0x0D, "(MCS-8/P1 ; MCS-8/P3)" */,
208 MCS_8 /* 0x0E, "(MCS-8/P2 ; MCS-8/P1)" */,
209 MCS_8 /* 0x0F, "(MCS-8/P2 ; MCS-8/P2)" */,
210 MCS_8 /* 0x10, "(MCS-8/P2 ; MCS-8/P3)" */,
211 MCS_8 /* 0x11, "(MCS-8/P3 ; MCS-8/P1)" */,
212 MCS_8 /* 0x12, "(MCS-8/P3 ; MCS-8/P2)" */,
213 MCS_8 /* 0x13, "(MCS-8/P3 ; MCS-8/P3)" */,
214 MCS_7 /* 0x14, "(MCS-7/P1 ; MCS-7/P1)" */,
215 MCS_7 /* 0x15, "(MCS-7/P1 ; MCS-7/P2)" */,
216 MCS_7 /* 0x16, "(MCS-7/P1 ; MCS-7/P3)" */,
217 MCS_7 /* 0x17, "(MCS-7/P2 ; MCS-7/P1)" */,
218 MCS_7 /* 0x18, "(MCS-7/P2 ; MCS-7/P2)" */,
219 MCS_7 /* 0x19, "(MCS-7/P2 ; MCS-7/P3)" */,
220 MCS_7 /* 0x1A, "(MCS-7/P3 ; MCS-7/P1)" */,
221 MCS_7 /* 0x1B, "(MCS-7/P3 ; MCS-7/P2)" */,
222 MCS_7 /* 0x1C, "(MCS-7/P3 ; MCS-7/P3)" */,
223 MCS_0 /* 0x1D, "reserved" */,
224 MCS_0 /* 0x1E, "reserved" */,
225 MCS_0 /* 0x1F, "reserved" */
226 };
227 return egprs_Header_type1_coding_puncturing_scheme_to_mcs[cps];
228 }
229
230 /* Coding and Puncturing Scheme indicator field for Header type 2 in (EC-)EGPRS TBF or uplink EGPRS2-A TBF */
231 function f_rlcmac_cps_htype2_to_mcs(uint3_t cps) return CodingScheme {
232 var CodingSchemeArray egprs_Header_type2_coding_puncturing_scheme_to_mcs := {
233 MCS_6 /* {0x00, "MCS-6/P1"} */,
234 MCS_6 /* {0x01, "MCS-6/P2"} */,
235 MCS_6 /* {0x02, "MCS-6/P1 with 6 octet padding"} */,
236 MCS_6 /* {0x03, "MCS-6/P2 with 6 octet padding "} */,
237 MCS_5 /* {0x04, "MCS-5/P1"} */,
238 MCS_5 /* {0x05, "MCS-5/P2"} */,
239 MCS_5 /* {0x06, "MCS-6/P1 with 10 octet padding "} */,
240 MCS_5 /* {0x07, "MCS-6/P2 with 10 octet padding "} */
241 };
242 return egprs_Header_type2_coding_puncturing_scheme_to_mcs[cps];
243 }
244
245 /* Coding and Puncturing Scheme indicator field for Header type 3 */
246 function f_rlcmac_cps_htype3_to_mcs(uint3_t cps) return CodingScheme {
247 var CodingSchemeArray egprs_Header_type3_coding_puncturing_scheme_to_mcs := {
248 MCS_4 /* {0x00, "MCS-4/P1"} */,
249 MCS_4 /* {0x01, "MCS-4/P2"} */,
250 MCS_4 /* {0x02, "MCS-4/P3"} */,
251 MCS_3 /* {0x03, "MCS-3/P1"} */,
252 MCS_3 /* {0x04, "MCS-3/P2"} */,
253 MCS_3 /* {0x05, "MCS-3/P3"} */,
254 MCS_3 /* {0x06, "MCS-3/P1 with padding"} */,
255 MCS_3 /* {0x07, "MCS-3/P2 with padding"} */,
256 MCS_3 /* {0x08, "MCS-3/P3 with padding"} */,
257 MCS_2 /* {0x09, "MCS-2/P1"} */,
258 MCS_2 /* {0x0A, "MCS-2/P2"} */,
259 MCS_1 /* {0x0B, "MCS-1/P1"} */,
260 MCS_1 /* {0x0C, "MCS-1/P2"} */,
261 MCS_2 /* {0x0D, "MCS-2/P1 with padding"} */,
262 MCS_2 /* {0x0E, "MCS-2/P2 with padding"} */,
263 MCS_0 /* {0x0F, "MCS-0"} */
264 };
265 return egprs_Header_type3_coding_puncturing_scheme_to_mcs[cps];
266 }
267
268 function f_rlcmac_cps_htype_to_mcs(uint3_t cps, EgprsHeaderType htype) return CodingScheme {
269 select (htype) {
270 case (RLCMAC_HDR_TYPE_1) { return f_rlcmac_cps_htype1_to_mcs(cps); }
271 case (RLCMAC_HDR_TYPE_2) { return f_rlcmac_cps_htype2_to_mcs(cps); }
272 case (RLCMAC_HDR_TYPE_3) { return f_rlcmac_cps_htype3_to_mcs(cps); }
273 }
274 //TODO: return error here.
275 return CS_1;
276 }
277
278 function f_rlcmac_mcs_to_cps_htype1(CodingScheme mcs, uint2_t part, boolean with_padding) return uint5_t {
279 //TODO: implement similar to f_rlcmac_mcs_to_cps_htype3()
280 //TODO: return error here.
281 return 0;
282 }
283
284 function f_rlcmac_mcs_to_cps_htype2(CodingScheme mcs, uint2_t part, boolean with_padding) return uint5_t {
285 //TODO: implement similar to f_rlcmac_mcs_to_cps_htype3()
286 //TODO: return error here.
287 return 0;
288 }
289
290 function f_rlcmac_mcs_to_cps_htype3(CodingScheme mcs, uint2_t part, boolean with_padding) return uint5_t {
291 select (mcs) {
292 case (MCS_4) {
293 select (part) {
294 case (1) { return 0; /* {0x00, "MCS-4/P1"} */ }
295 case (2) { return 1; /* {0x01, "MCS-4/P2"} */ }
296 case (3) { return 2; /* {0x01, "MCS-4/P2"} */ }
297 }
298 }
299 case (MCS_3) {
300 if (not with_padding) {
301 select (part) {
302 case (1) { return 3; /* {0x03, "MCS-3/P1"} */ }
303 case (2) { return 4; /* {0x04, "MCS-3/P2"} */ }
304 case (3) { return 5; /* {0x05, "MCS-3/P3"} */ }
305 }
306 } else {
307 select (part) {
308 case (1) { return 6; /* {0x06, "MCS-3/P1 with padding"} */ }
309 case (2) { return 7; /* {0x07, "MCS-3/P2 with padding"} */ }
310 case (3) { return 8; /* {0x08, "MCS-3/P3 with padding"} */ }
311 }
312 }
313 }
314 case (MCS_2) {
315 if (not with_padding) {
316 select (part) {
317 case (1) { return 9; /* {0x09, "MCS-2/P1"} */ }
318 case (2) { return 10; /* {0x0A, "MCS-2/P2"} */ }
319 }
320 } else {
321 select (part) {
322 case (1) { return 13; /* {0x0D, "MCS-2/P1 with padding"} */ }
323 case (2) { return 14; /* {0x0E, "MCS-2/P2 with padding"} */}
324 }
325 }
326 }
327 case (MCS_1) {
328 select (part) {
329 case (1) { return 11; /* {0x0B, "MCS-1/P1"} */ }
330 case (2) { return 12; /* {0x0C, "MCS-1/P2"} */ }
331 }
332 }
333 case (MCS_0) { return 15; /* {0x0F, "MCS-0"} */ }
334 }
335 //TODO: return error here.
336 return 0;
337 }
338
339 function f_rlcmac_mcs_to_cps(CodingScheme mcs, uint2_t part, boolean with_padding := false) return uint5_t {
340
341 var EgprsHeaderType htype := f_rlcmac_mcs2headertype(mcs);
342 select (htype) {
343 case (RLCMAC_HDR_TYPE_1) { return f_rlcmac_mcs_to_cps_htype1(mcs, part, with_padding); }
344 case (RLCMAC_HDR_TYPE_2) { return f_rlcmac_mcs_to_cps_htype2(mcs, part, with_padding); }
345 case (RLCMAC_HDR_TYPE_3) { return f_rlcmac_mcs_to_cps_htype3(mcs, part, with_padding); }
346 }
347 //TODO: return error here.
348 return 0;
349 }
350
Vadim Yanitskiyf3cb4dd2020-07-21 01:52:33 +0700351 template (value) RlcmacUlBlock ts_RLC_UL_CTRL_ACK(template (value) RlcmacUlCtrlMsg ctrl,
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200352 MacPayloadType pt := MAC_PT_RLCMAC_NO_OPT,
353 boolean retry := false) := {
354 ctrl := {
355 mac_hdr := {
356 payload_type := pt,
357 spare := '00000'B,
358 retry := retry
359 },
360 payload := ctrl
361 }
362 }
363
Pau Espin Pedrole8db6732020-11-12 21:06:41 +0100364 private function f_presence_bit_chreq_desc(template (omit) ChannelReqDescription chreq_desc) return BIT1 {
365 if (istemplatekind(chreq_desc, "omit")) {
366 return '0'B;
367 }
368 return '1'B;
369 }
370
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200371 /* Send Template for Downlink ACK/NACK */
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +0100372 template (value) RlcmacUlBlock ts_RLCMAC_DL_ACK_NACK(template (value) uint5_t tfi, AckNackDescription andesc, boolean retry := false,
Pau Espin Pedrole8db6732020-11-12 21:06:41 +0100373 template (omit) ChannelReqDescription chreq_desc := omit) := {
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200374 ctrl := {
375 mac_hdr := {
376 payload_type := MAC_PT_RLCMAC_NO_OPT,
377 spare := '00000'B,
378 retry := retry
379 },
380 payload := {
381 msg_type := PACKET_DL_ACK_NACK,
382 u := {
383 dl_ack_nack := {
384 dl_tfi := tfi,
385 ack_nack_desc := andesc,
Pau Espin Pedrole8db6732020-11-12 21:06:41 +0100386 chreq_desc_presence := f_presence_bit_chreq_desc(chreq_desc),
387 chreq_desc := chreq_desc,
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200388 ch_qual_rep := c_ChQualRep_default
389 }
390 }
391 }
392 }
393 }
394
Pau Espin Pedrolafdd28d2020-11-12 21:02:18 +0100395 /* Send Template for Egprs Downlink ACK/NACK */
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +0100396 template (value) RlcmacUlBlock ts_RLCMAC_DL_ACK_NACK_EGPRS(template (value) uint5_t tfi,
397 EgprsAckNackDescription andesc,
398 boolean retry := false,
399 template (omit) ChannelReqDescription chreq_desc := omit) := {
Pau Espin Pedrolafdd28d2020-11-12 21:02:18 +0100400 ctrl := {
401 mac_hdr := {
402 payload_type := MAC_PT_RLCMAC_NO_OPT,
403 spare := '00000'B,
404 retry := retry
405 },
406 payload := {
407 msg_type := PACKET_EGPRS_DL_ACK_NACK,
408 u := {
409 dl_ack_nack_egprs := {
410 dl_tfi := tfi,
411 ms_oom := '0'B,
412 egprs_ch_qual_rep_presence := '0'B,
413 egprs_ch_qual_rep := omit,
Pau Espin Pedrole8db6732020-11-12 21:06:41 +0100414 chreq_desc_presence := f_presence_bit_chreq_desc(chreq_desc),
415 chreq_desc := chreq_desc,
Pau Espin Pedrolafdd28d2020-11-12 21:02:18 +0100416 pfi_presence := '0'B,
417 pfi := omit,
418 epdan_presence := '0'B,
419 ack_nack_desc_ie := ts_EgprsAckNackDescriptionIE(andesc)
420 }
421 }
422 }
423 }
424 }
425
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200426 /* Template for uplink Data block */
Pau Espin Pedroldbc71272021-02-05 12:37:42 +0100427 template (value) RlcmacUlBlock t_RLCMAC_UL_DATA(template (value) CodingScheme cs,
428 template (value) uint5_t tfi,
429 template (value) uint4_t cv,
430 template (value) uint7_t bsn,
431 template (value) LlcBlocks blocks := {},
432 template (value) boolean stall := false) := {
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200433 data := {
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +0100434 cs := cs,
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200435 mac_hdr := {
436 payload_type := MAC_PT_RLC_DATA,
437 countdown := cv,
Pau Espin Pedrol80c1baa2020-11-10 17:45:31 +0100438 stall_ind := stall,
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200439 retry := false,
440 spare := '0'B,
441 pfi_ind := false,
442 tfi := tfi,
443 tlli_ind := false,
444 bsn := bsn,
445 e := false
446 },
447 tlli := omit,
448 pfi := omit,
449 blocks := blocks
450 }
451 }
Pau Espin Pedroldbc71272021-02-05 12:37:42 +0100452 template (value) RlcmacUlBlock t_RLCMAC_UL_DATA_TLLI(template (value) CodingScheme cs,
453 template (value) uint5_t tfi,
454 template (value) uint4_t cv,
455 template (value) uint7_t bsn,
456 template (value) LlcBlocks blocks := {},
457 template (value) boolean stall := false,
458 template (value) GprsTlli tlli) := {
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200459 data := {
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +0100460 cs := cs,
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200461 mac_hdr := {
462 payload_type := MAC_PT_RLC_DATA,
463 countdown := cv,
Pau Espin Pedrol80c1baa2020-11-10 17:45:31 +0100464 stall_ind := stall,
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200465 retry := false,
466 spare := '0'B,
467 pfi_ind := false,
468 tfi := tfi,
469 tlli_ind := true,
470 bsn := bsn,
471 e := false
472 },
473 tlli := tlli,
474 pfi := omit,
475 blocks := blocks
476 }
477 }
478
Pau Espin Pedrol2456dad2020-04-30 20:22:38 +0200479 /* Template for uplink Data block */
Pau Espin Pedroldbc71272021-02-05 12:37:42 +0100480 template (value) RlcmacUlBlock t_RLCMAC_UL_EGPRS_DATA(CodingScheme mcs,
481 template (value) uint5_t tfi,
482 template (value) uint4_t cv,
483 template (value) uint11_t bsn1,
484 template (value) uint8_t bsn2_offset := 0,
485 template (value) EgprsLlcBlocks blocks := {}) := {
Pau Espin Pedrol2456dad2020-04-30 20:22:38 +0200486 data_egprs := {
Pau Espin Pedrol5abfded2020-11-03 17:30:44 +0100487 mcs := mcs,
Pau Espin Pedrol2456dad2020-04-30 20:22:38 +0200488 mac_hdr := {
489 header_type := f_rlcmac_mcs2headertype(mcs),
490 tfi := tfi,
491 countdown := cv,
492 foi_si := '0'B,
493 r_ri := '0'B,
494 bsn1 := bsn1,
Pau Espin Pedrol081b1682020-11-06 17:15:52 +0100495 bsn2_offset := bsn2_offset,
Pau Espin Pedrol2456dad2020-04-30 20:22:38 +0200496 cps := f_rlcmac_mcs_to_cps(mcs, 1, false),
497 pfi_ind := false,
498 rsb := '0'B,
499 spb := '00'B
500 },
501 tlli_ind := false,
502 e := false,
503 tlli := omit,
504 pfi := omit,
505 blocks := blocks
506 }
507 }
508
Vadim Yanitskiy79545102022-12-21 05:46:48 +0700509 template (value) DlMacHeader
510 ts_RLCMAC_DlMacH(template (value) MacPayloadType pt := MAC_PT_RLCMAC_NO_OPT,
511 template (value) boolean rrbp_valid := false,
512 template (value) MacRrbp rrbp := RRBP_Nplus13_mod_2715648,
513 template (value) uint3_t usf := 7) := {
514 payload_type := pt,
515 rrbp := rrbp,
516 rrbp_valid := rrbp_valid,
517 usf := usf
518 }
519 template DlMacHeader
520 t_RLCMAC_DlMacH(template (present) MacPayloadType pt,
521 template (present) boolean rrbp_valid,
522 template (present) MacRrbp rrbp,
523 template (present) uint3_t usf) := {
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200524 payload_type := pt,
525 rrbp := rrbp,
Vadim Yanitskiy0a9b1482020-05-10 14:43:21 +0700526 rrbp_valid := rrbp_valid,
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200527 usf := usf
528 }
529
Pau Espin Pedrol92c19082021-01-08 17:12:02 +0100530 template RlcmacDlBlock tr_RLCMAC_DL_CTRL(template uint3_t usf := ?, template RlcmacDlCtrlMsg dl_ctrl := ?) := {
531 ctrl := {
532 mac_hdr := {
533 payload_type := (MAC_PT_RLCMAC_NO_OPT, MAC_PT_RLCMAC_OPT),
534 rrbp:= ?,
535 rrbp_valid := ?,
536 usf := usf
537 },
538 opt := *,
539 payload := dl_ctrl
540 }
541 }
542
Vadim Yanitskiy79545102022-12-21 05:46:48 +0700543 template (value) RlcmacDlBlock
544 ts_RLCMAC_DL_DUMMY_CTRL(template (value) DlMacHeader mac_hdr := ts_RLCMAC_DlMacH,
545 template (value) PageMode page_mode := PAGE_MODE_NORMAL) := {
546 ctrl := {
547 mac_hdr := mac_hdr,
548 opt := omit,
549 payload := {
550 msg_type := PACKET_DL_DUMMY_CTRL,
551 u := {
552 dl_dummy := {
553 page_mode := page_mode,
554 persistence_levels_present := '0'B,
555 persistence_levels := omit
556 }
557 }
558 }
559 }
560 }
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +0700561 template RlcmacDlBlock tr_RLCMAC_DL_DUMMY_CTRL(template uint3_t usf := ?, template PageMode page_mode := ?) := {
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200562 ctrl := {
563 mac_hdr := {
564 payload_type := (MAC_PT_RLCMAC_NO_OPT, MAC_PT_RLCMAC_OPT),
565 rrbp:= ?,
566 rrbp_valid := ?,
567 usf := usf
568 },
569 opt := *,
570 payload := {
571 msg_type := PACKET_DL_DUMMY_CTRL,
572 u := {
573 dl_dummy := {
574 page_mode := page_mode,
575 persistence_levels_present := ?,
576 persistence_levels := *
577 }
578 }
579 }
580 }
581 }
582
583 template RlcmacDlBlock tr_RLCMAC_DL_PACKET_ASS(template uint3_t usf := ?) := {
584 ctrl := {
585 mac_hdr := {
586 payload_type := (MAC_PT_RLCMAC_NO_OPT, MAC_PT_RLCMAC_OPT),
587 rrbp:= ?,
588 rrbp_valid := ?,
589 usf := usf
590 },
591 opt := *,
592 payload := {
593 msg_type := PACKET_DL_ASSIGNMENT,
594 u := {
595 dl_assignment := {
596 page_mode := ?,
597 pres1 := ?,
598 persistence_levels := *,
Pau Espin Pedrol984d09f2020-05-19 18:51:58 +0200599 tfi_or_tlli := ?,
600 egprs2 := '0'B,
601 mac_mode := ?,
602 rlc_mode := ?,
603 control_ack := ?,
604 timeslot_alloc := ?,
605 pkt_ta := ?,
606 p0_present := ?,
607 p0 := *,
608 reserved := *,
609 pr_mode := *,
610 freq_par_present := ?,
611 freq_par := *,
612 dl_tfi_ass_present := ?,
613 dl_tfi_assignment := *,
614 pwr_ctrl_present := ?,
615 pwr_ctrl := *,
616 tbf_starting_time_present := ?,
617 tbf_starting_time := *,
Vadim Yanitskiy41b4dd82020-07-22 14:00:56 +0700618 spare := '0'B,
619 rel_additions := *
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200620 }
621 }
622 }
623 }
624 }
625
626 template RlcmacDlBlock tr_RLCMAC_UL_PACKET_ASS(template uint3_t usf := ?) := {
627 ctrl := {
628 mac_hdr := {
629 payload_type := (MAC_PT_RLCMAC_NO_OPT, MAC_PT_RLCMAC_OPT),
630 rrbp:= ?,
631 rrbp_valid := ?,
632 usf := usf
633 },
634 opt := *,
635 payload := {
636 msg_type := PACKET_UL_ASSIGNMENT,
637 u := {
638 ul_assignment := {
639 page_mode := ?,
640 persistence_levels_present := ?,
641 persistence_levels := *,
642 identity := ?,
643 is_egprs := ?, /* msg escape */
Pau Espin Pedrol45b664b2020-05-14 15:16:40 +0200644 gprs := *,
645 egprs := *
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200646 }
647 }
648 }
649 }
650 }
651
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +0200652 template RlcmacDlBlock tr_RLCMAC_UL_PACKET_ASS_GPRS(template uint3_t usf := ?, template PktUlAssGprs gprs := ?)
Vadim Yanitskiyc227ea92020-07-21 02:48:58 +0700653 modifies tr_RLCMAC_UL_PACKET_ASS := {
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +0200654 ctrl := {
655 payload := {
656 u := {
657 ul_assignment := {
658 is_egprs := '0'B,
Pau Espin Pedrol45b664b2020-05-14 15:16:40 +0200659 gprs := gprs,
660 egprs := omit
661 }
662 }
663 }
664 }
665 }
666
667 template RlcmacDlBlock tr_RLCMAC_UL_PACKET_ASS_EGPRS(template uint3_t usf := ?, template PktUlAssEgprs egprs := ?)
Vadim Yanitskiyc227ea92020-07-21 02:48:58 +0700668 modifies tr_RLCMAC_UL_PACKET_ASS := {
Pau Espin Pedrol45b664b2020-05-14 15:16:40 +0200669 ctrl := {
670 payload := {
671 u := {
672 ul_assignment := {
673 is_egprs := '1'B,
674 gprs := omit,
675 egprs := egprs
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +0200676 }
677 }
678 }
679 }
680 }
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200681
682 /* Receive Template for Uplink ACK/NACK */
Pau Espin Pedrol692222c2020-05-17 00:25:37 +0200683 template RlcmacDlBlock tr_RLCMAC_UL_ACK_NACK(template uint5_t ul_tfi) := {
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200684 ctrl := {
685 mac_hdr := {
686 payload_type := (MAC_PT_RLCMAC_NO_OPT, MAC_PT_RLCMAC_OPT),
687 rrbp:= ?,
688 rrbp_valid := ?,
689 usf := ?
690 },
691 opt := *,
692 payload := {
693 msg_type := PACKET_UL_ACK_NACK,
694 u := {
695 ul_ack_nack := {
696 page_mode := ?,
697 msg_excape := ?,
698 uplink_tfi := ul_tfi,
Pau Espin Pedrol692222c2020-05-17 00:25:37 +0200699 is_egprs := ?,
700 gprs := *,
701 egprs := *
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200702 }
703 }
704 }
705 }
Pau Espin Pedrol692222c2020-05-17 00:25:37 +0200706 };
707
Pau Espin Pedrol763a97b2023-07-24 16:43:10 +0200708 template RlcmacDlBlock tr_RLCMAC_UL_ACK_NACK_GPRS(template uint5_t ul_tfi := ?, template UlAckNackGprs gprs := tr_UlAckNackGprs(*))
Pau Espin Pedrol692222c2020-05-17 00:25:37 +0200709 modifies tr_RLCMAC_UL_ACK_NACK := {
710 ctrl := {
711 payload := {
712 u := {
713 ul_ack_nack := {
714 is_egprs := '0'B,
715 gprs := gprs,
716 egprs := omit
717 }
718 }
719 }
720 }
721 };
722
Pau Espin Pedrol763a97b2023-07-24 16:43:10 +0200723 template RlcmacDlBlock tr_RLCMAC_UL_ACK_NACK_EGPRS(template uint5_t ul_tfi := ?, template UlAckNackEgprs egprs := tr_UlAckNackEgprs(*))
Pau Espin Pedrol692222c2020-05-17 00:25:37 +0200724 modifies tr_RLCMAC_UL_ACK_NACK := {
725 ctrl := {
726 payload := {
727 u := {
728 ul_ack_nack := {
729 is_egprs := '1'B,
730 gprs := omit,
731 egprs := egprs
732 }
733 }
734 }
735 }
736 };
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200737
738 template RlcmacDlBlock tr_RLCMAC_PACKET_PAG_REQ(template uint3_t usf := ?) := {
739 ctrl := {
740 mac_hdr := {
741 payload_type := MAC_PT_RLCMAC_NO_OPT,
742 rrbp:= ?,
743 rrbp_valid := ?,
744 usf := usf
745 },
746 opt := *,
747 payload := {
748 msg_type := PACKET_PAGING_REQUEST,
749 u := {
750 paging := {
751 page_mode := ?,
752 persistence_levels_present := ?,
753 persistence_levels := *,
754 nln_present := ?,
755 nln := *,
Vadim Yanitskiye94164d2020-10-31 05:46:03 +0700756 repeated_pageinfo := *,
757 repeated_pageinfo_term := '0'B
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200758 }
759 }
760 }
761 }
762 }
763
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700764 /* Either GPRS or EGPRS data block with arbitrary contents */
765 template RlcmacDlBlock tr_RLCMAC_DATA := (tr_RLCMAC_DATA_GPRS, tr_RLCMAC_DATA_EGPRS);
766
Vadim Yanitskiyd4f22aa2020-05-10 13:13:46 +0700767 template RlcmacDlBlock tr_RLCMAC_DATA_GPRS(template (present) boolean rrbp_valid := ?,
768 template (present) MacRrbp rrbp := ?,
769 template (present) uint3_t usf := ?) := {
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200770 data := {
Pau Espin Pedrol5abfded2020-11-03 17:30:44 +0100771 cs := ?,
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200772 mac_hdr := {
773 mac_hdr := {
774 payload_type := MAC_PT_RLC_DATA,
Vadim Yanitskiyd4f22aa2020-05-10 13:13:46 +0700775 rrbp := rrbp,
776 rrbp_valid := rrbp_valid,
777 usf := usf
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200778 },
779 hdr_ext := ?
780 },
781 blocks := ?
782 }
783 }
784
785 template RlcmacDlBlock tr_RLCMAC_DATA_EGPRS := {
786 data_egprs := {
Pau Espin Pedrol5abfded2020-11-03 17:30:44 +0100787 mcs := ?,
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200788 mac_hdr := ?,
789 fbi := ?,
790 e := ?,
791 blocks := ?
792 }
793 }
794
795 /* Template for Uplink MAC Control Header */
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +0100796 template (value) UlMacCtrlHeader t_RLCMAC_UlMacCtrlH(template (value) MacPayloadType pt,
797 template (value) boolean retry := false) := {
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200798 payload_type := pt,
799 spare := '00000'B,
800 retry := retry
801 }
802
803 /* Template for Uplink Control ACK */
Vadim Yanitskiy4f034b12022-10-04 03:34:16 +0700804 template (value) RlcmacUlBlock
805 ts_RLCMAC_CTRL_ACK(GprsTlli tlli, CtrlAck ack := MS_RCVD_TWO_RLC_SAME_RTI_DIFF_RBSN) := {
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200806 ctrl := {
807 mac_hdr := t_RLCMAC_UlMacCtrlH(MAC_PT_RLCMAC_NO_OPT),
808 payload := {
809 msg_type := PACKET_CONTROL_ACK,
810 u := {
811 ctrl_ack := {
812 tlli := tlli,
813 ctrl_ack := ack
814 }
815 }
816 }
817 }
818 }
819
Vadim Yanitskiy58f9de22022-10-04 03:39:43 +0700820 template (value) RlcmacUlBlock
821 ts_RLCMAC_UL_DUMMY_CTRL(template (value) GprsTlli tlli) := {
822 ctrl := {
823 mac_hdr := t_RLCMAC_UlMacCtrlH(MAC_PT_RLCMAC_NO_OPT),
824 payload := {
825 msg_type := PACKET_UL_DUMMY_CTRL,
826 u := {
827 ul_dummy := {
828 tlli := tlli
829 }
830 }
831 }
832 }
833 }
834
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +0200835 template LlcBlockHdr t_RLCMAC_LLCBLOCK_HDR(uint16_t length_ind, boolean more, boolean e) := {
836 length_ind := length_ind,
837 more := more, /* 1 = new LLC PDU starts */
838 e := e /* 0 = another extension octet after LLC PDU, 1 = no more extension octets */
839 }
840
841 template EgprsLlcBlockHdr t_RLCMAC_LLCBLOCK_EGPRS_HDR(uint16_t length_ind, boolean e) := {
842 length_ind := length_ind,
843 e := e /* 0 = another extension octet after LLC PDU, 1 = no more extension octets */
844 }
845
846 /* Template for a LlcBlock (part of a LLC frame inside RlcMacDlDataBlock */
847 template LlcBlock t_RLCMAC_LLCBLOCK(octetstring data, template (omit) LlcBlockHdr llc_hdr := omit) := {
848 hdr := llc_hdr, /* omit = let encoder figure out the header */
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200849 payload := data
850 }
851
Pau Espin Pedrol2456dad2020-04-30 20:22:38 +0200852 /* Template for a LlcBlock (part of a LLC frame inside RlcMacEgprs?lDataBlock */
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +0200853 template EgprsLlcBlock t_RLCMAC_LLCBLOCK_EGPRS(octetstring data, template (omit) EgprsLlcBlockHdr llc_hdr := omit) := {
Pau Espin Pedrol2456dad2020-04-30 20:22:38 +0200854 /* let encoder figure out the header */
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +0200855 hdr := llc_hdr, /* omit = let encoder figure out the header */
Pau Espin Pedrol2456dad2020-04-30 20:22:38 +0200856 payload := data
857 }
858
Vadim Yanitskiy71be1292022-12-21 05:58:45 +0700859 template (value) PTCCHDownlinkMsg
860 ts_PTCCHDownlinkMsg(template (value) uint7_t tai0_ta := 0,
861 template (value) uint7_t tai1_ta := 0,
862 template (value) uint7_t tai2_ta := 0,
863 template (value) uint7_t tai3_ta := 0,
864 template (value) uint7_t tai4_ta := 0,
865 template (value) uint7_t tai5_ta := 0,
866 template (value) uint7_t tai6_ta := 0,
867 template (value) uint7_t tai7_ta := 0,
868 template (value) uint7_t tai8_ta := 0,
869 template (value) uint7_t tai9_ta := 0,
870 template (value) uint7_t tai10_ta := 0,
871 template (value) uint7_t tai11_ta := 0,
872 template (value) uint7_t tai12_ta := 0,
873 template (value) uint7_t tai13_ta := 0,
874 template (value) uint7_t tai14_ta := 0,
875 template (value) uint7_t tai15_ta := 0) := {
876 ta_idx := {
877 { spare := '0'B, ta_val := tai0_ta },
878 { spare := '0'B, ta_val := tai1_ta },
879 { spare := '0'B, ta_val := tai2_ta },
880 { spare := '0'B, ta_val := tai3_ta },
881 { spare := '0'B, ta_val := tai4_ta },
882 { spare := '0'B, ta_val := tai5_ta },
883 { spare := '0'B, ta_val := tai6_ta },
884 { spare := '0'B, ta_val := tai7_ta },
885 { spare := '0'B, ta_val := tai8_ta },
886 { spare := '0'B, ta_val := tai9_ta },
887 { spare := '0'B, ta_val := tai10_ta },
888 { spare := '0'B, ta_val := tai11_ta },
889 { spare := '0'B, ta_val := tai12_ta },
890 { spare := '0'B, ta_val := tai13_ta },
891 { spare := '0'B, ta_val := tai14_ta },
892 { spare := '0'B, ta_val := tai15_ta }
893 },
894 padding := '2B2B2B2B2B2B2B'O
895 }
Vadim Yanitskiy92c5d612022-12-21 05:57:13 +0700896 template PTCCHDownlinkMsg
897 tr_PTCCHDownlinkMsg(template (present) uint7_t tai0_ta := ?,
898 template (present) uint7_t tai1_ta := ?,
899 template (present) uint7_t tai2_ta := ?,
900 template (present) uint7_t tai3_ta := ?,
901 template (present) uint7_t tai4_ta := ?,
902 template (present) uint7_t tai5_ta := ?,
903 template (present) uint7_t tai6_ta := ?,
904 template (present) uint7_t tai7_ta := ?,
905 template (present) uint7_t tai8_ta := ?,
906 template (present) uint7_t tai9_ta := ?,
907 template (present) uint7_t tai10_ta := ?,
908 template (present) uint7_t tai11_ta := ?,
909 template (present) uint7_t tai12_ta := ?,
910 template (present) uint7_t tai13_ta := ?,
911 template (present) uint7_t tai14_ta := ?,
912 template (present) uint7_t tai15_ta := ?) := {
913 ta_idx := {
914 { spare := '0'B, ta_val := tai0_ta },
915 { spare := '0'B, ta_val := tai1_ta },
916 { spare := '0'B, ta_val := tai2_ta },
917 { spare := '0'B, ta_val := tai3_ta },
918 { spare := '0'B, ta_val := tai4_ta },
919 { spare := '0'B, ta_val := tai5_ta },
920 { spare := '0'B, ta_val := tai6_ta },
921 { spare := '0'B, ta_val := tai7_ta },
922 { spare := '0'B, ta_val := tai8_ta },
923 { spare := '0'B, ta_val := tai9_ta },
924 { spare := '0'B, ta_val := tai10_ta },
925 { spare := '0'B, ta_val := tai11_ta },
926 { spare := '0'B, ta_val := tai12_ta },
927 { spare := '0'B, ta_val := tai13_ta },
928 { spare := '0'B, ta_val := tai14_ta },
929 { spare := '0'B, ta_val := tai15_ta }
930 },
931 padding := '2B2B2B2B2B2B2B'O
932 }
933
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200934} with { encode "RAW"; variant "FIELDORDER(msb)" }