blob: 8e6942e615a359895dd346ae74428ea4ff494e92 [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
34 /* Partof DL RLC data block and DL RLC/MAC ctrl block */
35 type record DlMacHeader {
36 MacPayloadType payload_type,
37 MacRrbp rrbp,
38 boolean rrbp_valid,
39 uint3_t usf
40 } with {
41 variant (rrbp_valid) "FIELDLENGTH(1)"
42 };
43
44 /* TS 44.060 10.4.10a */
45 type enumerated PowerReduction {
46 PWR_RED_0_to_3dB ('00'B),
47 PWR_RED_3_to_7dB ('01'B),
48 PWR_RED_7_to_10dB ('10'B),
49 PWR_RED_RESERVED ('11'B)
50 } with { variant "FIELDLENGTH(2)" };
51
52 /* TS 44.060 10.4.9d */
53 type enumerated DirectionBit {
54 DIR_UPLINK_TBF ('0'B),
55 DIR_DOWNLINK_TBF ('1'B)
56 } with { variant "FIELDLENGTH(1)" };
57
58 type record TfiOctet {
59 /* PR, TFI, D */
60 PowerReduction pr,
61 uint5_t tfi,
62 DirectionBit d
63 } with { variant "" };
64
65 type record RbsnExtOctet {
66 uint3_t rbsn_e,
67 BIT1 fs_e,
68 BIT4 spare
69 } with { variant "" };
70
71 type record DlCtrlOptOctets {
72 /* RBSN, RTI, FS, AC (optional, depending on mac_hdr.payload_type) */
73 BIT1 rbsn,
74 uint5_t rti,
75 boolean fs,
76 boolean tfi_octet_present,
77 TfiOctet tfi optional,
78 RbsnExtOctet rbsn_ext optional
79 } with {
80 variant (fs) "FIELDLENGTH(1)"
81 variant (tfi_octet_present) "FIELDLENGTH(1)"
82 variant (tfi) "PRESENCE(tfi_octet_present = true)"
83 variant (rbsn_ext) "PRESENCE(rbsn='1'B, fs=false)"
84 };
85
86 /* TS 44.060 10.3.1 Downlink RLC/MAC control block */
87 type record RlcmacDlCtrlBlock {
88 DlMacHeader mac_hdr,
89 DlCtrlOptOctets opt optional,
Harald Welte9d348522017-08-01 00:27:39 +020090 RlcmacDlCtrlMsg payload
Harald Welte484160b2017-07-28 13:30:24 +020091 } with {
92 variant (opt) "PRESENCE(mac_hdr.payload_type = MAC_PT_RLCMAC_OPT)"
93 };
94
95 external function enc_RlcmacDlCtrlBlock(in RlcmacDlCtrlBlock si) return octetstring
96 with { extension "prototype(convert) encode(RAW)" };
97 external function dec_RlcmacDlCtrlBlock(in octetstring stream) return RlcmacDlCtrlBlock
98 with { extension "prototype(convert) decode(RAW)" };
99
100 type record UlMacCtrlHeader {
Harald Welteefbc2fc2017-07-31 00:05:23 +0200101 MacPayloadType payload_type,
Harald Welte484160b2017-07-28 13:30:24 +0200102 BIT5 spare,
103 boolean retry
104 } with { variant (retry) "FIELDLENGTH(1)" };
105
106 /* TS 44.060 10.3.2 UplinkRLC/MAC control block */
107 type record RlcmacUlCtrlBlock {
108 UlMacCtrlHeader mac_hdr,
Harald Welte9d348522017-08-01 00:27:39 +0200109 RlcmacUlCtrlMsg payload
Harald Welte484160b2017-07-28 13:30:24 +0200110 } with { variant "" };
111
112 external function enc_RlcmacUlCtrlBlock(in RlcmacUlCtrlBlock si) return octetstring
113 with { extension "prototype(convert) encode(RAW)" };
114 external function dec_RlcmacUlCtrlBlock(in octetstring stream) return RlcmacUlCtrlBlock
115 with { extension "prototype(convert) decode(RAW)" };
116
117 /* a single RLC block / LLC-segment */
Harald Welte43e060a2017-07-30 22:38:03 +0200118 type record LlcBlockHdr {
Harald Welte484160b2017-07-28 13:30:24 +0200119 uint6_t length_ind,
120 /* 1 = new LLC PDU starts */
Harald Welte060e27a2018-03-03 20:38:19 +0100121 boolean more,
Harald Welte484160b2017-07-28 13:30:24 +0200122 /* 0 = another extension octet after LLC PDU, 1 = no more extension octets */
Harald Welte43e060a2017-07-30 22:38:03 +0200123 boolean e
Harald Welte484160b2017-07-28 13:30:24 +0200124 } with {
Harald Welte43e060a2017-07-30 22:38:03 +0200125 variant (e) "FIELDLENGTH(1)"
Harald Weltecc5c1152018-03-09 12:54:01 +0100126 encode "RAW"
Harald Welte484160b2017-07-28 13:30:24 +0200127 };
Harald Weltecc5c1152018-03-09 12:54:01 +0100128
129 external function enc_LlcBlockHdr(in LlcBlockHdr si) return octetstring
130 with { extension "prototype(convert) encode(RAW)" };
131 external function dec_LlcBlockHdr(in octetstring stream) return LlcBlockHdr
132 with { extension "prototype(convert) decode(RAW)" };
133
Harald Welte43e060a2017-07-30 22:38:03 +0200134 type record LlcBlock {
135 /* Header is only present if LI field was present */
Harald Welte060e27a2018-03-03 20:38:19 +0100136 LlcBlockHdr hdr optional,
Harald Welte43e060a2017-07-30 22:38:03 +0200137 octetstring payload
138 } with { variant "" };
139 type record of LlcBlock LlcBlocks;
Harald Welte484160b2017-07-28 13:30:24 +0200140
141 /* TS 44.060 10.2.1 Downlink RLC data block */
Harald Welte43e060a2017-07-30 22:38:03 +0200142 type record DlMacHdrDataExt {
Harald Welte484160b2017-07-28 13:30:24 +0200143 /* Octet 1 */
Harald Welte484160b2017-07-28 13:30:24 +0200144 PowerReduction pr,
145 BIT1 spare,
146 uint4_t tfi, /* 3 or 4? */
147 boolean fbi,
Harald Welte43e060a2017-07-30 22:38:03 +0200148 /* Octet 2 */
Harald Welte484160b2017-07-28 13:30:24 +0200149 uint7_t bsn,
Harald Welte43e060a2017-07-30 22:38:03 +0200150 boolean e
151 } with {
152 variant (e) "FIELDLENGTH(1)"
153 };
154 type record DlMacDataHeader {
155 DlMacHeader mac_hdr,
156 DlMacHdrDataExt hdr_ext
Harald Welte484160b2017-07-28 13:30:24 +0200157 } with { variant "" };
Harald Welte43e060a2017-07-30 22:38:03 +0200158 type record RlcmacDlDataBlock {
159 DlMacDataHeader mac_hdr,
160 /* Octet 3..M / N: manual C++ Decoder */
161 LlcBlocks blocks
162 } with {
163 variant ""
164 };
Harald Welte484160b2017-07-28 13:30:24 +0200165
Harald Welte43e060a2017-07-30 22:38:03 +0200166 external function enc_RlcmacDlDataBlock(in RlcmacDlDataBlock si) return octetstring;
167 external function dec_RlcmacDlDataBlock(in octetstring stream) return RlcmacDlDataBlock;
Harald Welte484160b2017-07-28 13:30:24 +0200168
169
170 /* TS 44.060 10.2.2 */
171 type record UlMacDataHeader {
Harald Welte43e060a2017-07-30 22:38:03 +0200172 /* Octet 0 */
Harald Welteefbc2fc2017-07-31 00:05:23 +0200173 MacPayloadType payload_type,
Harald Welte484160b2017-07-28 13:30:24 +0200174 uint4_t countdown,
175 boolean stall_ind,
Harald Welte43e060a2017-07-30 22:38:03 +0200176 boolean retry,
177 /* Octet 1 */
178 BIT1 spare,
179 boolean pfi_ind,
180 uint5_t tfi,
181 boolean tlli_ind,
182 /* Octet 2 */
183 uint7_t bsn,
184 boolean e
Harald Welte484160b2017-07-28 13:30:24 +0200185 } with {
Harald Welte43e060a2017-07-30 22:38:03 +0200186 variant (stall_ind) "FIELDLENGTH(1)"
187 variant (retry) "FIELDLENGTH(1)"
188 variant (pfi_ind) "FIELDLENGTH(1)"
189 variant (tlli_ind) "FIELDLENGTH(1)"
190 variant (e) "FIELDLENGTH(1)"
Harald Welte484160b2017-07-28 13:30:24 +0200191 };
192
Harald Welte484160b2017-07-28 13:30:24 +0200193 type record RlcMacUlPfi {
194 uint7_t pfi,
195 boolean m
196 } with {
197 variant (m) "FIELDLENGTH(1)"
198 };
199
200 /* TS 44.060 10.2.2 */
201 type record RlcmacUlDataBlock {
202 /* MAC header */
203 UlMacDataHeader mac_hdr,
Harald Welte43e060a2017-07-30 22:38:03 +0200204 /* Octet 3 ... M (optional): manual C++ Decoder */
205 GprsTlli tlli optional,
206 RlcMacUlPfi pfi optional,
207 LlcBlocks blocks
Harald Welte484160b2017-07-28 13:30:24 +0200208 } with {
Harald Welte43e060a2017-07-30 22:38:03 +0200209 variant (tlli) "PRESENCE(mac_hdr.tlli_ind = true)"
210 variant (pfi) "PRESENCE(mac_hdr.pfi_ind = true)"
Harald Welte484160b2017-07-28 13:30:24 +0200211 };
212
Harald Welte43e060a2017-07-30 22:38:03 +0200213 external function enc_RlcmacUlDataBlock(in RlcmacUlDataBlock si) return octetstring;
214 external function dec_RlcmacUlDataBlock(in octetstring stream) return RlcmacUlDataBlock;
Harald Welte484160b2017-07-28 13:30:24 +0200215
Harald Welteefbc2fc2017-07-31 00:05:23 +0200216 type union RlcmacUlBlock {
217 RlcmacUlDataBlock data,
218 RlcmacUlCtrlBlock ctrl
219 } with {
220 variant "TAG(data, mac_hdr.payload_type = MAC_PT_RLC_DATA;
221 ctrl, mac_hdr.payload_type = MAC_PT_RLCMAC_NO_OPT;
222 ctrl, mac_hdr.payload_type = MAC_PT_RLCMAC_OPT)"
223 };
224
Harald Welte78a1af62017-07-31 17:33:56 +0200225 /* as the sub-types (RlcmacDl*Block) are not using the RAW coder, we cannot
226 * use auto-generated functions here, as they would decode those sub-types
227 * based on the RAW coder, not baed on the manual C++ functions */
228 external function enc_RlcmacUlBlock(in RlcmacUlBlock si) return octetstring;
229 external function dec_RlcmacUlBlock(in octetstring stream) return RlcmacUlBlock;
Harald Welteefbc2fc2017-07-31 00:05:23 +0200230
231 type union RlcmacDlBlock {
232 RlcmacDlDataBlock data,
233 RlcmacDlCtrlBlock ctrl
234 } with {
235 variant "TAG(data, mac_hdr.mac_hdr.payload_type = MAC_PT_RLC_DATA;
236 ctrl, mac_hdr.payload_type = MAC_PT_RLCMAC_NO_OPT;
237 ctrl, mac_hdr.payload_type = MAC_PT_RLCMAC_OPT)"
238 };
239
Harald Welte78a1af62017-07-31 17:33:56 +0200240 /* as the sub-types (RlcmacDl*Block) are not using the RAW coder, we cannot
241 * use auto-generated functions here, as they would decode those sub-types
242 * based on the RAW coder, not baed on the manual C++ functions */
243 external function enc_RlcmacDlBlock(in RlcmacDlBlock si) return octetstring;
244 external function dec_RlcmacDlBlock(in octetstring stream) return RlcmacDlBlock;
Harald Welteefbc2fc2017-07-31 00:05:23 +0200245
Harald Welte7024baa2018-03-02 23:37:51 +0100246 template (value) RlcmacUlBlock ts_RLC_UL_CTRL_ACK(RlcmacUlCtrlMsg ctrl,
247 MacPayloadType pt := MAC_PT_RLCMAC_NO_OPT,
248 boolean retry := false) := {
249 ctrl := {
250 mac_hdr := {
251 payload_type := pt,
252 spare := '00000'B,
253 retry := retry
254 },
255 payload := ctrl
256 }
257 }
258
Pau Espin Pedrola3f0a852019-12-02 19:16:26 +0100259 /* Send Template for Downlink ACK/NACK */
260 template RlcmacUlBlock ts_RLCMAC_DL_ACK_NACK(template uint5_t tfi, AckNackDescription andesc, boolean retry := false) := {
261 ctrl := {
262 mac_hdr := {
263 payload_type := MAC_PT_RLCMAC_NO_OPT,
264 spare := '00000'B,
265 retry := retry
266 },
267 payload := {
268 msg_type := PACKET_DL_ACK_NACK,
269 u := {
270 dl_ack_nack := {
271 dl_tfi := tfi,
272 ack_nack_desc := andesc,
273 chreq_desc_presence := '0'B,
274 chreq_desc := omit,
275 ch_qual_rep := c_ChQualRep_default
276 }
277 }
278 }
279 }
280 }
281
282 /* Template for uplink Data block */
Harald Welte060e27a2018-03-03 20:38:19 +0100283 template RlcmacUlBlock t_RLCMAC_UL_DATA(template uint5_t tfi, template uint4_t cv, template uint7_t bsn,
284 template LlcBlocks blocks := {}, template boolean stall := false) := {
285 data := {
286 mac_hdr := {
287 payload_type := MAC_PT_RLC_DATA,
288 countdown := cv,
289 stall_ind := false,
290 retry := false,
291 spare := '0'B,
292 pfi_ind := false,
293 tfi := tfi,
294 tlli_ind := false,
295 bsn := bsn,
296 e := false
297 },
298 tlli := omit,
299 pfi := omit,
300 blocks := blocks
301 }
302 }
303 template RlcmacUlBlock t_RLCMAC_UL_DATA_TLLI(template uint5_t tfi, template uint4_t cv, template uint7_t bsn,
304 template LlcBlocks blocks := {}, template boolean stall := false, template GprsTlli tlli) := {
305 data := {
306 mac_hdr := {
307 payload_type := MAC_PT_RLC_DATA,
308 countdown := cv,
309 stall_ind := false,
310 retry := false,
311 spare := '0'B,
312 pfi_ind := false,
313 tfi := tfi,
314 tlli_ind := true,
315 bsn := bsn,
316 e := false
317 },
318 tlli := tlli,
319 pfi := omit,
320 blocks := blocks
321 }
322 }
323
324 template DlMacHeader t_RLCMAC_DlMacH(template MacPayloadType pt, template MacRrbp rrbp, template
325uint3_t usf) := {
326 payload_type := pt,
327 rrbp := rrbp,
328 rrbp_valid := ispresent(rrbp),
329 usf := usf
330 }
331
Pau Espin Pedrol596faa42019-10-04 19:31:29 +0200332 template RlcmacDlBlock tr_RLCMAC_DUMMY_CTRL(template uint3_t usf := ?) := {
333 ctrl := {
334 mac_hdr := {
335 payload_type := (MAC_PT_RLCMAC_NO_OPT, MAC_PT_RLCMAC_OPT),
336 rrbp:= ?,
337 rrbp_valid := ?,
338 usf := usf
339 },
340 opt := *,
341 payload := {
342 msg_type := PACKET_DL_DUMMY_CTRL,
343 u := {
344 dl_dummy := {
345 page_mode := ?,
346 persistence_levels_present := ?,
347 persistence_levels := *
348 }
349 }
350 }
351 }
352 }
353
Pau Espin Pedrol21659632019-12-02 19:12:08 +0100354 /* Receive Template for Uplink ACK/NACK */
355 template RlcmacDlBlock tr_RLCMAC_UL_ACK_NACK(template uint5_t ul_tfi, template GprsTlli tlli := ?) := {
Harald Welte060e27a2018-03-03 20:38:19 +0100356 ctrl := {
357 mac_hdr := {
358 payload_type := (MAC_PT_RLCMAC_NO_OPT, MAC_PT_RLCMAC_OPT),
359 rrbp:= ?,
Vadim Yanitskiy0eb26622019-09-14 20:35:28 +0200360 rrbp_valid := ?,
Harald Welte060e27a2018-03-03 20:38:19 +0100361 usf := ?
362 },
363 opt := *,
364 payload := {
365 msg_type := PACKET_UL_ACK_NACK,
366 u := {
367 ul_ack_nack := {
368 page_mode := ?,
369 msg_excape := ?,
370 uplink_tfi := ul_tfi,
371 is_egprs := '0'B,
372 gprs := {
373 ch_coding_cmd := ?,
374 ack_nack_desc := ?,
375 cont_res_tlli_present := ?,
376 cont_res_tlli := tlli,
377 pkt_ta_present := ?,
378 pkt_ta := *,
379 pwr_ctrl_present := ?,
380 pwr_ctrl := *
381 }
382 }
383 }
384 }
385 }
386 }
387
Harald Welteb669ee02018-03-09 12:50:02 +0100388 template RlcmacDlBlock tr_RLCMAC_DATA_RRBP := {
389 data := {
390 mac_hdr := {
391 mac_hdr := {
392 payload_type := MAC_PT_RLC_DATA,
393 rrbp := ?,
394 rrbp_valid := true,
395 usf := ?
396 },
397 hdr_ext := ?
398 },
399 blocks := ?
400 }
401 }
402
Harald Welte060e27a2018-03-03 20:38:19 +0100403 /* Template for Uplink MAC Control Header */
404 template UlMacCtrlHeader t_RLCMAC_UlMacCtrlH(template MacPayloadType pt, template boolean retry := false) := {
405 payload_type := pt,
406 spare := '00000'B,
407 retry := retry
408 }
409
Pau Espin Pedrol21659632019-12-02 19:12:08 +0100410 /* Template for Uplink Control ACK */
Harald Welte060e27a2018-03-03 20:38:19 +0100411 template RlcmacUlBlock ts_RLCMAC_CTRL_ACK(GprsTlli tlli, CtrlAck ack := MS_RCVD_TWO_RLC_SAME_RTI_DIFF_RBSN) := {
412 ctrl := {
413 mac_hdr := t_RLCMAC_UlMacCtrlH(MAC_PT_RLCMAC_NO_OPT),
414 payload := {
415 msg_type := PACKET_CONTROL_ACK,
416 u := {
417 ctrl_ack := {
418 tlli := tlli,
419 ctrl_ack := ack
420 }
421 }
422 }
423 }
424 }
425
426 /* Template for a LlcBlock (part of a LLC frame inside RlcMac?lDataBlock */
427 template LlcBlock t_RLCMAC_LLCBLOCK(octetstring data, boolean more := false, boolean e := true) := {
428 /* let encoder figure out the header */
429 hdr := omit,
430 payload := data
431 }
432
Vadim Yanitskiy1bd8ec52019-10-01 05:44:52 +0700433 /* PTCCH/D (Packet Timing Advance Control Channel) message.
434 * TODO: add a spec. reference to the message format definition. */
435 type record PTCCHTimingAdvanceIE {
436 BIT1 spare ('0'B),
437 uint7_t ta_val
438 } with { variant "" };
439 type record of PTCCHTimingAdvanceIE PTCCHTimingAdvanceIEs;
440 type record PTCCHDownlinkMsg {
441 PTCCHTimingAdvanceIEs ta_idx length(16),
442 octetstring padding length(7)
443 } with { variant "" };
444
445 external function enc_PTCCHDownlinkMsg(in PTCCHDownlinkMsg si) return octetstring
446 with { extension "prototype(convert) encode(RAW)" };
447 external function dec_PTCCHDownlinkMsg(in octetstring stream) return PTCCHDownlinkMsg
448 with { extension "prototype(convert) decode(RAW)" };
449
450 template PTCCHDownlinkMsg tr_PTCCHDownlinkMsg(
451 template (present) uint7_t tai0_ta := ?,
452 template (present) uint7_t tai1_ta := ?,
453 template (present) uint7_t tai2_ta := ?,
454 template (present) uint7_t tai3_ta := ?,
455 template (present) uint7_t tai4_ta := ?,
456 template (present) uint7_t tai5_ta := ?,
457 template (present) uint7_t tai6_ta := ?,
458 template (present) uint7_t tai7_ta := ?,
459 template (present) uint7_t tai8_ta := ?,
460 template (present) uint7_t tai9_ta := ?,
461 template (present) uint7_t tai10_ta := ?,
462 template (present) uint7_t tai11_ta := ?,
463 template (present) uint7_t tai12_ta := ?,
464 template (present) uint7_t tai13_ta := ?,
465 template (present) uint7_t tai14_ta := ?,
466 template (present) uint7_t tai15_ta := ?
467 ) := {
468 ta_idx := {
469 { spare := '0'B, ta_val := tai0_ta },
470 { spare := '0'B, ta_val := tai1_ta },
471 { spare := '0'B, ta_val := tai2_ta },
472 { spare := '0'B, ta_val := tai3_ta },
473 { spare := '0'B, ta_val := tai4_ta },
474 { spare := '0'B, ta_val := tai5_ta },
475 { spare := '0'B, ta_val := tai6_ta },
476 { spare := '0'B, ta_val := tai7_ta },
477 { spare := '0'B, ta_val := tai8_ta },
478 { spare := '0'B, ta_val := tai9_ta },
479 { spare := '0'B, ta_val := tai10_ta },
480 { spare := '0'B, ta_val := tai11_ta },
481 { spare := '0'B, ta_val := tai12_ta },
482 { spare := '0'B, ta_val := tai13_ta },
483 { spare := '0'B, ta_val := tai14_ta },
484 { spare := '0'B, ta_val := tai15_ta }
485 },
486 padding := '2B2B2B2B2B2B2B'O
487 }
488
Harald Welte060e27a2018-03-03 20:38:19 +0100489
Harald Welte484160b2017-07-28 13:30:24 +0200490} with { encode "RAW"; variant "FIELDORDER(msb)" }