blob: dd1371f7258270cdf389df34cadced4778da34b2 [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 Pedrol27d6af52020-04-30 20:13:32 +020096 /* Coding and Puncturing Scheme indicator field for Header type 1 in EGPRS TBF or EC TBF or downlink EGPRS2 TBF */
97 function f_rlcmac_cps_htype1_to_mcs(uint3_t cps) return CodingScheme {
98 var CodingSchemeArray egprs_Header_type1_coding_puncturing_scheme_to_mcs := {
99 MCS_9 /* 0x00, "(MCS-9/P1 ; MCS-9/P1)" */,
100 MCS_9 /* 0x01, "(MCS-9/P1 ; MCS-9/P2)" */,
101 MCS_9 /* 0x02, "(MCS-9/P1 ; MCS-9/P3)" */,
102 MCS_0 /* 0x03, "reserved" */,
103 MCS_9 /* 0x04, "(MCS-9/P2 ; MCS-9/P1)" */,
104 MCS_9 /* 0x05, "(MCS-9/P2 ; MCS-9/P2)" */,
105 MCS_9 /* 0x06, "(MCS-9/P2 ; MCS-9/P3)" */,
106 MCS_0 /* 0x07, "reserved" */,
107 MCS_9 /* 0x08, "(MCS-9/P3 ; MCS-9/P1)" */,
108 MCS_9 /* 0x09, "(MCS-9/P3 ; MCS-9/P2)" */,
109 MCS_9 /* 0x0A, "(MCS-9/P3 ; MCS-9/P3)" */,
110 MCS_8 /* 0x0B, "(MCS-8/P1 ; MCS-8/P1)" */,
111 MCS_8 /* 0x0C, "(MCS-8/P1 ; MCS-8/P2)" */,
112 MCS_8 /* 0x0D, "(MCS-8/P1 ; MCS-8/P3)" */,
113 MCS_8 /* 0x0E, "(MCS-8/P2 ; MCS-8/P1)" */,
114 MCS_8 /* 0x0F, "(MCS-8/P2 ; MCS-8/P2)" */,
115 MCS_8 /* 0x10, "(MCS-8/P2 ; MCS-8/P3)" */,
116 MCS_8 /* 0x11, "(MCS-8/P3 ; MCS-8/P1)" */,
117 MCS_8 /* 0x12, "(MCS-8/P3 ; MCS-8/P2)" */,
118 MCS_8 /* 0x13, "(MCS-8/P3 ; MCS-8/P3)" */,
119 MCS_7 /* 0x14, "(MCS-7/P1 ; MCS-7/P1)" */,
120 MCS_7 /* 0x15, "(MCS-7/P1 ; MCS-7/P2)" */,
121 MCS_7 /* 0x16, "(MCS-7/P1 ; MCS-7/P3)" */,
122 MCS_7 /* 0x17, "(MCS-7/P2 ; MCS-7/P1)" */,
123 MCS_7 /* 0x18, "(MCS-7/P2 ; MCS-7/P2)" */,
124 MCS_7 /* 0x19, "(MCS-7/P2 ; MCS-7/P3)" */,
125 MCS_7 /* 0x1A, "(MCS-7/P3 ; MCS-7/P1)" */,
126 MCS_7 /* 0x1B, "(MCS-7/P3 ; MCS-7/P2)" */,
127 MCS_7 /* 0x1C, "(MCS-7/P3 ; MCS-7/P3)" */,
128 MCS_0 /* 0x1D, "reserved" */,
129 MCS_0 /* 0x1E, "reserved" */,
130 MCS_0 /* 0x1F, "reserved" */
131 };
132 return egprs_Header_type1_coding_puncturing_scheme_to_mcs[cps];
133 }
134
135 /* Coding and Puncturing Scheme indicator field for Header type 2 in (EC-)EGPRS TBF or uplink EGPRS2-A TBF */
136 function f_rlcmac_cps_htype2_to_mcs(uint3_t cps) return CodingScheme {
137 var CodingSchemeArray egprs_Header_type2_coding_puncturing_scheme_to_mcs := {
138 MCS_6 /* {0x00, "MCS-6/P1"} */,
139 MCS_6 /* {0x01, "MCS-6/P2"} */,
140 MCS_6 /* {0x02, "MCS-6/P1 with 6 octet padding"} */,
141 MCS_6 /* {0x03, "MCS-6/P2 with 6 octet padding "} */,
142 MCS_5 /* {0x04, "MCS-5/P1"} */,
143 MCS_5 /* {0x05, "MCS-5/P2"} */,
144 MCS_5 /* {0x06, "MCS-6/P1 with 10 octet padding "} */,
145 MCS_5 /* {0x07, "MCS-6/P2 with 10 octet padding "} */
146 };
147 return egprs_Header_type2_coding_puncturing_scheme_to_mcs[cps];
148 }
149
150 /* Coding and Puncturing Scheme indicator field for Header type 3 */
151 function f_rlcmac_cps_htype3_to_mcs(uint3_t cps) return CodingScheme {
152 var CodingSchemeArray egprs_Header_type3_coding_puncturing_scheme_to_mcs := {
153 MCS_4 /* {0x00, "MCS-4/P1"} */,
154 MCS_4 /* {0x01, "MCS-4/P2"} */,
155 MCS_4 /* {0x02, "MCS-4/P3"} */,
156 MCS_3 /* {0x03, "MCS-3/P1"} */,
157 MCS_3 /* {0x04, "MCS-3/P2"} */,
158 MCS_3 /* {0x05, "MCS-3/P3"} */,
159 MCS_3 /* {0x06, "MCS-3/P1 with padding"} */,
160 MCS_3 /* {0x07, "MCS-3/P2 with padding"} */,
161 MCS_3 /* {0x08, "MCS-3/P3 with padding"} */,
162 MCS_2 /* {0x09, "MCS-2/P1"} */,
163 MCS_2 /* {0x0A, "MCS-2/P2"} */,
164 MCS_1 /* {0x0B, "MCS-1/P1"} */,
165 MCS_1 /* {0x0C, "MCS-1/P2"} */,
166 MCS_2 /* {0x0D, "MCS-2/P1 with padding"} */,
167 MCS_2 /* {0x0E, "MCS-2/P2 with padding"} */,
168 MCS_0 /* {0x0F, "MCS-0"} */
169 };
170 return egprs_Header_type3_coding_puncturing_scheme_to_mcs[cps];
171 }
172
173 function f_rlcmac_cps_htype_to_mcs(uint3_t cps, EgprsHeaderType htype) return CodingScheme {
174 select (htype) {
175 case (RLCMAC_HDR_TYPE_1) { return f_rlcmac_cps_htype1_to_mcs(cps); }
176 case (RLCMAC_HDR_TYPE_2) { return f_rlcmac_cps_htype2_to_mcs(cps); }
177 case (RLCMAC_HDR_TYPE_3) { return f_rlcmac_cps_htype3_to_mcs(cps); }
178 }
179 //TODO: return error here.
180 return CS_1;
181 }
182
183 function f_rlcmac_mcs_to_cps_htype1(CodingScheme mcs, uint2_t part, boolean with_padding) return uint5_t {
184 //TODO: implement similar to f_rlcmac_mcs_to_cps_htype3()
185 //TODO: return error here.
186 return 0;
187 }
188
189 function f_rlcmac_mcs_to_cps_htype2(CodingScheme mcs, uint2_t part, boolean with_padding) return uint5_t {
190 //TODO: implement similar to f_rlcmac_mcs_to_cps_htype3()
191 //TODO: return error here.
192 return 0;
193 }
194
195 function f_rlcmac_mcs_to_cps_htype3(CodingScheme mcs, uint2_t part, boolean with_padding) return uint5_t {
196 select (mcs) {
197 case (MCS_4) {
198 select (part) {
199 case (1) { return 0; /* {0x00, "MCS-4/P1"} */ }
200 case (2) { return 1; /* {0x01, "MCS-4/P2"} */ }
201 case (3) { return 2; /* {0x01, "MCS-4/P2"} */ }
202 }
203 }
204 case (MCS_3) {
205 if (not with_padding) {
206 select (part) {
207 case (1) { return 3; /* {0x03, "MCS-3/P1"} */ }
208 case (2) { return 4; /* {0x04, "MCS-3/P2"} */ }
209 case (3) { return 5; /* {0x05, "MCS-3/P3"} */ }
210 }
211 } else {
212 select (part) {
213 case (1) { return 6; /* {0x06, "MCS-3/P1 with padding"} */ }
214 case (2) { return 7; /* {0x07, "MCS-3/P2 with padding"} */ }
215 case (3) { return 8; /* {0x08, "MCS-3/P3 with padding"} */ }
216 }
217 }
218 }
219 case (MCS_2) {
220 if (not with_padding) {
221 select (part) {
222 case (1) { return 9; /* {0x09, "MCS-2/P1"} */ }
223 case (2) { return 10; /* {0x0A, "MCS-2/P2"} */ }
224 }
225 } else {
226 select (part) {
227 case (1) { return 13; /* {0x0D, "MCS-2/P1 with padding"} */ }
228 case (2) { return 14; /* {0x0E, "MCS-2/P2 with padding"} */}
229 }
230 }
231 }
232 case (MCS_1) {
233 select (part) {
234 case (1) { return 11; /* {0x0B, "MCS-1/P1"} */ }
235 case (2) { return 12; /* {0x0C, "MCS-1/P2"} */ }
236 }
237 }
238 case (MCS_0) { return 15; /* {0x0F, "MCS-0"} */ }
239 }
240 //TODO: return error here.
241 return 0;
242 }
243
244 function f_rlcmac_mcs_to_cps(CodingScheme mcs, uint2_t part, boolean with_padding := false) return uint5_t {
245
246 var EgprsHeaderType htype := f_rlcmac_mcs2headertype(mcs);
247 select (htype) {
248 case (RLCMAC_HDR_TYPE_1) { return f_rlcmac_mcs_to_cps_htype1(mcs, part, with_padding); }
249 case (RLCMAC_HDR_TYPE_2) { return f_rlcmac_mcs_to_cps_htype2(mcs, part, with_padding); }
250 case (RLCMAC_HDR_TYPE_3) { return f_rlcmac_mcs_to_cps_htype3(mcs, part, with_padding); }
251 }
252 //TODO: return error here.
253 return 0;
254 }
255
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200256 template (value) RlcmacUlBlock ts_RLC_UL_CTRL_ACK(RlcmacUlCtrlMsg ctrl,
257 MacPayloadType pt := MAC_PT_RLCMAC_NO_OPT,
258 boolean retry := false) := {
259 ctrl := {
260 mac_hdr := {
261 payload_type := pt,
262 spare := '00000'B,
263 retry := retry
264 },
265 payload := ctrl
266 }
267 }
268
269 /* Send Template for Downlink ACK/NACK */
270 template RlcmacUlBlock ts_RLCMAC_DL_ACK_NACK(template uint5_t tfi, AckNackDescription andesc, boolean retry := false) := {
271 ctrl := {
272 mac_hdr := {
273 payload_type := MAC_PT_RLCMAC_NO_OPT,
274 spare := '00000'B,
275 retry := retry
276 },
277 payload := {
278 msg_type := PACKET_DL_ACK_NACK,
279 u := {
280 dl_ack_nack := {
281 dl_tfi := tfi,
282 ack_nack_desc := andesc,
283 chreq_desc_presence := '0'B,
284 chreq_desc := omit,
285 ch_qual_rep := c_ChQualRep_default
286 }
287 }
288 }
289 }
290 }
291
292 /* Template for uplink Data block */
293 template RlcmacUlBlock t_RLCMAC_UL_DATA(template uint5_t tfi, template uint4_t cv, template uint7_t bsn,
294 template LlcBlocks blocks := {}, template boolean stall := false) := {
295 data := {
296 mac_hdr := {
297 payload_type := MAC_PT_RLC_DATA,
298 countdown := cv,
299 stall_ind := false,
300 retry := false,
301 spare := '0'B,
302 pfi_ind := false,
303 tfi := tfi,
304 tlli_ind := false,
305 bsn := bsn,
306 e := false
307 },
308 tlli := omit,
309 pfi := omit,
310 blocks := blocks
311 }
312 }
313 template RlcmacUlBlock t_RLCMAC_UL_DATA_TLLI(template uint5_t tfi, template uint4_t cv, template uint7_t bsn,
314 template LlcBlocks blocks := {}, template boolean stall := false, template GprsTlli tlli) := {
315 data := {
316 mac_hdr := {
317 payload_type := MAC_PT_RLC_DATA,
318 countdown := cv,
319 stall_ind := false,
320 retry := false,
321 spare := '0'B,
322 pfi_ind := false,
323 tfi := tfi,
324 tlli_ind := true,
325 bsn := bsn,
326 e := false
327 },
328 tlli := tlli,
329 pfi := omit,
330 blocks := blocks
331 }
332 }
333
Pau Espin Pedrol2456dad2020-04-30 20:22:38 +0200334 /* Template for uplink Data block */
335 template RlcmacUlBlock t_RLCMAC_UL_EGPRS_DATA(CodingScheme mcs,
336 template uint5_t tfi, template uint4_t cv,
337 template uint11_t bsn1, template EgprsLlcBlocks blocks := {}) := {
338 data_egprs := {
339 mac_hdr := {
340 header_type := f_rlcmac_mcs2headertype(mcs),
341 tfi := tfi,
342 countdown := cv,
343 foi_si := '0'B,
344 r_ri := '0'B,
345 bsn1 := bsn1,
346 cps := f_rlcmac_mcs_to_cps(mcs, 1, false),
347 pfi_ind := false,
348 rsb := '0'B,
349 spb := '00'B
350 },
351 tlli_ind := false,
352 e := false,
353 tlli := omit,
354 pfi := omit,
355 blocks := blocks
356 }
357 }
358
Vadim Yanitskiy0a9b1482020-05-10 14:43:21 +0700359 template DlMacHeader t_RLCMAC_DlMacH(template (present) MacPayloadType pt,
360 template (present) boolean rrbp_valid,
361 template (present) MacRrbp rrbp,
362 template (present) uint3_t usf) := {
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200363 payload_type := pt,
364 rrbp := rrbp,
Vadim Yanitskiy0a9b1482020-05-10 14:43:21 +0700365 rrbp_valid := rrbp_valid,
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200366 usf := usf
367 }
368
369 template RlcmacDlBlock tr_RLCMAC_DUMMY_CTRL(template uint3_t usf := ?, template PageMode page_mode := ?) := {
370 ctrl := {
371 mac_hdr := {
372 payload_type := (MAC_PT_RLCMAC_NO_OPT, MAC_PT_RLCMAC_OPT),
373 rrbp:= ?,
374 rrbp_valid := ?,
375 usf := usf
376 },
377 opt := *,
378 payload := {
379 msg_type := PACKET_DL_DUMMY_CTRL,
380 u := {
381 dl_dummy := {
382 page_mode := page_mode,
383 persistence_levels_present := ?,
384 persistence_levels := *
385 }
386 }
387 }
388 }
389 }
390
391 template RlcmacDlBlock tr_RLCMAC_DL_PACKET_ASS(template uint3_t usf := ?) := {
392 ctrl := {
393 mac_hdr := {
394 payload_type := (MAC_PT_RLCMAC_NO_OPT, MAC_PT_RLCMAC_OPT),
395 rrbp:= ?,
396 rrbp_valid := ?,
397 usf := usf
398 },
399 opt := *,
400 payload := {
401 msg_type := PACKET_DL_ASSIGNMENT,
402 u := {
403 dl_assignment := {
404 page_mode := ?,
405 pres1 := ?,
406 persistence_levels := *,
407 tfi_or_tlli := ?
408 }
409 }
410 }
411 }
412 }
413
414 template RlcmacDlBlock tr_RLCMAC_UL_PACKET_ASS(template uint3_t usf := ?) := {
415 ctrl := {
416 mac_hdr := {
417 payload_type := (MAC_PT_RLCMAC_NO_OPT, MAC_PT_RLCMAC_OPT),
418 rrbp:= ?,
419 rrbp_valid := ?,
420 usf := usf
421 },
422 opt := *,
423 payload := {
424 msg_type := PACKET_UL_ASSIGNMENT,
425 u := {
426 ul_assignment := {
427 page_mode := ?,
428 persistence_levels_present := ?,
429 persistence_levels := *,
430 identity := ?,
431 is_egprs := ?, /* msg escape */
432 gprs := *
433 }
434 }
435 }
436 }
437 }
438
439
440 /* Receive Template for Uplink ACK/NACK */
441 template RlcmacDlBlock tr_RLCMAC_UL_ACK_NACK(template uint5_t ul_tfi, template GprsTlli tlli := ?) := {
442 ctrl := {
443 mac_hdr := {
444 payload_type := (MAC_PT_RLCMAC_NO_OPT, MAC_PT_RLCMAC_OPT),
445 rrbp:= ?,
446 rrbp_valid := ?,
447 usf := ?
448 },
449 opt := *,
450 payload := {
451 msg_type := PACKET_UL_ACK_NACK,
452 u := {
453 ul_ack_nack := {
454 page_mode := ?,
455 msg_excape := ?,
456 uplink_tfi := ul_tfi,
457 is_egprs := '0'B,
458 gprs := {
459 ch_coding_cmd := ?,
460 ack_nack_desc := ?,
461 cont_res_tlli_present := ?,
462 cont_res_tlli := tlli,
463 pkt_ta_present := ?,
464 pkt_ta := *,
465 pwr_ctrl_present := ?,
466 pwr_ctrl := *
467 }
468 }
469 }
470 }
471 }
472 }
473
474 template RlcmacDlBlock tr_RLCMAC_PACKET_PAG_REQ(template uint3_t usf := ?) := {
475 ctrl := {
476 mac_hdr := {
477 payload_type := MAC_PT_RLCMAC_NO_OPT,
478 rrbp:= ?,
479 rrbp_valid := ?,
480 usf := usf
481 },
482 opt := *,
483 payload := {
484 msg_type := PACKET_PAGING_REQUEST,
485 u := {
486 paging := {
487 page_mode := ?,
488 persistence_levels_present := ?,
489 persistence_levels := *,
490 nln_present := ?,
491 nln := *,
492 repeated_pageinfo_present := ?,
493 repeated_pageinfo := *
494 }
495 }
496 }
497 }
498 }
499
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700500 /* Either GPRS or EGPRS data block with arbitrary contents */
501 template RlcmacDlBlock tr_RLCMAC_DATA := (tr_RLCMAC_DATA_GPRS, tr_RLCMAC_DATA_EGPRS);
502
Vadim Yanitskiyd4f22aa2020-05-10 13:13:46 +0700503 template RlcmacDlBlock tr_RLCMAC_DATA_GPRS(template (present) boolean rrbp_valid := ?,
504 template (present) MacRrbp rrbp := ?,
505 template (present) uint3_t usf := ?) := {
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200506 data := {
507 mac_hdr := {
508 mac_hdr := {
509 payload_type := MAC_PT_RLC_DATA,
Vadim Yanitskiyd4f22aa2020-05-10 13:13:46 +0700510 rrbp := rrbp,
511 rrbp_valid := rrbp_valid,
512 usf := usf
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200513 },
514 hdr_ext := ?
515 },
516 blocks := ?
517 }
518 }
519
520 template RlcmacDlBlock tr_RLCMAC_DATA_EGPRS := {
521 data_egprs := {
522 mac_hdr := ?,
523 fbi := ?,
524 e := ?,
525 blocks := ?
526 }
527 }
528
529 /* Template for Uplink MAC Control Header */
530 template UlMacCtrlHeader t_RLCMAC_UlMacCtrlH(template MacPayloadType pt, template boolean retry := false) := {
531 payload_type := pt,
532 spare := '00000'B,
533 retry := retry
534 }
535
536 /* Template for Uplink Control ACK */
537 template RlcmacUlBlock ts_RLCMAC_CTRL_ACK(GprsTlli tlli, CtrlAck ack := MS_RCVD_TWO_RLC_SAME_RTI_DIFF_RBSN) := {
538 ctrl := {
539 mac_hdr := t_RLCMAC_UlMacCtrlH(MAC_PT_RLCMAC_NO_OPT),
540 payload := {
541 msg_type := PACKET_CONTROL_ACK,
542 u := {
543 ctrl_ack := {
544 tlli := tlli,
545 ctrl_ack := ack
546 }
547 }
548 }
549 }
550 }
551
552 /* Template for a LlcBlock (part of a LLC frame inside RlcMac?lDataBlock */
553 template LlcBlock t_RLCMAC_LLCBLOCK(octetstring data, boolean more := false, boolean e := true) := {
554 /* let encoder figure out the header */
555 hdr := omit,
556 payload := data
557 }
558
Pau Espin Pedrol2456dad2020-04-30 20:22:38 +0200559 /* Template for a LlcBlock (part of a LLC frame inside RlcMacEgprs?lDataBlock */
560 template EgprsLlcBlock t_RLCMAC_LLCBLOCK_EGPRS(octetstring data, boolean e := true) := {
561 /* let encoder figure out the header */
562 hdr := omit,
563 payload := data
564 }
565
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +0200566} with { encode "RAW"; variant "FIELDORDER(msb)" }