blob: e99dfef711b7ecff5436d0a7084f2d5ef194b31a [file] [log] [blame]
Harald Weltec676c682017-12-24 20:38:20 +01001module IuUP_Types {
2
Harald Welte35bb7162018-01-03 21:07:52 +01003/* Definition of abstract types for the IuUP protocol as specified in
4 * 3GPP TS 25.415. Uses the TITAN "RAW" codec to auto-generate encoder/decoder
5 * functions.
6 *
7 * (C) 2017 by Harald Welte <laforge@gnumonks.org>
8 * All rights reserved.
9 *
10 * Released under the terms of GNU General Public License, Version 2 or
11 * (at your option) any later version.
12 */
13
Harald Weltec676c682017-12-24 20:38:20 +010014import from Osmocom_Types all;
15import from General_Types all;
16
17/* See TS 25.415 6.6.3.1 */
18type uint4_t IuUP_PDU_Type;
19
20/* See TS 25.415 6.6.3.2 */
21type enumerated IuUP_AckNack {
22 IuUP_ACKNACK_CTRL (0),
23 IuUP_ACKNACK_ACK (1),
24 IuUP_ACKNACK_NACK (2),
25 IuUP_ACKNACK_RESERVED (3)
26} with { variant "FIELDLENGTH(2)" };
27
28/* See TS 25.415 6.6.3.3 */
29type uint4_t IuUP_FrameNr;
30
31/* See TS 25.415 6.6.3.5 */
32type enumerated IuUP_FQC {
33 IuUP_FQC_GOOD (0),
34 IuUP_FQC_BAD (1),
35 IuUP_FQC_BAD_RADIO (2),
36 IuUP_FQC_SPARE (3)
37} with { variant "FIELDLENGTH(2)" };
38
39/* See TS 25.415 6.6.3.6 */
40type uint6_t IuUP_RFCI;
41
42/* See TS 25.415 6.6.3.7 */
43type enumerated IuUP_ProcedureIndicator {
44 IuUP_PRI_INITIALIZATION (0),
45 IuUP_PRI_RATE_CONTROL (1),
46 IuUP_PRI_TIME_ALIGNMENT (2),
47 IuUP_PRI_ERROR_EVENT (3)
48 /* reserved */
49} with { variant "FIELDLENGTH(4)" };
50
51/* See TS 25.415 6.6.3.13 */
52type uint6_t IuUP_NumOfRfciInd;
53
54/* See TS 25.415 6.6.3.15 */
55type enumerated IuUP_ErrorDistance {
56 IuUP_ERR_DIST_LOCAL (0),
57 IuUP_ERR_DIST_FIRST_FW (1),
58 IuUP_ERR_DIST_SECOND_FW (2),
59 IuUP_ERR_DIST_RESERVED (3)
60} with { variant "FIELDLENGTH(2)" };
61
62/* See TS 25.415 6.6.3.16 */
63type enumerated IuUP_ErrorCause {
64 /* Syntactical protocol errors */
65 IuUP_CAUSE_CRC_ERROR_HEADER (0),
66 IuUP_CAUSE_CRC_ERROR_PAYLOAD (1),
67 IuUP_CAUSE_UNEXP_FRAME_NR (2),
68 IuUP_CAUSE_FRAME_LOSS (3),
69 IuUP_CAUSE_PDU_TYPE_UNKNOWN (4),
70 IuUP_CAUSE_UNKNOWN_PROCEDURE (5),
71 IuUP_CAUSE_UNKNOWN_RES_VAL (6),
72 IuUP_CAUSE_UNKNOWN_FIELD (7),
73 IuUP_CAUSE_FRAME_TOO_SHORT (8),
74 IuUP_CAUSE_MISSING_FIELD (9),
75 /* Semantical protocol errors */
76 IuUP_CAUSE_UNEXPECTED_PDU_TYPE (16),
77 IuUP_CAUSE_UNEXPECTED_PROCEDURE (18),
78 IuUP_CAUSE_UNEXPECTED_RFCI (19),
79 IuUP_CAUSE_UNEXPECTED_VALUE (20),
80 /* Other Errors */
81 IuUP_CAUSE_INIT_FAIL (42),
82 IuUP_CAUSE_INIT_FAIL_NET_TMR_EXP (43),
83 IuUP_CAUSE_INIT_FAIL_FERR_REP_NACK (44),
84 IuUP_CAUSE_RATE_CONTROL_FAIL (45),
85 IuUP_CAUSE_ERROR_EVENT_FAIL (46),
86 IuUP_CAUSE_TIME_ALIGN_NOTSUPP (47),
87 IuUP_CAUSE_REQ_ALIGN_NOTPOSS (48),
88 IuUP_CAUSE_IU_UP_VERS_NOTSUPP (49)
89} with { variant "FIELDLENGTH(6)" };
90
91/* See TS 25.415 6.6.3.18 */
92type uint8_t IuUP_TimeAlignment;
93
Pau Espin Pedrol5b4f2c62022-05-25 17:07:17 +020094/* See TS 25.415 6.6.3.24 */
95type uint4_t IuUP_IPTI;
Harald Weltec676c682017-12-24 20:38:20 +010096
97/* See TS 25.415 6.6.2.1 */
98type record IuUP_PDU_Type_0 {
99 IuUP_PDU_Type pdu_type, /* 0 */
100 IuUP_FrameNr frame_nr,
101 IuUP_FQC fqc,
102 IuUP_RFCI rfci,
103 uint6_t header_crc,
104 uint10_t payload_crc,
105 octetstring payload
106};
107
108/* See TS 25.415 6.6.2.2 */
109type record IuUP_PDU_Type_1 {
110 IuUP_PDU_Type pdu_type, /* 1 */
111 IuUP_FrameNr frame_nr,
112 IuUP_FQC fqc,
113 IuUP_RFCI rfci,
114 uint6_t header_crc,
115 BIT2 spare,
116 octetstring payload
117};
118
119/* See TS 25.415 6.6.6.2.3 */
120type record IuUP_PDU_Type_14 {
121 IuUP_PDU_Type pdu_type,
122 IuUP_AckNack ack_nack,
123 uint2_t frame_nr,
Pau Espin Pedrol5b4f2c62022-05-25 17:07:17 +0200124 IuUP_PDU14_Union u
125} with { variant (u) "CROSSTAG(proc, ack_nack=IuUP_ACKNACK_CTRL;
126 ack, ack_nack=IuUP_ACKNACK_ACK;
127 nack, ack_nack=IuUP_ACKNACK_NACK)"
128};
129
130type record IuUP_PDU_Type_14_Common_Hdr {
Harald Weltec676c682017-12-24 20:38:20 +0100131 uint4_t iuup_version,
132 IuUP_ProcedureIndicator procedure_ind,
133 uint6_t header_crc,
Pau Espin Pedrol5b4f2c62022-05-25 17:07:17 +0200134 uint10_t payload_crc
135};
136
137type union IuUP_PDU14_Union {
138 IuUP_PDU14_ProcSending proc,
139 IuUP_PDU14_ACK ack,
140 IuUP_PDU14_NACK nack
Harald Weltec676c682017-12-24 20:38:20 +0100141};
142
143/* 6.6.2.3.1 Figure 21 */
144type record IuUP_PDU14_ProcSending {
Pau Espin Pedrol5b4f2c62022-05-25 17:07:17 +0200145 IuUP_PDU_Type_14_Common_Hdr hdr,
146 IuUP_PDU14_ProcSendingUnion u
147} with {
148 variant (u) "CROSSTAG(init, hdr.procedure_ind=IuUP_PRI_INITIALIZATION;
149 rate_ctrl, hdr.procedure_ind=IuUP_PRI_RATE_CONTROL;
150 time_alignment, hdr.procedure_ind=IuUP_PRI_TIME_ALIGNMENT;
151 error_event, hdr.procedure_ind=IuUP_PRI_ERROR_EVENT;
152 other, OTHERWISE)"
Harald Weltec676c682017-12-24 20:38:20 +0100153};
154
155/* 6.6.2.3.2 Figure 22 */
156type record IuUP_PDU14_ACK {
Pau Espin Pedrol5b4f2c62022-05-25 17:07:17 +0200157 IuUP_PDU_Type_14_Common_Hdr hdr,
Harald Weltec676c682017-12-24 20:38:20 +0100158 octetstring spare_ext optional
159};
160
161/* 6.6.2.3.3 Figure 23 */
162type record IuUP_PDU14_NACK {
Pau Espin Pedrol5b4f2c62022-05-25 17:07:17 +0200163 IuUP_PDU_Type_14_Common_Hdr hdr,
Harald Weltec676c682017-12-24 20:38:20 +0100164 IuUP_ErrorCause err_cause,
165 BIT2 spare,
166 octetstring spare_ext optional
167};
168
Harald Weltec676c682017-12-24 20:38:20 +0100169type union IuUP_PDU14_ProcSendingUnion {
170 IuUP_PDU14_ProcSending_INIT init,
171 IuUP_PDU14_ProcSending_RATE_CTRL rate_ctrl,
Harald Weltec676c682017-12-24 20:38:20 +0100172 IuUP_PDU14_ProcSending_TIME_ALIGNMENT time_alignment,
Pau Espin Pedrol5b4f2c62022-05-25 17:07:17 +0200173 IuUP_PDU14_ProcSending_ERROR_EVENT error_event,
174 octetstring other
Harald Weltec676c682017-12-24 20:38:20 +0100175};
176
177/* 6.6.2.3.4.1 Initialisation */
178type record IuUP_PDU14_ProcSending_INIT {
179 BIT3 spare,
180 boolean ti,
181 uint3_t subflows_per_rfci,
182 boolean chain_ind,
Pau Espin Pedrol5b4f2c62022-05-25 17:07:17 +0200183 IuUP_InitRfci rfci,
184 IuUP_IPTI_List IPTIs optional,
185 BIT16 versions_supported,
186 uint4_t data_pdu_type,
187 BIT4 spare2
188} with {
189 variant (IPTIs) "PRESENCE(ti=true)"
190 variant (versions_supported) "BITORDER(lsb)"
191 variant (versions_supported) "BYTEORDER(last)"
Harald Weltec676c682017-12-24 20:38:20 +0100192};
193type record IuUP_InitRfci {
194 boolean lri,
195 boolean li,
Pau Espin Pedrol5b4f2c62022-05-25 17:07:17 +0200196 IuUP_RFCI rfci_id,
Harald Weltec676c682017-12-24 20:38:20 +0100197 RecOfU8 len8 optional,
Pau Espin Pedrol5b4f2c62022-05-25 17:07:17 +0200198 RecOfU16 len16 optional,
199 IuUP_InitRfci rfci optional
200} with {
201 variant (len8) "PRESENCE(li=false)";
202 variant (len16) "PRESENCE(li=true)"
203 variant (rfci) "PRESENCE(lri=false)"
Harald Weltec676c682017-12-24 20:38:20 +0100204};
Pau Espin Pedrol5b4f2c62022-05-25 17:07:17 +0200205type record of IuUP_IPTI IuUP_IPTI_List with {
206 variant "FIELDLENGTH(3)"
207 variant "PADDING(yes)"
208 };
209type record of uint8_t RecOfU8 with { variant "FIELDLENGTH(3)" };
210type record of uint16_t RecOfU16 with { variant "FIELDLENGTH(3)" };
211type record of IuUP_InitRfci IuUP_InitRfciList;
Harald Weltec676c682017-12-24 20:38:20 +0100212
213/* 6.6.2.3.4.2.1 Rate Control procedure */
214type record IuUP_PDU14_ProcSending_RATE_CTRL {
215 BIT2 spare,
216 uint6_t nr_of_rfci_ind,
217 bitstring rfci_ind
218} with { variant (nr_of_rfci_ind) "LENGTHTO(rfci_ind)"
219 variant (nr_of_rfci_ind) "UNIT(bits)"
220};
221
222/* 6.6.2.3.4.3 Time Alignment */
223type record IuUP_PDU14_ProcSending_TIME_ALIGNMENT {
224 uint8_t time_alignment,
225 octetstring spare optional
226};
227
228/* 6.6.2.3.4.4 Error Event */
229type record IuUP_PDU14_ProcSending_ERROR_EVENT {
230 IuUP_ErrorDistance distance,
231 IuUP_ErrorCause cause
232};
233
234
235type union IuUP_PDU {
236 IuUP_PDU_Type_0 type_0,
237 IuUP_PDU_Type_1 type_1,
238 IuUP_PDU_Type_14 type_14
239} with { variant "TAG( type_0, pdu_type = 0;
240 type_1, pdu_type = 1;
241 type_14, pdu_type = 14;)" };
242
243/* hand-written C++ functions */
244external function f_enc_IuUP_PDU(in IuUP_PDU msg) return octetstring;
245external function f_IuUP_compute_crc_header(in octetstring inp) return uint6_t;
246external function f_IuUP_compute_crc_payload(in octetstring inp) return uint10_t;
247
248/* auto-generated */
249external function dec_IuUP_PDU(in octetstring stream) return IuUP_PDU
250 with { extension "prototype(convert) decode(RAW)" };
251
252template IuUP_PDU ts_IuUP_INIT_ACK(uint2_t frame_nr, uint4_t version) := {
253 type_14 := {
254 pdu_type := 14,
255 ack_nack := IuUP_ACKNACK_ACK,
256 frame_nr := frame_nr,
Harald Weltec676c682017-12-24 20:38:20 +0100257 u := {
258 ack := {
Pau Espin Pedrol5b4f2c62022-05-25 17:07:17 +0200259 hdr := {
260 iuup_version := version,
261 procedure_ind := IuUP_PRI_INITIALIZATION,
262 header_crc := 0,
263 payload_crc := 0
264 },
Harald Weltec676c682017-12-24 20:38:20 +0100265 spare_ext := omit
266 }
267 }
268 }
269};
270
271template IuUP_PDU tr_IuUP_INIT_ACK(template uint2_t frame_nr := ?, template uint4_t version := ?) := {
272 type_14 := {
273 pdu_type := 14,
274 ack_nack := IuUP_ACKNACK_ACK,
275 frame_nr := frame_nr,
Harald Weltec676c682017-12-24 20:38:20 +0100276 u := {
277 ack := {
Pau Espin Pedrol5b4f2c62022-05-25 17:07:17 +0200278 hdr := {
279 iuup_version := version,
280 procedure_ind := IuUP_PRI_INITIALIZATION,
281 header_crc := ?,
282 payload_crc := ?
283 },
Harald Weltec676c682017-12-24 20:38:20 +0100284 spare_ext := omit
285 }
286 }
287 }
288};
289
Pau Espin Pedrol5b4f2c62022-05-25 17:07:17 +0200290template (value) IuUP_InitRfci ts_IuUP_InitRfci(
291 template (value) boolean lri,
292 template (value) boolean li,
293 template (value) IuUP_RFCI rfci_id,
294 template (omit) RecOfU8 len8,
295 template (omit) RecOfU16 len16,
296 template (omit) IuUP_InitRfci rfci := omit) := {
297 lri := lri,
298 li := li,
299 rfci_id := rfci_id,
300 len8 := len8,
301 len16 := len16,
302 rfci := rfci
303}
304
305template (value) IuUP_PDU14_ProcSending_INIT ts_IuUP_PDU14_ProcSending_INIT(
306 template (value) boolean ti := true,
307 template (value) uint3_t subflows_per_rfci := 3,
308 template (value) boolean chain_ind := false,
309 template (value) IuUP_InitRfci rfci := ts_IuUP_InitRfci(false, false, 0, {81, 103, 60}, omit,
310 ts_IuUP_InitRfci(false, false, 1, {39, 0, 0}, omit,
311 ts_IuUP_InitRfci(true, false, 2, {0, 0, 0}, omit, omit))),
312 template (omit) IuUP_IPTI_List IPTIs := {1, 7, 1},
313 template (value) BIT16 versions_supported := '0000000000000001'B,
314 template (value) uint4_t data_pdu_type := 0) := {
315 spare := '000'B,
316 ti := ti,
317 subflows_per_rfci := subflows_per_rfci,
318 chain_ind := chain_ind,
319 rfci := rfci,
320 IPTIs := IPTIs,
321 versions_supported := versions_supported,
322 data_pdu_type := data_pdu_type,
323 spare2 := '0000'B
324}
325
326template (present) IuUP_PDU14_ProcSending_INIT tr_IuUP_PDU14_ProcSending_INIT(
327 template (present) boolean ti := ?,
328 template (present) uint3_t subflows_per_rfci := ?,
329 template (present) boolean chain_ind := ?,
330 template (present) IuUP_InitRfci rfci := ?,
331 template IuUP_IPTI_List IPTIs := *,
332 template (present) BIT16 versions_supported := ?,
333 template (present) uint4_t data_pdu_type := ?) := {
334 spare := '000'B,
335 ti := ti,
336 subflows_per_rfci := subflows_per_rfci,
337 chain_ind := chain_ind,
338 rfci := rfci,
339 IPTIs := IPTIs,
340 versions_supported := versions_supported,
341 data_pdu_type := data_pdu_type,
342 spare2 := '0000'B
343}
344
345template (value) IuUP_PDU ts_IuUP_INIT(template (value) IuUP_PDU14_ProcSending_INIT init, uint2_t frame_nr := 0, uint4_t version := 0) := {
Harald Weltec676c682017-12-24 20:38:20 +0100346 type_14 := {
347 pdu_type := 14,
348 ack_nack := IuUP_ACKNACK_CTRL,
349 frame_nr := frame_nr,
Harald Weltec676c682017-12-24 20:38:20 +0100350 u := {
Pau Espin Pedrol5b4f2c62022-05-25 17:07:17 +0200351 proc := {
352 hdr := {
353 iuup_version := version,
354 procedure_ind := IuUP_PRI_INITIALIZATION,
355 header_crc := 0,
356 payload_crc := 0
357 },
358 u := {
359 init := init
360 }
Harald Weltec676c682017-12-24 20:38:20 +0100361 }
362 }
363 }
364};
365
Pau Espin Pedrol5b4f2c62022-05-25 17:07:17 +0200366template IuUP_PDU tr_IuUP_INIT(template (present) IuUP_PDU14_ProcSending_INIT init := ?, template octetstring payload := ?, template uint2_t frame_nr := ?,
Harald Weltec676c682017-12-24 20:38:20 +0100367 template uint4_t version := ?) := {
368 type_14 := {
369 pdu_type := 14,
370 ack_nack := IuUP_ACKNACK_CTRL,
371 frame_nr := frame_nr,
Harald Weltec676c682017-12-24 20:38:20 +0100372 u := {
Pau Espin Pedrol5b4f2c62022-05-25 17:07:17 +0200373 proc := {
374 hdr := {
375 iuup_version := version,
376 procedure_ind := IuUP_PRI_INITIALIZATION,
377 header_crc := ?,
378 payload_crc := ?
379 },
380 u := {
381 init := init
382 }
Harald Weltec676c682017-12-24 20:38:20 +0100383 }
384 }
385 }
386};
387
388
389template IuUP_PDU ts_IuUP_Type0(IuUP_FrameNr frame_nr, IuUP_RFCI rfci, octetstring payload,
390 IuUP_FQC fqc := IuUP_FQC_GOOD) := {
391 type_0 := {
392 pdu_type := 0,
393 frame_nr := frame_nr,
394 fqc := fqc,
395 rfci := rfci,
396 header_crc := 0,
397 payload_crc := 0,
398 payload := payload
399 }
400};
401
402template IuUP_PDU tr_IuUP_Type0(template IuUP_FrameNr frame_nr := ?, template IuUP_RFCI rfci := ?,
403 template IuUP_FQC fqc := ?) := {
404 type_0 := {
405 pdu_type := 0,
406 frame_nr := frame_nr,
407 fqc := fqc,
408 rfci := rfci,
409 header_crc := ?,
410 payload_crc := ?,
411 payload := ?
412 }
413};
414
415template IuUP_PDU ts_IuUP_Type1(IuUP_FrameNr frame_nr, IuUP_RFCI rfci, octetstring payload,
416 IuUP_FQC fqc := IuUP_FQC_GOOD) := {
417 type_1 := {
418 pdu_type := 1,
419 frame_nr := frame_nr,
420 fqc := fqc,
421 rfci := rfci,
422 header_crc := 0,
423 spare := '00'B,
424 payload := payload
425 }
426};
427
428
429template IuUP_PDU tr_IuUP_Type1(template IuUP_FrameNr frame_nr := ?, template IuUP_RFCI rfci := ?,
430 template IuUP_FQC fqc := ?) := {
431 type_1 := {
432 pdu_type := 1,
433 frame_nr := frame_nr,
434 fqc := fqc,
435 rfci := rfci,
436 header_crc := ?,
437 spare := ?,
438 payload := ?
439 }
440};
441
442
443
444} with { encode "RAW" ; variant "FIELDORDER(msb)" }