aboutsummaryrefslogtreecommitdiffstats
path: root/library/IuUP_Types.ttcn
blob: b822ddf189e76cc43017c4d5139bf4c08b10307c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
module IuUP_Types {

/* Definition of abstract types for the IuUP protocol as specified in
 * 3GPP TS 25.415.  Uses the TITAN "RAW" codec to auto-generate encoder/decoder
 * functions.
 *
 * (C) 2017 by Harald Welte <laforge@gnumonks.org>
 * All rights reserved.
 *
 * Released under the terms of GNU General Public License, Version 2 or
 * (at your option) any later version.
 */

import from Osmocom_Types all;
import from General_Types all;

/* See TS 25.415 6.6.3.1 */
type uint4_t IuUP_PDU_Type;

/* See TS 25.415 6.6.3.2 */
type enumerated IuUP_AckNack {
	IuUP_ACKNACK_CTRL	(0),
	IuUP_ACKNACK_ACK	(1),
	IuUP_ACKNACK_NACK	(2),
	IuUP_ACKNACK_RESERVED	(3)
} with { variant "FIELDLENGTH(2)" };

/* See TS 25.415 6.6.3.3 */
type uint4_t IuUP_FrameNr;

/* See TS 25.415 6.6.3.5 */
type enumerated IuUP_FQC {
	IuUP_FQC_GOOD		(0),
	IuUP_FQC_BAD		(1),
	IuUP_FQC_BAD_RADIO	(2),
	IuUP_FQC_SPARE		(3)
} with { variant "FIELDLENGTH(2)" };

/* See TS 25.415 6.6.3.6 */
type uint6_t IuUP_RFCI;

/* See TS 25.415 6.6.3.7 */
type enumerated IuUP_ProcedureIndicator {
	IuUP_PRI_INITIALIZATION		(0),
	IuUP_PRI_RATE_CONTROL		(1),
	IuUP_PRI_TIME_ALIGNMENT		(2),
	IuUP_PRI_ERROR_EVENT		(3)
	/* reserved */
} with { variant "FIELDLENGTH(4)" };

/* See TS 25.415 6.6.3.13 */
type uint6_t IuUP_NumOfRfciInd;

/* See TS 25.415 6.6.3.15 */
type enumerated IuUP_ErrorDistance {
	IuUP_ERR_DIST_LOCAL		(0),
	IuUP_ERR_DIST_FIRST_FW		(1),
	IuUP_ERR_DIST_SECOND_FW		(2),
	IuUP_ERR_DIST_RESERVED		(3)
} with { variant "FIELDLENGTH(2)" };

/* See TS 25.415 6.6.3.16 */
type enumerated IuUP_ErrorCause {
	/* Syntactical protocol errors */
	IuUP_CAUSE_CRC_ERROR_HEADER	(0),
	IuUP_CAUSE_CRC_ERROR_PAYLOAD	(1),
	IuUP_CAUSE_UNEXP_FRAME_NR	(2),
	IuUP_CAUSE_FRAME_LOSS		(3),
	IuUP_CAUSE_PDU_TYPE_UNKNOWN	(4),
	IuUP_CAUSE_UNKNOWN_PROCEDURE	(5),
	IuUP_CAUSE_UNKNOWN_RES_VAL	(6),
	IuUP_CAUSE_UNKNOWN_FIELD	(7),
	IuUP_CAUSE_FRAME_TOO_SHORT	(8),
	IuUP_CAUSE_MISSING_FIELD	(9),
	/* Semantical protocol errors */
	IuUP_CAUSE_UNEXPECTED_PDU_TYPE	(16),
	IuUP_CAUSE_UNEXPECTED_PROCEDURE	(18),
	IuUP_CAUSE_UNEXPECTED_RFCI	(19),
	IuUP_CAUSE_UNEXPECTED_VALUE	(20),
	/* Other Errors */
	IuUP_CAUSE_INIT_FAIL		(42),
	IuUP_CAUSE_INIT_FAIL_NET_TMR_EXP	(43),
	IuUP_CAUSE_INIT_FAIL_FERR_REP_NACK	(44),
	IuUP_CAUSE_RATE_CONTROL_FAIL	(45),
	IuUP_CAUSE_ERROR_EVENT_FAIL	(46),
	IuUP_CAUSE_TIME_ALIGN_NOTSUPP	(47),
	IuUP_CAUSE_REQ_ALIGN_NOTPOSS	(48),
	IuUP_CAUSE_IU_UP_VERS_NOTSUPP	(49)
} with { variant "FIELDLENGTH(6)" };

/* See TS 25.415 6.6.3.18 */
type uint8_t IuUP_TimeAlignment;


/* See TS 25.415 6.6.2.1 */
type record IuUP_PDU_Type_0 {
	IuUP_PDU_Type	pdu_type,	/* 0 */
	IuUP_FrameNr	frame_nr,
	IuUP_FQC	fqc,
	IuUP_RFCI	rfci,
	uint6_t		header_crc,
	uint10_t	payload_crc,
	octetstring	payload
};

/* See TS 25.415 6.6.2.2 */
type record IuUP_PDU_Type_1 {
	IuUP_PDU_Type	pdu_type,	/* 1 */
	IuUP_FrameNr	frame_nr,
	IuUP_FQC	fqc,
	IuUP_RFCI	rfci,
	uint6_t		header_crc,
	BIT2		spare,
	octetstring	payload
};

/* See TS 25.415 6.6.6.2.3 */
type record IuUP_PDU_Type_14 {
	IuUP_PDU_Type	pdu_type,
	IuUP_AckNack	ack_nack,
	uint2_t		frame_nr,
	uint4_t		iuup_version,
	IuUP_ProcedureIndicator	procedure_ind,
	uint6_t		header_crc,
	uint10_t	payload_crc,
	IuUP_PDU14_Union u
} with { variant (u) "CROSSTAG(	proc_sending,	ack_nack=IuUP_ACKNACK_CTRL;
				ack,		ack_nack=IuUP_ACKNACK_ACK;
				nack,		ack_nack=IuUP_ACKNACK_NACK)"
};

