blob: eb9d8455a21f0b11bead5b25b19b99017c9aa49f [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 Pedrol372af7a2020-04-27 17:32:01 +020034 type enumerated EgprsHeaderType {
35 RLCMAC_HDR_TYPE_1,
36 RLCMAC_HDR_TYPE_2,
37 RLCMAC_HDR_TYPE_3
38 };
39
Pau Espin Pedroldc9666f2020-03-18 20:30:16 +010040 type enumerated CodingScheme {
41 CS_1,
42 CS_2,
43 CS_3,
44 CS_4,
Pau Espin Pedrol372af7a2020-04-27 17:32:01 +020045 MCS_0,
Pau Espin Pedroldc9666f2020-03-18 20:30:16 +010046 MCS_1,
47 MCS_2,
48 MCS_3,
49 MCS_4,
50 MCS_5,
51 MCS_6,
52 MCS_7,
53 MCS_8,
54 MCS_9
55 //MCS5_7, ?
56 // MCS6_9 ?
57 };
Pau Espin Pedrol27d6af52020-04-30 20:13:32 +020058 type record of CodingScheme CodingSchemeArray;
Pau Espin Pedroldc9666f2020-03-18 20:30:16 +010059
Harald Welte484160b2017-07-28 13:30:24 +020060 /* Partof DL RLC data block and DL RLC/MAC ctrl block */
61 type record DlMacHeader {
62 MacPayloadType payload_type,
63 MacRrbp rrbp,
64 boolean rrbp_valid,
65 uint3_t usf
66 } with {
67 variant (rrbp_valid) "FIELDLENGTH(1)"
68 };
69
70 /* TS 44.060 10.4.10a */
71 type enumerated PowerReduction {
72 PWR_RED_0_to_3dB ('00'B),
73 PWR_RED_3_to_7dB ('01'B),
74 PWR_RED_7_to_10dB ('10'B),
75 PWR_RED_RESERVED ('11'B)
76 } with { variant "FIELDLENGTH(2)" };
77
78 /* TS 44.060 10.4.9d */
79 type enumerated DirectionBit {
80 DIR_UPLINK_TBF ('0'B),
81 DIR_DOWNLINK_TBF ('1'B)
82 } with { variant "FIELDLENGTH(1)" };
83
84 type record TfiOctet {
85 /* PR, TFI, D */
86 PowerReduction pr,
87 uint5_t tfi,
88 DirectionBit d
89 } with { variant "" };
90
91 type record RbsnExtOctet {
92 uint3_t rbsn_e,
93 BIT1 fs_e,
94 BIT4 spare
95 } with { variant "" };
96
97 type record DlCtrlOptOctets {
98 /* RBSN, RTI, FS, AC (optional, depending on mac_hdr.payload_type) */
99 BIT1 rbsn,
100 uint5_t rti,
101 boolean fs,
102 boolean tfi_octet_present,
103 TfiOctet tfi optional,
104 RbsnExtOctet rbsn_ext optional
105 } with {
106 variant (fs) "FIELDLENGTH(1)"
107 variant (tfi_octet_present) "FIELDLENGTH(1)"
108 variant (tfi) "PRESENCE(tfi_octet_present = true)"
109 variant (rbsn_ext) "PRESENCE(rbsn='1'B, fs=false)"
110 };
111
112 /* TS 44.060 10.3.1 Downlink RLC/MAC control block */
113 type record RlcmacDlCtrlBlock {
114 DlMacHeader mac_hdr,
115 DlCtrlOptOctets opt optional,
Harald Welte9d348522017-08-01 00:27:39 +0200116 RlcmacDlCtrlMsg payload
Harald Welte484160b2017-07-28 13:30:24 +0200117 } with {
118 variant (opt) "PRESENCE(mac_hdr.payload_type = MAC_PT_RLCMAC_OPT)"
119 };
120
121 external function enc_RlcmacDlCtrlBlock(in RlcmacDlCtrlBlock si) return octetstring
122 with { extension "prototype(convert) encode(RAW)" };
123 external function dec_RlcmacDlCtrlBlock(in octetstring stream) return RlcmacDlCtrlBlock
124 with { extension "prototype(convert) decode(RAW)" };
125
126 type record UlMacCtrlHeader {
Harald Welteefbc2fc2017-07-31 00:05:23 +0200127 MacPayloadType payload_type,
Harald Welte484160b2017-07-28 13:30:24 +0200128 BIT5 spare,
129 boolean retry
130 } with { variant (retry) "FIELDLENGTH(1)" };
131
132 /* TS 44.060 10.3.2 UplinkRLC/MAC control block */
133 type record RlcmacUlCtrlBlock {
134 UlMacCtrlHeader mac_hdr,
Harald Welte9d348522017-08-01 00:27:39 +0200135 RlcmacUlCtrlMsg payload
Harald Welte484160b2017-07-28 13:30:24 +0200136 } with { variant "" };
137
138 external function enc_RlcmacUlCtrlBlock(in RlcmacUlCtrlBlock si) return octetstring
139 with { extension "prototype(convert) encode(RAW)" };
140 external function dec_RlcmacUlCtrlBlock(in octetstring stream) return RlcmacUlCtrlBlock
141 with { extension "prototype(convert) decode(RAW)" };
142
143 /* a single RLC block / LLC-segment */
Harald Welte43e060a2017-07-30 22:38:03 +0200144 type record LlcBlockHdr {
Harald Welte484160b2017-07-28 13:30:24 +0200145 uint6_t length_ind,
146 /* 1 = new LLC PDU starts */
Harald Welte060e27a2018-03-03 20:38:19 +0100147 boolean more,
Harald Welte484160b2017-07-28 13:30:24 +0200148 /* 0 = another extension octet after LLC PDU, 1 = no more extension octets */
Harald Welte43e060a2017-07-30 22:38:03 +0200149 boolean e
Harald Welte484160b2017-07-28 13:30:24 +0200150 } with {
Harald Welte43e060a2017-07-30 22:38:03 +0200151 variant (e) "FIELDLENGTH(1)"
Harald Weltecc5c1152018-03-09 12:54:01 +0100152 encode "RAW"
Harald Welte484160b2017-07-28 13:30:24 +0200153 };
Harald Weltecc5c1152018-03-09 12:54:01 +0100154
155 external function enc_LlcBlockHdr(in LlcBlockHdr si) return octetstring
156 with { extension "prototype(convert) encode(RAW)" };
157 external function dec_LlcBlockHdr(in octetstring stream) return LlcBlockHdr
158 with { extension "prototype(convert) decode(RAW)" };
159
Harald Welte43e060a2017-07-30 22:38:03 +0200160 type record LlcBlock {
161 /* Header is only present if LI field was present */
Harald Welte060e27a2018-03-03 20:38:19 +0100162 LlcBlockHdr hdr optional,
Harald Welte43e060a2017-07-30 22:38:03 +0200163 octetstring payload
164 } with { variant "" };
165 type record of LlcBlock LlcBlocks;
Harald Welte484160b2017-07-28 13:30:24 +0200166
167 /* TS 44.060 10.2.1 Downlink RLC data block */
Harald Welte43e060a2017-07-30 22:38:03 +0200168 type record DlMacHdrDataExt {
Harald Welte484160b2017-07-28 13:30:24 +0200169 /* Octet 1 */
Harald Welte484160b2017-07-28 13:30:24 +0200170 PowerReduction pr,
171 BIT1 spare,
172 uint4_t tfi, /* 3 or 4? */
173 boolean fbi,
Harald Welte43e060a2017-07-30 22:38:03 +0200174 /* Octet 2 */
Harald Welte484160b2017-07-28 13:30:24 +0200175 uint7_t bsn,
Harald Welte43e060a2017-07-30 22:38:03 +0200176 boolean e
177 } with {
178 variant (e) "FIELDLENGTH(1)"
179 };
180 type record DlMacDataHeader {
181 DlMacHeader mac_hdr,
182 DlMacHdrDataExt hdr_ext
Harald Welte484160b2017-07-28 13:30:24 +0200183 } with { variant "" };
Harald Welte43e060a2017-07-30 22:38:03 +0200184 type record RlcmacDlDataBlock {
Pau Espin Pedrol5abfded2020-11-03 17:30:44 +0100185 CodingScheme cs, /* Provided by C++ Decoder */
Harald Welte43e060a2017-07-30 22:38:03 +0200186 DlMacDataHeader mac_hdr,
187 /* Octet 3..M / N: manual C++ Decoder */
188 LlcBlocks blocks
189 } with {
190 variant ""
191 };
Harald Welte484160b2017-07-28 13:30:24 +0200192
Harald Welte43e060a2017-07-30 22:38:03 +0200193 external function enc_RlcmacDlDataBlock(in RlcmacDlDataBlock si) return octetstring;
194 external function dec_RlcmacDlDataBlock(in octetstring stream) return RlcmacDlDataBlock;
Harald Welte484160b2017-07-28 13:30:24 +0200195
196
Pau Espin Pedrol372af7a2020-04-27 17:32:01 +0200197 /* a single RLC block / LLC-segment */
198 type record EgprsLlcBlockHdr {
199 uint7_t length_ind,
200 /* 0 = another extension octet after LLC PDU, 1 = no more extension octets */
201 boolean e
202 } with {
203 variant (e) "FIELDLENGTH(1)"
204 encode "RAW"
205 };
206
207 external function enc_EgprsLlcBlockHdr(in EgprsLlcBlockHdr si) return octetstring
208 with { extension "prototype(convert) encode(RAW)" };
209 external function dec_EgprsLlcBlockHdr(in octetstring stream) return EgprsLlcBlockHdr
210 with { extension "prototype(convert) decode(RAW)" };
211
212 type record EgprsLlcBlock {
213 /* Header is only present if LI field was present */
214 EgprsLlcBlockHdr hdr optional,
215 octetstring payload
216 } with { variant "" };
217 type record of EgprsLlcBlock EgprsLlcBlocks;
218
219 /* TS 44.060 10.3a.1.1 EGPRS downlink RLC data block, manual c++ encoder/decoder */
220 type record EgprsDlMacDataHeader {
221 EgprsHeaderType header_type, /* Set internally by decoder */
222 uint5_t tfi,
223 MacRrbp rrbp,
224 BIT2 esp,
225 uint3_t usf,
Pau Espin Pedrol081b1682020-11-06 17:15:52 +0100226 uint11_t bsn1,
Pau Espin Pedrol372af7a2020-04-27 17:32:01 +0200227 uint8_t bsn2_offset,
228 uint2_t pr, /* power reduction */
229 uint2_t spb,
230 uint4_t cps
231 } with { variant "" };
232 /* Manual C++ Decoder: */
233 type record RlcmacDlEgprsDataBlock {
Pau Espin Pedrol5abfded2020-11-03 17:30:44 +0100234 CodingScheme mcs, /* Provided by C++ Decoder */
Pau Espin Pedrol372af7a2020-04-27 17:32:01 +0200235 EgprsDlMacDataHeader mac_hdr,
236 boolean fbi,
237 boolean e,
238 EgprsLlcBlocks blocks
239 } with {
240 variant (fbi) "FIELDLENGTH(1)"
241 variant (e) "FIELDLENGTH(1)"
242 };
243
Harald Welte484160b2017-07-28 13:30:24 +0200244 /* TS 44.060 10.2.2 */
245 type record UlMacDataHeader {
Harald Welte43e060a2017-07-30 22:38:03 +0200246 /* Octet 0 */
Harald Welteefbc2fc2017-07-31 00:05:23 +0200247 MacPayloadType payload_type,
Harald Welte484160b2017-07-28 13:30:24 +0200248 uint4_t countdown,
249 boolean stall_ind,
Harald Welte43e060a2017-07-30 22:38:03 +0200250 boolean retry,
251 /* Octet 1 */
252 BIT1 spare,
253 boolean pfi_ind,
254 uint5_t tfi,
255 boolean tlli_ind,
256 /* Octet 2 */
257 uint7_t bsn,
258 boolean e
Harald Welte484160b2017-07-28 13:30:24 +0200259 } with {
Harald Welte43e060a2017-07-30 22:38:03 +0200260 variant (stall_ind) "FIELDLENGTH(1)"
261 variant (retry) "FIELDLENGTH(1)"
262 variant (pfi_ind) "FIELDLENGTH(1)"
263 variant (tlli_ind) "FIELDLENGTH(1)"
264 variant (e) "FIELDLENGTH(1)"
Harald Welte484160b2017-07-28 13:30:24 +0200265 };
266
Harald Welte484160b2017-07-28 13:30:24 +0200267 type record RlcMacUlPfi {
268 uint7_t pfi,
269 boolean m
270 } with {
271 variant (m) "FIELDLENGTH(1)"
272 };
273
Pau Espin Pedrol372af7a2020-04-27 17:32:01 +0200274 /* TS 44.060 10.3a.1.1 10.3a.4 EGPRS Uplink RLC/MAC header, manual c++ encoder/decoder */
275 type record EgprsUlMacDataHeader {
276 EgprsHeaderType header_type, /* Set internally by decoder */
277 uint5_t tfi,
278 uint4_t countdown,
279 BIT1 foi_si,
280 BIT1 r_ri,
281 uint11_t bsn1,
Pau Espin Pedrol081b1682020-11-06 17:15:52 +0100282 uint8_t bsn2_offset,
Pau Espin Pedrol372af7a2020-04-27 17:32:01 +0200283 uint4_t cps,
284 boolean pfi_ind,
285 BIT1 rsb,
286 BIT2 spb
287 } with {
288 variant (pfi_ind) "FIELDLENGTH(1)"
289 };
290 /* Manual C++ Decoder: 10.3a.2.1 EGPRS Uplink RLC data block */
291 type record RlcmacUlEgprsDataBlock {
Pau Espin Pedrol5abfded2020-11-03 17:30:44 +0100292 CodingScheme mcs, /* Provided by C++ Decoder */
Pau Espin Pedrol372af7a2020-04-27 17:32:01 +0200293 EgprsUlMacDataHeader mac_hdr,
294 boolean tlli_ind,
295 boolean e,
296 /* Octet 3 ... M (optional): manual C++ Decoder */
297 GprsTlli tlli optional,
298 RlcMacUlPfi pfi optional,
299 EgprsLlcBlocks blocks
300 } with {
301 variant (tlli_ind) "FIELDLENGTH(1)"
302 variant (e) "FIELDLENGTH(1)"
303 };
304
Harald Welte484160b2017-07-28 13:30:24 +0200305 /* TS 44.060 10.2.2 */
306 type record RlcmacUlDataBlock {
Pau Espin Pedrol5abfded2020-11-03 17:30:44 +0100307 CodingScheme cs, /* Provided by C++ Decoder */
Harald Welte484160b2017-07-28 13:30:24 +0200308 /* MAC header */
309 UlMacDataHeader mac_hdr,
Harald Welte43e060a2017-07-30 22:38:03 +0200310 /* Octet 3 ... M (optional): manual C++ Decoder */
311 GprsTlli tlli optional,
312 RlcMacUlPfi pfi optional,
313 LlcBlocks blocks
Harald Welte484160b2017-07-28 13:30:24 +0200314 } with {
Harald Welte43e060a2017-07-30 22:38:03 +0200315 variant (tlli) "PRESENCE(mac_hdr.tlli_ind = true)"
316 variant (pfi) "PRESENCE(mac_hdr.pfi_ind = true)"
Harald Welte484160b2017-07-28 13:30:24 +0200317 };
318
Harald Welte43e060a2017-07-30 22:38:03 +0200319 external function enc_RlcmacUlDataBlock(in RlcmacUlDataBlock si) return octetstring;
320 external function dec_RlcmacUlDataBlock(in octetstring stream) return RlcmacUlDataBlock;
Harald Welte484160b2017-07-28 13:30:24 +0200321
Harald Welteefbc2fc2017-07-31 00:05:23 +0200322 type union RlcmacUlBlock {
323 RlcmacUlDataBlock data,
Pau Espin Pedrol372af7a2020-04-27 17:32:01 +0200324 RlcmacUlEgprsDataBlock data_egprs,
Harald Welteefbc2fc2017-07-31 00:05:23 +0200325 RlcmacUlCtrlBlock ctrl
326 } with {
327 variant "TAG(data, mac_hdr.payload_type = MAC_PT_RLC_DATA;
Pau Espin Pedrol372af7a2020-04-27 17:32:01 +0200328 ctrl, {mac_hdr.payload_type = MAC_PT_RLCMAC_NO_OPT,
329 mac_hdr.payload_type = MAC_PT_RLCMAC_OPT};
330 data_egprs, {mac_hdr.header_type = RLCMAC_HDR_TYPE_1,
331 mac_hdr.header_type = RLCMAC_HDR_TYPE_2,
332 mac_hdr.header_type = RLCMAC_HDR_TYPE_3}
333 )"
Harald Welteefbc2fc2017-07-31 00:05:23 +0200334 };
335
Harald Welte78a1af62017-07-31 17:33:56 +0200336 /* as the sub-types (RlcmacDl*Block) are not using the RAW coder, we cannot
337 * use auto-generated functions here, as they would decode those sub-types
338 * based on the RAW coder, not baed on the manual C++ functions */
339 external function enc_RlcmacUlBlock(in RlcmacUlBlock si) return octetstring;
340 external function dec_RlcmacUlBlock(in octetstring stream) return RlcmacUlBlock;
Harald Welteefbc2fc2017-07-31 00:05:23 +0200341
342 type union RlcmacDlBlock {
343 RlcmacDlDataBlock data,
Pau Espin Pedrol372af7a2020-04-27 17:32:01 +0200344 RlcmacDlEgprsDataBlock data_egprs,
Harald Welteefbc2fc2017-07-31 00:05:23 +0200345 RlcmacDlCtrlBlock ctrl
346 } with {
347 variant "TAG(data, mac_hdr.mac_hdr.payload_type = MAC_PT_RLC_DATA;
Pau Espin Pedrol372af7a2020-04-27 17:32:01 +0200348 ctrl, {mac_hdr.payload_type = MAC_PT_RLCMAC_NO_OPT,
349 mac_hdr.payload_type = MAC_PT_RLCMAC_OPT};
350 data_egprs, {mac_hdr.header_type = RLCMAC_HDR_TYPE_1,
351 mac_hdr.header_type = RLCMAC_HDR_TYPE_2,
352 mac_hdr.header_type = RLCMAC_HDR_TYPE_3}
353 )"
Harald Welteefbc2fc2017-07-31 00:05:23 +0200354 };
355
Harald Welte78a1af62017-07-31 17:33:56 +0200356 /* as the sub-types (RlcmacDl*Block) are not using the RAW coder, we cannot
357 * use auto-generated functions here, as they would decode those sub-types
358 * based on the RAW coder, not baed on the manual C++ functions */
359 external function enc_RlcmacDlBlock(in RlcmacDlBlock si) return octetstring;
360 external function dec_RlcmacDlBlock(in octetstring stream) return RlcmacDlBlock;
Harald Welteefbc2fc2017-07-31 00:05:23 +0200361
Pau Espin Pedrolfe3ae512020-04-28 18:05:59 +0200362/************************
363 * PTCCH/D (Packet Timing Advance Control Channel) message.
364 * TODO: add a spec. reference to the message format definition.
365 *************************/
Vadim Yanitskiy1bd8ec52019-10-01 05:44:52 +0700366 type record PTCCHTimingAdvanceIE {
367 BIT1 spare ('0'B),
368 uint7_t ta_val
369 } with { variant "" };
370 type record of PTCCHTimingAdvanceIE PTCCHTimingAdvanceIEs;
371 type record PTCCHDownlinkMsg {
372 PTCCHTimingAdvanceIEs ta_idx length(16),
373 octetstring padding length(7)
374 } with { variant "" };
375
376 external function enc_PTCCHDownlinkMsg(in PTCCHDownlinkMsg si) return octetstring
377 with { extension "prototype(convert) encode(RAW)" };
378 external function dec_PTCCHDownlinkMsg(in octetstring stream) return PTCCHDownlinkMsg
379 with { extension "prototype(convert) decode(RAW)" };
380
381 template PTCCHDownlinkMsg tr_PTCCHDownlinkMsg(
382 template (present) uint7_t tai0_ta := ?,
383 template (present) uint7_t tai1_ta := ?,
384 template (present) uint7_t tai2_ta := ?,
385 template (present) uint7_t tai3_ta := ?,
386 template (present) uint7_t tai4_ta := ?,
387 template (present) uint7_t tai5_ta := ?,
388 template (present) uint7_t tai6_ta := ?,
389 template (present) uint7_t tai7_ta := ?,
390 template (present) uint7_t tai8_ta := ?,
391 template (present) uint7_t tai9_ta := ?,
392 template (present) uint7_t tai10_ta := ?,
393 template (present) uint7_t tai11_ta := ?,
394 template (present) uint7_t tai12_ta := ?,
395 template (present) uint7_t tai13_ta := ?,
396 template (present) uint7_t tai14_ta := ?,
397 template (present) uint7_t tai15_ta := ?
398 ) := {
399 ta_idx := {
400 { spare := '0'B, ta_val := tai0_ta },
401 { spare := '0'B, ta_val := tai1_ta },
402 { spare := '0'B, ta_val := tai2_ta },
403 { spare := '0'B, ta_val := tai3_ta },
404 { spare := '0'B, ta_val := tai4_ta },
405 { spare := '0'B, ta_val := tai5_ta },
406 { spare := '0'B, ta_val := tai6_ta },
407 { spare := '0'B, ta_val := tai7_ta },
408 { spare := '0'B, ta_val := tai8_ta },
409 { spare := '0'B, ta_val := tai9_ta },
410 { spare := '0'B, ta_val := tai10_ta },
411 { spare := '0'B, ta_val := tai11_ta },
412 { spare := '0'B, ta_val := tai12_ta },
413 { spare := '0'B, ta_val := tai13_ta },
414 { spare := '0'B, ta_val := tai14_ta },
415 { spare := '0'B, ta_val := tai15_ta }
416 },
417 padding := '2B2B2B2B2B2B2B'O
418 }
419
Harald Welte060e27a2018-03-03 20:38:19 +0100420
Harald Welte484160b2017-07-28 13:30:24 +0200421} with { encode "RAW"; variant "FIELDORDER(msb)" }