blob: dbcf4ae2c1c58385f84f59b391c4fd243643e80f [file] [log] [blame]
Harald Welte484160b2017-07-28 13:30:24 +02001/* TITAN REW encode/decode definitions for 3GPP TS 44.060 RLC/MAC Blocks */
Harald Welte34b5a952019-05-27 11:54:11 +02002
3/* (C) 2017-2018 Harald Welte <laforge@gnumonks.org>
4 * All rights reserved.
5 *
6 * Released under the terms of GNU General Public License, Version 2 or
7 * (at your option) any later version.
8 *
9 * SPDX-License-Identifier: GPL-2.0-or-later
10 */
11
Harald Welte484160b2017-07-28 13:30:24 +020012module RLCMAC_Types {
13 import from General_Types all;
14 import from Osmocom_Types all;
15 import from GSM_Types all;
Harald Welte9d348522017-08-01 00:27:39 +020016 import from RLCMAC_CSN1_Types all;
Harald Welte484160b2017-07-28 13:30:24 +020017
18 /* TS 44.060 10.4.7 */
19 type enumerated MacPayloadType {
20 MAC_PT_RLC_DATA ('00'B),
21 MAC_PT_RLCMAC_NO_OPT ('01'B),
22 MAC_PT_RLCMAC_OPT ('10'B),
23 MAC_PT_RESERVED ('11'B)
24 } with { variant "FIELDLENGTH(2)" };
25
26 /* TS 44.060 10.4.5 */
27 type enumerated MacRrbp {
28 RRBP_Nplus13_mod_2715648 ('00'B),
29 RRBP_Nplus17_or_18_mod_2715648 ('01'B),
Harald Welte1cd673d2018-03-02 21:41:31 +010030 RRBP_Nplus21_or_22_mod_2715648 ('10'B),
Harald Welte484160b2017-07-28 13:30:24 +020031 RRBP_Nplus26_mod_2715648 ('11'B)
32 } with { variant "FIELDLENGTH(2)" };
33
Pau Espin Pedrol65bab9e2019-12-04 21:05:10 +010034 function f_rrbp_fn_delay(MacRrbp rrbp) return uint32_t {
35 select (rrbp) {
36 case (RRBP_Nplus13_mod_2715648) { return 13; }
37 case (RRBP_Nplus17_or_18_mod_2715648) { return 17; }
38 case (RRBP_Nplus21_or_22_mod_2715648) { return 21; }
39 case (RRBP_Nplus26_mod_2715648) { return 26; }
40 }
41 return 0;
42 }
43
Pau Espin Pedroldc9666f2020-03-18 20:30:16 +010044 type enumerated CodingScheme {
45 CS_1,
46 CS_2,
47 CS_3,
48 CS_4,
49 MCS_1,
50 MCS_2,
51 MCS_3,
52 MCS_4,
53 MCS_5,
54 MCS_6,
55 MCS_7,
56 MCS_8,
57 MCS_9
58 //MCS5_7, ?
59 // MCS6_9 ?
60 };
61
62 function f_rlcmac_cs_mcs2block_len(CodingScheme cs_mcs) return uint32_t {
63 select (cs_mcs) {
64 case (CS_1) { return 23; }
65 case (CS_2) { return 34; }
66 case (CS_3) { return 40; }
67 case (CS_4) { return 54; }
68 case (MCS_1) { return 27; }
69 case (MCS_2) { return 33; }
70 case (MCS_3) { return 42; }
71 case (MCS_4) { return 49; }
72 case (MCS_5) { return 61; }
73 case (MCS_6) { return 79; }
74 case (MCS_7) { return 119; }
75 case (MCS_8) { return 143; }
76 case (MCS_9) { return 155; }
77 }
78 return 0;
79 }
80
81 function f_rlcmac_block_len2cs_mcs(uint32_t len) return CodingScheme {
82 select (len) {
83 case (23) { return CS_1; }
84 case (34) { return CS_2; }
85 case (40) { return CS_3; }
86 case (54) { return CS_4; }
87 case (27) { return MCS_1; }
88 case (33) { return MCS_2; }
89 case (42) { return MCS_3; }
90 case (49) { return MCS_4; }
91 case (60) { return MCS_5; }
92 case (61) { return MCS_5; }
93 case (78) { return MCS_6; }
94 case (79) { return MCS_6; }
95 case (118) { return MCS_7; }
96 case (119) { return MCS_7; }
97 case (142) { return MCS_8; }
98 case (143) { return MCS_8; }
99 case (154) { return MCS_9; }
100 case (155) { return MCS_9; }
101 }
102 return CS_1;
103 }
104
Harald Welte484160b2017-07-28 13:30:24 +0200105 /* Partof DL RLC data block and DL RLC/MAC ctrl block */
106 type record DlMacHeader {
107 MacPayloadType payload_type,
108 MacRrbp rrbp,
109 boolean rrbp_valid,
110 uint3_t usf
111 } with {
112 variant (rrbp_valid) "FIELDLENGTH(1)"
113 };
114
115 /* TS 44.060 10.4.10a */
116 type enumerated PowerReduction {
117 PWR_RED_0_to_3dB ('00'B),
118 PWR_RED_3_to_7dB ('01'B),
119 PWR_RED_7_to_10dB ('10'B),
120 PWR_RED_RESERVED ('11'B)
121 } with { variant "FIELDLENGTH(2)" };
122
123 /* TS 44.060 10.4.9d */
124 type enumerated DirectionBit {
125 DIR_UPLINK_TBF ('0'B),
126 DIR_DOWNLINK_TBF ('1'B)
127 } with { variant "FIELDLENGTH(1)" };
128
129 type record TfiOctet {
130 /* PR, TFI, D */
131 PowerReduction pr,
132 uint5_t tfi,
133 DirectionBit d
134 } with { variant "" };
135
136 type record RbsnExtOctet {
137 uint3_t rbsn_e,
138 BIT1 fs_e,
139 BIT4 spare
140 } with { variant "" };
141
142 type record DlCtrlOptOctets {
143 /* RBSN, RTI, FS, AC (optional, depending on mac_hdr.payload_type) */
144 BIT1 rbsn,
145 uint5_t rti,
146 boolean fs,
147 boolean tfi_octet_present,
148 TfiOctet tfi optional,
149 RbsnExtOctet rbsn_ext optional
150 } with {
151 variant (fs) "FIELDLENGTH(1)"
152 variant (tfi_octet_present) "FIELDLENGTH(1)"
153 variant (tfi) "PRESENCE(tfi_octet_present = true)"
154 variant (rbsn_ext) "PRESENCE(rbsn='1'B, fs=false)"
155 };
156
157 /* TS 44.060 10.3.1 Downlink RLC/MAC control block */
158 type record RlcmacDlCtrlBlock {
159 DlMacHeader mac_hdr,
160 DlCtrlOptOctets opt optional,
Harald Welte9d348522017-08-01 00:27:39 +0200161 RlcmacDlCtrlMsg payload
Harald Welte484160b2017-07-28 13:30:24 +0200162 } with {
163 variant (opt) "PRESENCE(mac_hdr.payload_type = MAC_PT_RLCMAC_OPT)"
164 };
165
166 external function enc_RlcmacDlCtrlBlock(in RlcmacDlCtrlBlock si) return octetstring
167 with { extension "prototype(convert) encode(RAW)" };
168 external function dec_RlcmacDlCtrlBlock(in octetstring stream) return RlcmacDlCtrlBlock
169 with { extension "prototype(convert) decode(RAW)" };
170
171 type record UlMacCtrlHeader {
Harald Welteefbc2fc2017-07-31 00:05:23 +0200172 MacPayloadType payload_type,
Harald Welte484160b2017-07-28 13:30:24 +0200173 BIT5 spare,
174 boolean retry
175 } with { variant (retry) "FIELDLENGTH(1)" };
176
177 /* TS 44.060 10.3.2 UplinkRLC/MAC control block */
178 type record RlcmacUlCtrlBlock {
179 UlMacCtrlHeader mac_hdr,
Harald Welte9d348522017-08-01 00:27:39 +0200180 RlcmacUlCtrlMsg payload
Harald Welte484160b2017-07-28 13:30:24 +0200181 } with { variant "" };
182
183 external function enc_RlcmacUlCtrlBlock(in RlcmacUlCtrlBlock si) return octetstring
184 with { extension "prototype(convert) encode(RAW)" };
185 external function dec_RlcmacUlCtrlBlock(in octetstring stream) return RlcmacUlCtrlBlock
186 with { extension "prototype(convert) decode(RAW)" };
187
188 /* a single RLC block / LLC-segment */
Harald Welte43e060a2017-07-30 22:38:03 +0200189 type record LlcBlockHdr {
Harald Welte484160b2017-07-28 13:30:24 +0200190 uint6_t length_ind,
191 /* 1 = new LLC PDU starts */
Harald Welte060e27a2018-03-03 20:38:19 +0100192 boolean more,
Harald Welte484160b2017-07-28 13:30:24 +0200193 /* 0 = another extension octet after LLC PDU, 1 = no more extension octets */
Harald Welte43e060a2017-07-30 22:38:03 +0200194 boolean e
Harald Welte484160b2017-07-28 13:30:24 +0200195 } with {
Harald Welte43e060a2017-07-30 22:38:03 +0200196 variant (e) "FIELDLENGTH(1)"
Harald Weltecc5c1152018-03-09 12:54:01 +0100197 encode "RAW"
Harald Welte484160b2017-07-28 13:30:24 +0200198 };
Harald Weltecc5c1152018-03-09 12:54:01 +0100199
200 external function enc_LlcBlockHdr(in LlcBlockHdr si) return octetstring
201 with { extension "prototype(convert) encode(RAW)" };
202 external function dec_LlcBlockHdr(in octetstring stream) return LlcBlockHdr
203 with { extension "prototype(convert) decode(RAW)" };
204
Harald Welte43e060a2017-07-30 22:38:03 +0200205 type record LlcBlock {
206 /* Header is only present if LI field was present */
Harald Welte060e27a2018-03-03 20:38:19 +0100207 LlcBlockHdr hdr optional,
Harald Welte43e060a2017-07-30 22:38:03 +0200208 octetstring payload
209 } with { variant "" };
210 type record of LlcBlock LlcBlocks;
Harald Welte484160b2017-07-28 13:30:24 +0200211
212 /* TS 44.060 10.2.1 Downlink RLC data block */
Harald Welte43e060a2017-07-30 22:38:03 +0200213 type record DlMacHdrDataExt {
Harald Welte484160b2017-07-28 13:30:24 +0200214 /* Octet 1 */
Harald Welte484160b2017-07-28 13:30:24 +0200215 PowerReduction pr,
216 BIT1 spare,
217 uint4_t tfi, /* 3 or 4? */
218 boolean fbi,
Harald Welte43e060a2017-07-30 22:38:03 +0200219 /* Octet 2 */
Harald Welte484160b2017-07-28 13:30:24 +0200220 uint7_t bsn,
Harald Welte43e060a2017-07-30 22:38:03 +0200221 boolean e
222 } with {
223 variant (e) "FIELDLENGTH(1)"
224 };
225 type record DlMacDataHeader {
226 DlMacHeader mac_hdr,
227 DlMacHdrDataExt hdr_ext
Harald Welte484160b2017-07-28 13:30:24 +0200228 } with { variant "" };
Harald Welte43e060a2017-07-30 22:38:03 +0200229 type record RlcmacDlDataBlock {
230 DlMacDataHeader mac_hdr,
231 /* Octet 3..M / N: manual C++ Decoder */
232 LlcBlocks blocks
233 } with {
234 variant ""
235 };
Harald Welte484160b2017-07-28 13:30:24 +0200236
Harald Welte43e060a2017-07-30 22:38:03 +0200237 external function enc_RlcmacDlDataBlock(in RlcmacDlDataBlock si) return octetstring;
238 external function dec_RlcmacDlDataBlock(in octetstring stream) return RlcmacDlDataBlock;
Harald Welte484160b2017-07-28 13:30:24 +0200239
240
241 /* TS 44.060 10.2.2 */
242 type record UlMacDataHeader {
Harald Welte43e060a2017-07-30 22:38:03 +0200243 /* Octet 0 */
Harald Welteefbc2fc2017-07-31 00:05:23 +0200244 MacPayloadType payload_type,
Harald Welte484160b2017-07-28 13:30:24 +0200245 uint4_t countdown,
246 boolean stall_ind,
Harald Welte43e060a2017-07-30 22:38:03 +0200247 boolean retry,
248 /* Octet 1 */
249 BIT1 spare,
250 boolean pfi_ind,
251 uint5_t tfi,
252 boolean tlli_ind,
253 /* Octet 2 */
254 uint7_t bsn,
255 boolean e
Harald Welte484160b2017-07-28 13:30:24 +0200256 } with {
Harald Welte43e060a2017-07-30 22:38:03 +0200257 variant (stall_ind) "FIELDLENGTH(1)"
258 variant (retry) "FIELDLENGTH(1)"
259 variant (pfi_ind) "FIELDLENGTH(1)"
260 variant (tlli_ind) "FIELDLENGTH(1)"
261 variant (e) "FIELDLENGTH(1)"
Harald Welte484160b2017-07-28 13:30:24 +0200262 };
263
Harald Welte484160b2017-07-28 13:30:24 +0200264 type record RlcMacUlPfi {
265 uint7_t pfi,
266 boolean m
267 } with {
268 variant (m) "FIELDLENGTH(1)"
269 };
270
271 /* TS 44.060 10.2.2 */
272 type record RlcmacUlDataBlock {
273 /* MAC header */
274 UlMacDataHeader mac_hdr,
Harald Welte43e060a2017-07-30 22:38:03 +0200275 /* Octet 3 ... M (optional): manual C++ Decoder */
276 GprsTlli tlli optional,
277 RlcMacUlPfi pfi optional,
278 LlcBlocks blocks
Harald Welte484160b2017-07-28 13:30:24 +0200279 } with {
Harald Welte43e060a2017-07-30 22:38:03 +0200280 variant (tlli) "PRESENCE(mac_hdr.tlli_ind = true)"
281 variant (pfi) "PRESENCE(mac_hdr.pfi_ind = true)"
Harald Welte484160b2017-07-28 13:30:24 +0200282 };
283
Harald Welte43e060a2017-07-30 22:38:03 +0200284 external function enc_RlcmacUlDataBlock(in RlcmacUlDataBlock si) return octetstring;
285 external function dec_RlcmacUlDataBlock(in octetstring stream) return RlcmacUlDataBlock;
Harald Welte484160b2017-07-28 13:30:24 +0200286
Harald Welteefbc2fc2017-07-31 00:05:23 +0200287 type union RlcmacUlBlock {
288 RlcmacUlDataBlock data,
289 RlcmacUlCtrlBlock ctrl
290 } with {
291 variant "TAG(data, mac_hdr.payload_type = MAC_PT_RLC_DATA;
292 ctrl, mac_hdr.payload_type = MAC_PT_RLCMAC_NO_OPT;
293 ctrl, mac_hdr.payload_type = MAC_PT_RLCMAC_OPT)"
294 };
295
Harald Welte78a1af62017-07-31 17:33:56 +0200296 /* as the sub-types (RlcmacDl*Block) are not using the RAW coder, we cannot
297 * use auto-generated functions here, as they would decode those sub-types
298 * based on the RAW coder, not baed on the manual C++ functions */
299 external function enc_RlcmacUlBlock(in RlcmacUlBlock si) return octetstring;
300 external function dec_RlcmacUlBlock(in octetstring stream) return RlcmacUlBlock;
Harald Welteefbc2fc2017-07-31 00:05:23 +0200301
302 type union RlcmacDlBlock {
303 RlcmacDlDataBlock data,
304 RlcmacDlCtrlBlock ctrl
305 } with {
306 variant "TAG(data, mac_hdr.mac_hdr.payload_type = MAC_PT_RLC_DATA;
307 ctrl, mac_hdr.payload_type = MAC_PT_RLCMAC_NO_OPT;
308 ctrl, mac_hdr.payload_type = MAC_PT_RLCMAC_OPT)"
309 };
310
Harald Welte78a1af62017-07-31 17:33:56 +0200311 /* as the sub-types (RlcmacDl*Block) are not using the RAW coder, we cannot
312 * use auto-generated functions here, as they would decode those sub-types
313 * based on the RAW coder, not baed on the manual C++ functions */
314 external function enc_RlcmacDlBlock(in RlcmacDlBlock si) return octetstring;
315 external function dec_RlcmacDlBlock(in octetstring stream) return RlcmacDlBlock;
Harald Welteefbc2fc2017-07-31 00:05:23 +0200316
Harald Welte7024baa2018-03-02 23:37:51 +0100317 template (value) RlcmacUlBlock ts_RLC_UL_CTRL_ACK(RlcmacUlCtrlMsg ctrl,
318 MacPayloadType pt := MAC_PT_RLCMAC_NO_OPT,
319 boolean retry := false) := {
320 ctrl := {
321 mac_hdr := {
322 payload_type := pt,
323 spare := '00000'B,
324 retry := retry
325 },
326 payload := ctrl
327 }
328 }
329
Pau Espin Pedrola3f0a852019-12-02 19:16:26 +0100330 /* Send Template for Downlink ACK/NACK */
331 template RlcmacUlBlock ts_RLCMAC_DL_ACK_NACK(template uint5_t tfi, AckNackDescription andesc, boolean retry := false) := {
332 ctrl := {
333 mac_hdr := {
334 payload_type := MAC_PT_RLCMAC_NO_OPT,
335 spare := '00000'B,
336 retry := retry
337 },
338 payload := {
339 msg_type := PACKET_DL_ACK_NACK,
340 u := {
341 dl_ack_nack := {
342 dl_tfi := tfi,
343 ack_nack_desc := andesc,
344 chreq_desc_presence := '0'B,
345 chreq_desc := omit,
346 ch_qual_rep := c_ChQualRep_default
347 }
348 }
349 }
350 }
351 }
352
353 /* Template for uplink Data block */
Harald Welte060e27a2018-03-03 20:38:19 +0100354 template RlcmacUlBlock t_RLCMAC_UL_DATA(template uint5_t tfi, template uint4_t cv, template uint7_t bsn,
355 template LlcBlocks blocks := {}, template boolean stall := false) := {
356 data := {
357 mac_hdr := {
358 payload_type := MAC_PT_RLC_DATA,
359 countdown := cv,
360 stall_ind := false,
361 retry := false,
362 spare := '0'B,
363 pfi_ind := false,
364 tfi := tfi,
365 tlli_ind := false,
366 bsn := bsn,
367 e := false
368 },
369 tlli := omit,
370 pfi := omit,
371 blocks := blocks
372 }
373 }
374 template RlcmacUlBlock t_RLCMAC_UL_DATA_TLLI(template uint5_t tfi, template uint4_t cv, template uint7_t bsn,
375 template LlcBlocks blocks := {}, template boolean stall := false, template GprsTlli tlli) := {
376 data := {
377 mac_hdr := {
378 payload_type := MAC_PT_RLC_DATA,
379 countdown := cv,
380 stall_ind := false,
381 retry := false,
382 spare := '0'B,
383 pfi_ind := false,
384 tfi := tfi,
385 tlli_ind := true,
386 bsn := bsn,
387 e := false
388 },
389 tlli := tlli,
390 pfi := omit,
391 blocks := blocks
392 }
393 }
394
395 template DlMacHeader t_RLCMAC_DlMacH(template MacPayloadType pt, template MacRrbp rrbp, template
396uint3_t usf) := {
397 payload_type := pt,
398 rrbp := rrbp,
399 rrbp_valid := ispresent(rrbp),
400 usf := usf
401 }
402
Oliver Smith8f9daab2019-10-09 09:27:19 +0200403 template RlcmacDlBlock tr_RLCMAC_DUMMY_CTRL(template uint3_t usf := ?, template PageMode page_mode := ?) := {
Pau Espin Pedrol596faa42019-10-04 19:31:29 +0200404 ctrl := {
405 mac_hdr := {
406 payload_type := (MAC_PT_RLCMAC_NO_OPT, MAC_PT_RLCMAC_OPT),
407 rrbp:= ?,
408 rrbp_valid := ?,
409 usf := usf
410 },
411 opt := *,
412 payload := {
413 msg_type := PACKET_DL_DUMMY_CTRL,
414 u := {
415 dl_dummy := {
Oliver Smith8f9daab2019-10-09 09:27:19 +0200416 page_mode := page_mode,
Pau Espin Pedrol596faa42019-10-04 19:31:29 +0200417 persistence_levels_present := ?,
418 persistence_levels := *
419 }
420 }
421 }
422 }
423 }
424
Pau Espin Pedrolff8da192019-12-05 17:23:58 +0100425 template RlcmacDlBlock tr_RLCMAC_DL_PACKET_ASS(template uint3_t usf := ?) := {
426 ctrl := {
427 mac_hdr := {
428 payload_type := (MAC_PT_RLCMAC_NO_OPT, MAC_PT_RLCMAC_OPT),
429 rrbp:= ?,
430 rrbp_valid := ?,
431 usf := usf
432 },
433 opt := *,
434 payload := {
435 msg_type := PACKET_DL_ASSIGNMENT,
436 u := {
437 dl_assignment := {
438 page_mode := ?,
439 pres1 := ?,
440 persistence_levels := *,
441 tfi_or_tlli := ?
442 }
443 }
444 }
445 }
446 }
447
Pau Espin Pedrol21659632019-12-02 19:12:08 +0100448 /* Receive Template for Uplink ACK/NACK */
449 template RlcmacDlBlock tr_RLCMAC_UL_ACK_NACK(template uint5_t ul_tfi, template GprsTlli tlli := ?) := {
Harald Welte060e27a2018-03-03 20:38:19 +0100450 ctrl := {
451 mac_hdr := {
452 payload_type := (MAC_PT_RLCMAC_NO_OPT, MAC_PT_RLCMAC_OPT),
453 rrbp:= ?,
Vadim Yanitskiy0eb26622019-09-14 20:35:28 +0200454 rrbp_valid := ?,
Harald Welte060e27a2018-03-03 20:38:19 +0100455 usf := ?
456 },
457 opt := *,
458 payload := {
459 msg_type := PACKET_UL_ACK_NACK,
460 u := {
461 ul_ack_nack := {
462 page_mode := ?,
463 msg_excape := ?,
464 uplink_tfi := ul_tfi,
465 is_egprs := '0'B,
466 gprs := {
467 ch_coding_cmd := ?,
468 ack_nack_desc := ?,
469 cont_res_tlli_present := ?,
470 cont_res_tlli := tlli,
471 pkt_ta_present := ?,
472 pkt_ta := *,
473 pwr_ctrl_present := ?,
474 pwr_ctrl := *
475 }
476 }
477 }
478 }
479 }
480 }
481
Oliver Smith8f9daab2019-10-09 09:27:19 +0200482 template RlcmacDlBlock tr_RLCMAC_PACKET_PAG_REQ(template uint3_t usf := ?) := {
483 ctrl := {
484 mac_hdr := {
485 payload_type := MAC_PT_RLCMAC_NO_OPT,
486 rrbp:= ?,
487 rrbp_valid := ?,
488 usf := usf
489 },
490 opt := *,
491 payload := {
492 msg_type := PACKET_PAGING_REQUEST,
493 u := {
494 paging := {
495 page_mode := ?,
496 persistence_levels_present := ?,
497 persistence_levels := *,
498 nln_present := ?,
499 nln := *,
500 repeated_pageinfo_present := ?,
501 repeated_pageinfo := *
502 }
503 }
504 }
505 }
506 }
507
Harald Welteb669ee02018-03-09 12:50:02 +0100508 template RlcmacDlBlock tr_RLCMAC_DATA_RRBP := {
509 data := {
510 mac_hdr := {
511 mac_hdr := {
512 payload_type := MAC_PT_RLC_DATA,
513 rrbp := ?,
514 rrbp_valid := true,
515 usf := ?
516 },
517 hdr_ext := ?
518 },
519 blocks := ?
520 }
521 }
522
Harald Welte060e27a2018-03-03 20:38:19 +0100523 /* Template for Uplink MAC Control Header */
524 template UlMacCtrlHeader t_RLCMAC_UlMacCtrlH(template MacPayloadType pt, template boolean retry := false) := {
525 payload_type := pt,
526 spare := '00000'B,
527 retry := retry
528 }
529
Pau Espin Pedrol21659632019-12-02 19:12:08 +0100530 /* Template for Uplink Control ACK */
Harald Welte060e27a2018-03-03 20:38:19 +0100531 template RlcmacUlBlock ts_RLCMAC_CTRL_ACK(GprsTlli tlli, CtrlAck ack := MS_RCVD_TWO_RLC_SAME_RTI_DIFF_RBSN) := {
532 ctrl := {
533 mac_hdr := t_RLCMAC_UlMacCtrlH(MAC_PT_RLCMAC_NO_OPT),
534 payload := {
535 msg_type := PACKET_CONTROL_ACK,
536 u := {
537 ctrl_ack := {
538 tlli := tlli,
539 ctrl_ack := ack
540 }
541 }
542 }
543 }
544 }
545
546 /* Template for a LlcBlock (part of a LLC frame inside RlcMac?lDataBlock */
547 template LlcBlock t_RLCMAC_LLCBLOCK(octetstring data, boolean more := false, boolean e := true) := {
548 /* let encoder figure out the header */
549 hdr := omit,
550 payload := data
551 }
552
Vadim Yanitskiy1bd8ec52019-10-01 05:44:52 +0700553 /* PTCCH/D (Packet Timing Advance Control Channel) message.
554 * TODO: add a spec. reference to the message format definition. */
555 type record PTCCHTimingAdvanceIE {
556 BIT1 spare ('0'B),
557 uint7_t ta_val
558 } with { variant "" };
559 type record of PTCCHTimingAdvanceIE PTCCHTimingAdvanceIEs;
560 type record PTCCHDownlinkMsg {
561 PTCCHTimingAdvanceIEs ta_idx length(16),
562 octetstring padding length(7)
563 } with { variant "" };
564
565 external function enc_PTCCHDownlinkMsg(in PTCCHDownlinkMsg si) return octetstring
566 with { extension "prototype(convert) encode(RAW)" };
567 external function dec_PTCCHDownlinkMsg(in octetstring stream) return PTCCHDownlinkMsg
568 with { extension "prototype(convert) decode(RAW)" };
569
570 template PTCCHDownlinkMsg tr_PTCCHDownlinkMsg(
571 template (present) uint7_t tai0_ta := ?,
572 template (present) uint7_t tai1_ta := ?,
573 template (present) uint7_t tai2_ta := ?,
574 template (present) uint7_t tai3_ta := ?,
575 template (present) uint7_t tai4_ta := ?,
576 template (present) uint7_t tai5_ta := ?,
577 template (present) uint7_t tai6_ta := ?,
578 template (present) uint7_t tai7_ta := ?,
579 template (present) uint7_t tai8_ta := ?,
580 template (present) uint7_t tai9_ta := ?,
581 template (present) uint7_t tai10_ta := ?,
582 template (present) uint7_t tai11_ta := ?,
583 template (present) uint7_t tai12_ta := ?,
584 template (present) uint7_t tai13_ta := ?,
585 template (present) uint7_t tai14_ta := ?,
586 template (present) uint7_t tai15_ta := ?
587 ) := {
588 ta_idx := {
589 { spare := '0'B, ta_val := tai0_ta },
590 { spare := '0'B, ta_val := tai1_ta },
591 { spare := '0'B, ta_val := tai2_ta },
592 { spare := '0'B, ta_val := tai3_ta },
593 { spare := '0'B, ta_val := tai4_ta },
594 { spare := '0'B, ta_val := tai5_ta },
595 { spare := '0'B, ta_val := tai6_ta },
596 { spare := '0'B, ta_val := tai7_ta },
597 { spare := '0'B, ta_val := tai8_ta },
598 { spare := '0'B, ta_val := tai9_ta },
599 { spare := '0'B, ta_val := tai10_ta },
600 { spare := '0'B, ta_val := tai11_ta },
601 { spare := '0'B, ta_val := tai12_ta },
602 { spare := '0'B, ta_val := tai13_ta },
603 { spare := '0'B, ta_val := tai14_ta },
604 { spare := '0'B, ta_val := tai15_ta }
605 },
606 padding := '2B2B2B2B2B2B2B'O
607 }
608
Harald Welte060e27a2018-03-03 20:38:19 +0100609
Harald Welte484160b2017-07-28 13:30:24 +0200610} with { encode "RAW"; variant "FIELDORDER(msb)" }