blob: 96b8a647548c360eeef15804fea73d24a17f0abc [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 {
185 DlMacDataHeader mac_hdr,
186 /* Octet 3..M / N: manual C++ Decoder */
187 LlcBlocks blocks
188 } with {
189 variant ""
190 };
Harald Welte484160b2017-07-28 13:30:24 +0200191
Harald Welte43e060a2017-07-30 22:38:03 +0200192 external function enc_RlcmacDlDataBlock(in RlcmacDlDataBlock si) return octetstring;
193 external function dec_RlcmacDlDataBlock(in octetstring stream) return RlcmacDlDataBlock;
Harald Welte484160b2017-07-28 13:30:24 +0200194
195
Pau Espin Pedrol372af7a2020-04-27 17:32:01 +0200196 /* a single RLC block / LLC-segment */
197 type record EgprsLlcBlockHdr {
198 uint7_t length_ind,
199 /* 0 = another extension octet after LLC PDU, 1 = no more extension octets */
200 boolean e
201 } with {
202 variant (e) "FIELDLENGTH(1)"
203 encode "RAW"
204 };
205
206 external function enc_EgprsLlcBlockHdr(in EgprsLlcBlockHdr si) return octetstring
207 with { extension "prototype(convert) encode(RAW)" };
208 external function dec_EgprsLlcBlockHdr(in octetstring stream) return EgprsLlcBlockHdr
209 with { extension "prototype(convert) decode(RAW)" };
210
211 type record EgprsLlcBlock {
212 /* Header is only present if LI field was present */
213 EgprsLlcBlockHdr hdr optional,
214 octetstring payload
215 } with { variant "" };
216 type record of EgprsLlcBlock EgprsLlcBlocks;
217
218 /* TS 44.060 10.3a.1.1 EGPRS downlink RLC data block, manual c++ encoder/decoder */
219 type record EgprsDlMacDataHeader {
220 EgprsHeaderType header_type, /* Set internally by decoder */
221 uint5_t tfi,
222 MacRrbp rrbp,
223 BIT2 esp,
224 uint3_t usf,
225 uint14_t bsn1,
226 uint8_t bsn2_offset,
227 uint2_t pr, /* power reduction */
228 uint2_t spb,
229 uint4_t cps
230 } with { variant "" };
231 /* Manual C++ Decoder: */
232 type record RlcmacDlEgprsDataBlock {
233 EgprsDlMacDataHeader mac_hdr,
234 boolean fbi,
235 boolean e,
236 EgprsLlcBlocks blocks
237 } with {
238 variant (fbi) "FIELDLENGTH(1)"
239 variant (e) "FIELDLENGTH(1)"
240 };
241
Harald Welte484160b2017-07-28 13:30:24 +0200242 /* TS 44.060 10.2.2 */
243 type record UlMacDataHeader {
Harald Welte43e060a2017-07-30 22:38:03 +0200244 /* Octet 0 */
Harald Welteefbc2fc2017-07-31 00:05:23 +0200245 MacPayloadType payload_type,
Harald Welte484160b2017-07-28 13:30:24 +0200246 uint4_t countdown,
247 boolean stall_ind,
Harald Welte43e060a2017-07-30 22:38:03 +0200248 boolean retry,
249 /* Octet 1 */
250 BIT1 spare,
251 boolean pfi_ind,
252 uint5_t tfi,
253 boolean tlli_ind,
254 /* Octet 2 */
255 uint7_t bsn,
256 boolean e
Harald Welte484160b2017-07-28 13:30:24 +0200257 } with {
Harald Welte43e060a2017-07-30 22:38:03 +0200258 variant (stall_ind) "FIELDLENGTH(1)"
259 variant (retry) "FIELDLENGTH(1)"
260 variant (pfi_ind) "FIELDLENGTH(1)"
261 variant (tlli_ind) "FIELDLENGTH(1)"
262 variant (e) "FIELDLENGTH(1)"
Harald Welte484160b2017-07-28 13:30:24 +0200263 };
264
Harald Welte484160b2017-07-28 13:30:24 +0200265 type record RlcMacUlPfi {
266 uint7_t pfi,
267 boolean m
268 } with {
269 variant (m) "FIELDLENGTH(1)"
270 };
271
Pau Espin Pedrol372af7a2020-04-27 17:32:01 +0200272 /* TS 44.060 10.3a.1.1 10.3a.4 EGPRS Uplink RLC/MAC header, manual c++ encoder/decoder */
273 type record EgprsUlMacDataHeader {
274 EgprsHeaderType header_type, /* Set internally by decoder */
275 uint5_t tfi,
276 uint4_t countdown,
277 BIT1 foi_si,
278 BIT1 r_ri,
279 uint11_t bsn1,
280 uint4_t cps,
281 boolean pfi_ind,
282 BIT1 rsb,
283 BIT2 spb
284 } with {
285 variant (pfi_ind) "FIELDLENGTH(1)"
286 };
287 /* Manual C++ Decoder: 10.3a.2.1 EGPRS Uplink RLC data block */
288 type record RlcmacUlEgprsDataBlock {
289 EgprsUlMacDataHeader mac_hdr,
290 boolean tlli_ind,
291 boolean e,
292 /* Octet 3 ... M (optional): manual C++ Decoder */
293 GprsTlli tlli optional,
294 RlcMacUlPfi pfi optional,
295 EgprsLlcBlocks blocks
296 } with {
297 variant (tlli_ind) "FIELDLENGTH(1)"
298 variant (e) "FIELDLENGTH(1)"
299 };
300
Harald Welte484160b2017-07-28 13:30:24 +0200301 /* TS 44.060 10.2.2 */
302 type record RlcmacUlDataBlock {
303 /* MAC header */
304 UlMacDataHeader mac_hdr,
Harald Welte43e060a2017-07-30 22:38:03 +0200305 /* Octet 3 ... M (optional): manual C++ Decoder */
306 GprsTlli tlli optional,
307 RlcMacUlPfi pfi optional,
308 LlcBlocks blocks
Harald Welte484160b2017-07-28 13:30:24 +0200309 } with {
Harald Welte43e060a2017-07-30 22:38:03 +0200310 variant (tlli) "PRESENCE(mac_hdr.tlli_ind = true)"
311 variant (pfi) "PRESENCE(mac_hdr.pfi_ind = true)"
Harald Welte484160b2017-07-28 13:30:24 +0200312 };
313
Harald Welte43e060a2017-07-30 22:38:03 +0200314 external function enc_RlcmacUlDataBlock(in RlcmacUlDataBlock si) return octetstring;
315 external function dec_RlcmacUlDataBlock(in octetstring stream) return RlcmacUlDataBlock;
Harald Welte484160b2017-07-28 13:30:24 +0200316
Harald Welteefbc2fc2017-07-31 00:05:23 +0200317 type union RlcmacUlBlock {
318 RlcmacUlDataBlock data,
Pau Espin Pedrol372af7a2020-04-27 17:32:01 +0200319 RlcmacUlEgprsDataBlock data_egprs,
Harald Welteefbc2fc2017-07-31 00:05:23 +0200320 RlcmacUlCtrlBlock ctrl
321 } with {
322 variant "TAG(data, mac_hdr.payload_type = MAC_PT_RLC_DATA;
Pau Espin Pedrol372af7a2020-04-27 17:32:01 +0200323 ctrl, {mac_hdr.payload_type = MAC_PT_RLCMAC_NO_OPT,
324 mac_hdr.payload_type = MAC_PT_RLCMAC_OPT};
325 data_egprs, {mac_hdr.header_type = RLCMAC_HDR_TYPE_1,
326 mac_hdr.header_type = RLCMAC_HDR_TYPE_2,
327 mac_hdr.header_type = RLCMAC_HDR_TYPE_3}
328 )"
Harald Welteefbc2fc2017-07-31 00:05:23 +0200329 };
330
Harald Welte78a1af62017-07-31 17:33:56 +0200331 /* as the sub-types (RlcmacDl*Block) are not using the RAW coder, we cannot
332 * use auto-generated functions here, as they would decode those sub-types
333 * based on the RAW coder, not baed on the manual C++ functions */
334 external function enc_RlcmacUlBlock(in RlcmacUlBlock si) return octetstring;
335 external function dec_RlcmacUlBlock(in octetstring stream) return RlcmacUlBlock;
Harald Welteefbc2fc2017-07-31 00:05:23 +0200336
337 type union RlcmacDlBlock {
338 RlcmacDlDataBlock data,
Pau Espin Pedrol372af7a2020-04-27 17:32:01 +0200339 RlcmacDlEgprsDataBlock data_egprs,
Harald Welteefbc2fc2017-07-31 00:05:23 +0200340 RlcmacDlCtrlBlock ctrl
341 } with {
342 variant "TAG(data, mac_hdr.mac_hdr.payload_type = MAC_PT_RLC_DATA;
Pau Espin Pedrol372af7a2020-04-27 17:32:01 +0200343 ctrl, {mac_hdr.payload_type = MAC_PT_RLCMAC_NO_OPT,
344 mac_hdr.payload_type = MAC_PT_RLCMAC_OPT};
345 data_egprs, {mac_hdr.header_type = RLCMAC_HDR_TYPE_1,
346 mac_hdr.header_type = RLCMAC_HDR_TYPE_2,
347 mac_hdr.header_type = RLCMAC_HDR_TYPE_3}
348 )"
Harald Welteefbc2fc2017-07-31 00:05:23 +0200349 };
350
Harald Welte78a1af62017-07-31 17:33:56 +0200351 /* as the sub-types (RlcmacDl*Block) are not using the RAW coder, we cannot
352 * use auto-generated functions here, as they would decode those sub-types
353 * based on the RAW coder, not baed on the manual C++ functions */
354 external function enc_RlcmacDlBlock(in RlcmacDlBlock si) return octetstring;
355 external function dec_RlcmacDlBlock(in octetstring stream) return RlcmacDlBlock;
Harald Welteefbc2fc2017-07-31 00:05:23 +0200356
Pau Espin Pedrolfe3ae512020-04-28 18:05:59 +0200357/************************
358 * PTCCH/D (Packet Timing Advance Control Channel) message.
359 * TODO: add a spec. reference to the message format definition.
360 *************************/
Vadim Yanitskiy1bd8ec52019-10-01 05:44:52 +0700361 type record PTCCHTimingAdvanceIE {
362 BIT1 spare ('0'B),
363 uint7_t ta_val
364 } with { variant "" };
365 type record of PTCCHTimingAdvanceIE PTCCHTimingAdvanceIEs;
366 type record PTCCHDownlinkMsg {
367 PTCCHTimingAdvanceIEs ta_idx length(16),
368 octetstring padding length(7)
369 } with { variant "" };
370
371 external function enc_PTCCHDownlinkMsg(in PTCCHDownlinkMsg si) return octetstring
372 with { extension "prototype(convert) encode(RAW)" };
373 external function dec_PTCCHDownlinkMsg(in octetstring stream) return PTCCHDownlinkMsg
374 with { extension "prototype(convert) decode(RAW)" };
375
376 template PTCCHDownlinkMsg tr_PTCCHDownlinkMsg(
377 template (present) uint7_t tai0_ta := ?,
378 template (present) uint7_t tai1_ta := ?,
379 template (present) uint7_t tai2_ta := ?,
380 template (present) uint7_t tai3_ta := ?,
381 template (present) uint7_t tai4_ta := ?,
382 template (present) uint7_t tai5_ta := ?,
383 template (present) uint7_t tai6_ta := ?,
384 template (present) uint7_t tai7_ta := ?,
385 template (present) uint7_t tai8_ta := ?,
386 template (present) uint7_t tai9_ta := ?,
387 template (present) uint7_t tai10_ta := ?,
388 template (present) uint7_t tai11_ta := ?,
389 template (present) uint7_t tai12_ta := ?,
390 template (present) uint7_t tai13_ta := ?,
391 template (present) uint7_t tai14_ta := ?,
392 template (present) uint7_t tai15_ta := ?
393 ) := {
394 ta_idx := {
395 { spare := '0'B, ta_val := tai0_ta },
396 { spare := '0'B, ta_val := tai1_ta },
397 { spare := '0'B, ta_val := tai2_ta },
398 { spare := '0'B, ta_val := tai3_ta },
399 { spare := '0'B, ta_val := tai4_ta },
400 { spare := '0'B, ta_val := tai5_ta },
401 { spare := '0'B, ta_val := tai6_ta },
402 { spare := '0'B, ta_val := tai7_ta },
403 { spare := '0'B, ta_val := tai8_ta },
404 { spare := '0'B, ta_val := tai9_ta },
405 { spare := '0'B, ta_val := tai10_ta },
406 { spare := '0'B, ta_val := tai11_ta },
407 { spare := '0'B, ta_val := tai12_ta },
408 { spare := '0'B, ta_val := tai13_ta },
409 { spare := '0'B, ta_val := tai14_ta },
410 { spare := '0'B, ta_val := tai15_ta }
411 },
412 padding := '2B2B2B2B2B2B2B'O
413 }
414
Harald Welte060e27a2018-03-03 20:38:19 +0100415
Harald Welte484160b2017-07-28 13:30:24 +0200416} with { encode "RAW"; variant "FIELDORDER(msb)" }