/* 6.6.2.3.1 Figure 21 */
type record IuUP_PDU14_ProcSending {
	octetstring	payload
};

/* 6.6.2.3.2 Figure 22 */
type record IuUP_PDU14_ACK {
	octetstring	spare_ext optional
};

/* 6.6.2.3.3 Figure 23 */
type record IuUP_PDU14_NACK {
	IuUP_ErrorCause	err_cause,
	BIT2		spare,
	octetstring	spare_ext optional
};

type union IuUP_PDU14_Union {
	IuUP_PDU14_ProcSending	proc_sending,
	IuUP_PDU14_ACK		ack,
	IuUP_PDU14_NACK		nack
};

type union IuUP_PDU14_ProcSendingUnion {
	IuUP_PDU14_ProcSending_INIT		init,
	IuUP_PDU14_ProcSending_RATE_CTRL	rate_ctrl,
	IuUP_PDU14_ProcSending_RATE_CTRL	rate_ctrl_ack,
	IuUP_PDU14_ProcSending_TIME_ALIGNMENT	time_alignment,
	IuUP_PDU14_ProcSending_ERROR_EVENT	error_event
};

/* 6.6.2.3.4.1 Initialisation */
type record IuUP_PDU14_ProcSending_INIT {
	BIT3		spare,
	boolean		ti,
	uint3_t		subflows_per_rfci,
	boolean		chain_ind,

	/* FIXME: Further decode */
	octetstring	payload
};
type record IuUP_InitRfci {
	boolean		lri,
	boolean		li,
	IuUP_RFCI	rfci,
	RecOfU8		len8 optional,
	RecOfU16	len16 optional
} with { variant (len8)		"PRESENCE(li=false)";
	 variant (len16)	"PRESENCE(li=true)"
};
type record of uint8_t RecOfU8;
type record of uint16_t RecOfU16;

/* 6.6.2.3.4.2.1 Rate Control procedure */
type record IuUP_PDU14_ProcSending_RATE_CTRL {
	BIT2		spare,
	uint6_t		nr_of_rfci_ind,
	bitstring	rfci_ind
} with { variant (nr_of_rfci_ind) "LENGTHTO(rfci_ind)"
	 variant (nr_of_rfci_ind) "UNIT(bits)"
};

/* 6.6.2.3.4.3 Time Alignment */
type record IuUP_PDU14_ProcSending_TIME_ALIGNMENT {
	uint8_t		time_alignment,
	octetstring	spare optional
};

/* 6.6.2.3.4.4 Error Event */
type record IuUP_PDU14_ProcSending_ERROR_EVENT {
	IuUP_ErrorDistance	distance,
	IuUP_ErrorCause		cause
};


