aboutsummaryrefslogtreecommitdiffstats
path: root/library/GTPv1U_Templates.ttcn
blob: a31e1d2d435c1554038dff786687a7525394534d (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
/* GTPv1-U Templates in TTCN-3
 * (C) 2018 Harald Welte <laforge@gnumonks.org>
 * contributions by sysmocom - s.f.m.c. GmbH
 * All rights reserved.
 *
 * Released under the terms of GNU General Public License, Version 2 or
 * (at your option) any later version.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

module GTPv1U_Templates {

	import from General_Types all;
	import from Osmocom_Types all;
	import from GTPU_Types all;
	import from GTPv1U_CodecPort all;

	template (present) PDU_GTPU tr_GTP1U_PDU(template (present) OCT1 msg_type,
						 template (present) OCT4 teid,
						 template (present) GTPU_IEs ies := ?) := {
		pn_bit := ?,
		s_bit := ?,
		e_bit := ?,
		spare := ?,
		/* Protocol Type flag (PT) shall be set to '1' in GTP */
		pt := '1'B,
		/* Version shall be set to decimal 1 ('001'). */
		version := '001'B,
		messageType := msg_type,
		lengthf := ?,
		teid := teid,
		opt_part := *,
		gtpu_IEs := ies
	}

	function f_GTPU_s_bit(template (omit) uint16_t seq) return BIT1 {
		if (istemplatekind(seq, "omit")) {
			return '0'B;
		}
		return '1'B;
	}

	function f_GTPU_opt_part(template (omit) uint16_t seq) return template (omit) GTPU_Header_optional_part {
		if (istemplatekind(seq, "omit")) {
			return omit;
		}
		var GTPU_Header_optional_part ret := {
			sequenceNumber := int2oct(valueof(seq), 2),
			npduNumber := '00'O,
			nextExtHeader := '00'O,
			gTPU_extensionHeader_List := omit
		};
		return ret;
	}

	/* generalized GTP-U send template */
	template (value) PDU_GTPU ts_GTP1U_PDU(OCT1 msg_type, template (omit) uint16_t seq, OCT4 teid, GTPU_IEs ies) := {
		/* N-PDU Number flag (PN): the GTP-U header contains a meaningful N-PDU Number field if the PN
		 * flag is set to 1. */
		pn_bit := '0'B,	/* we assume the encoder overwrites this if an optional part is given */
		/* If the Sequence Number flag (S) is set to '1' the sequence number field is present and
		 * meaningful otherwise it is set to '0'. For GTP-U messages Echo Request, Echo Response,
		 * Error Indication and Supported Extension Headers Notification, the S flag shall be set to '1'.
		 *
		 * Note that the caller must ensure that these conditions hold.
		 * The caller can either pass a sequence number (we set s_bit to '1'B) when appropriate,
		 * or may omit the sequence number (we set s_bit to '0'B). */
		s_bit := f_GTPU_s_bit(seq),
		/* Extension header presence */
		e_bit := '0'B,
		spare := '0'B,
		/* Protocol Type flag (PT) shall be set to '1' in GTP */
		pt := '1'B,
		/* Version shall be set to decimal 1 ('001'). */
		version := '001'B,
		messageType := msg_type,
		lengthf := 0,	/* we assume encoder overwrites this */
		teid := teid,
		opt_part := f_GTPU_opt_part(seq),
		gtpu_IEs := ies
	}

	template (present) Gtp1uUnitdata tr_GTPU_MsgType(template (present) Gtp1uPeer peer,
							 template (present) OCT1 msg_type,
							 template (present) OCT4 teid) := {
		peer := peer,
		gtpu := tr_GTP1U_PDU(msg_type, teid)
	}


	/* template matching reception of GTP-U echo-request/response */
	template (present) Gtp1uUnitdata tr_GTPU_PING(template (present) Gtp1uPeer peer) := tr_GTPU_MsgType(peer, '01'O, '00000000'O);
	template (present) Gtp1uUnitdata tr_GTPU_PONG(template (present) Gtp1uPeer peer) := tr_GTPU_MsgType(peer, '02'O, '00000000'O);

	/* template matching reception of GTP-U GPDU */
	template GTPU_IEs t_GPDU(template (present) octetstring data) := {
		g_PDU_IEs := {
			data := data
		}
	}
	template (present) Gtp1uUnitdata tr_GTPU_GPDU(template (present) Gtp1uPeer peer,
						      template (present) OCT4 teid,
						      template (present) octetstring data := ?) := {
		peer := peer,
		gtpu := tr_GTP1U_PDU('FF'O, teid, t_GPDU(data))
	}

	template (present) GTPU_IEs ts_UEchoReqPDU := {
		echoRequest_IEs := {
			private_extension_gtpu := omit
		}
	}

	/* master template for sending a GTP-C echo request */
	template (value) Gtp1uUnitdata ts_GTPU_PING(Gtp1uPeer peer, uint16_t seq) := {
		peer := peer,
		gtpu := ts_GTP1U_PDU('01'O, seq, '00000000'O, valueof(ts_UEchoReqPDU))
	}

	template GTPU_IEs ts_UEchoRespPDU(OCT1 restart_counter) := {
		echoResponse_IEs := {
			recovery_gtpu := {
				type_gtpu := '00'O, /* we assume encoder fixes? */
				restartCounter := restart_counter
			},
			private_extension_gtpu := omit
		}
	}

	/* master template for sending a GTP-U echo response */
	template (present) Gtp1uUnitdata ts_GTPU_PONG(Gtp1uPeer peer, uint16_t seq, OCT1 rest_ctr) := {
		peer := peer,
		gtpu := ts_GTP1U_PDU('02'O, seq, '00000000'O, valueof(ts_UEchoRespPDU(rest_ctr)))
	}

	template (value) GSNAddress_gtpu ts_UGsnAddr(octetstring ip_addr) := {
		type_gtpu := '85'O,
		lengthf := lengthof(ip_addr),
		gSNAddressValue := ip_addr
	}

	template (value) TeidDataI_gtpu ts_UteidDataI(OCT4 teid) := {
		type_gtpu := '10'O,
		teidDataI := teid
	}

	template (value)  GTPU_IEs ts_UErrorIndication(OCT4 teid, octetstring gsn_addr) := {
		errorIndication_IEs := {
			teidDataI_gtpu := ts_UteidDataI(teid),
			gSNAddress_gtpu := ts_UGsnAddr(gsn_addr),
			private_extension_gtpu := omit
		}
	}

	/* master template for sending a GTP-U Error indication */
	template (value) Gtp1uUnitdata ts_GTPU_ErrorIndication(Gtp1uPeer peer, uint16_t seq, OCT4 teid, octetstring gsn_addr) := {
		peer := peer,
		gtpu := ts_GTP1U_PDU('1A'O, seq, '00000000'O, valueof(ts_UErrorIndication(teid, gsn_addr)))
	}

	/* master template for sending a GTP-U user plane data */
	template (value) Gtp1uUnitdata ts_GTP1U_GPDU(Gtp1uPeer peer, template (omit) uint16_t seq, OCT4 teid, octetstring data) := {
		peer := peer,
		gtpu := ts_GTP1U_PDU('FF'O, seq, teid, { g_PDU_IEs := { data := data }})
	}
}