type union IuUP_PDU {
	IuUP_PDU_Type_0		type_0,
	IuUP_PDU_Type_1		type_1,
	IuUP_PDU_Type_14	type_14
} with { variant "TAG(	type_0,		pdu_type = 0;
			type_1,		pdu_type = 1;
			type_14,	pdu_type = 14;)" };

/* hand-written C++ functions */
external function f_enc_IuUP_PDU(in IuUP_PDU msg) return octetstring;
external function f_IuUP_compute_crc_header(in octetstring inp) return uint6_t;
external function f_IuUP_compute_crc_payload(in octetstring inp) return uint10_t;

/* auto-generated */
external function dec_IuUP_PDU(in octetstring stream) return IuUP_PDU
	with { extension "prototype(convert) decode(RAW)" };

template IuUP_PDU ts_IuUP_INIT_ACK(uint2_t frame_nr, uint4_t version) := {
	type_14 := {
		pdu_type := 14,
		ack_nack := IuUP_ACKNACK_ACK,
		frame_nr := frame_nr,
		iuup_version := version,
		procedure_ind := IuUP_PRI_INITIALIZATION,
		header_crc := 0,
		payload_crc := 0,
		u := {
			ack := {
				spare_ext := omit
			}
		}
	}
};

template IuUP_PDU tr_IuUP_INIT_ACK(template uint2_t frame_nr := ?, template uint4_t version := ?) := {
	type_14 := {
		pdu_type := 14,
		ack_nack := IuUP_ACKNACK_ACK,
		frame_nr := frame_nr,
		iuup_version := version,
		procedure_ind := IuUP_PRI_INITIALIZATION,
		header_crc := ?,
		payload_crc := ?,
		u := {
			ack := {
				spare_ext := omit
			}
		}
	}
};

template IuUP_PDU ts_IuUP_INIT(octetstring payload, uint2_t frame_nr := 0, uint4_t version := 0) := {
	type_14 := {
		pdu_type := 14,
		ack_nack := IuUP_ACKNACK_CTRL,
		frame_nr := frame_nr,
		iuup_version := version,
		procedure_ind := IuUP_PRI_INITIALIZATION,
		header_crc := 0,
		payload_crc := 0,
		u := {
			proc_sending := {
				payload := payload
			}
		}
	}
};

template IuUP_PDU tr_IuUP_INIT(template octetstring payload := ?, template uint2_t frame_nr := ?,
				template uint4_t version := ?) := {
	type_14 := {
		pdu_type := 14,
		ack_nack := IuUP_ACKNACK_CTRL,
		frame_nr := frame_nr,
		iuup_version := version,
		procedure_ind := IuUP_PRI_INITIALIZATION,
		header_crc := ?,
		payload_crc := ?,
		u := {
			proc_sending := {
				payload := payload
			}
		}
	}
};


template IuUP_PDU ts_IuUP_Type0(IuUP_FrameNr frame_nr, IuUP_RFCI rfci, octetstring payload,
				IuUP_FQC fqc := IuUP_FQC_GOOD) := {
	type_0 := {
		pdu_type := 0,
		frame_nr := frame_nr,
		fqc := fqc,
		rfci := rfci,
		header_crc := 0,
		payload_crc := 0,
		payload := payload
	}
};

template IuUP_PDU tr_IuUP_Type0(template IuUP_FrameNr frame_nr := ?, template IuUP_RFCI rfci := ?,
				template IuUP_FQC fqc := ?) := {
	type_0 := {
		pdu_type := 0,
		frame_nr := frame_nr,
		fqc := fqc,
		rfci := rfci,
		header_crc := ?,
		payload_crc := ?,
		payload := ?
	}
};

template IuUP_PDU ts_IuUP_Type1(IuUP_FrameNr frame_nr, IuUP_RFCI rfci, octetstring payload,
				IuUP_FQC fqc := IuUP_FQC_GOOD) := {
	type_1 := {
		pdu_type := 1,
		frame_nr := frame_nr,
		fqc := fqc,
		rfci := rfci,
		header_crc := 0,
		spare := '00'B,
		payload := payload
	}
};


template IuUP_PDU tr_IuUP_Type1(template IuUP_FrameNr frame_nr := ?, template IuUP_RFCI rfci := ?,
				template IuUP_FQC fqc := ?) := {
	type_1 := {
		pdu_type := 1,
		frame_nr := frame_nr,
		fqc := fqc,
		rfci := rfci,
		header_crc := ?,
		spare := ?,
		payload := ?
	}
};



} with { encode "RAW" ; variant "FIELDORDER(msb)" }