aboutsummaryrefslogtreecommitdiffstats
path: root/pcu/PCU_Tests_NS.ttcn
blob: 4db78d8762956840998965aa810ace54de6337b2 (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
module PCU_Tests_NS {

/* Osmocom PCU test suite for IP Sub-Network-Service (SNS) in TTCN-3
 * (C) 2018-2019 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.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

import from General_Types all;
import from Osmocom_Types all;
import from PCU_Tests all;
import from SGSN_Components all;
import from Osmocom_Gb_Types all;
import from NS_CodecPort all;
import from NS_Types all;
import from BSSGP_Types all;
import from UD_Types all;
import from NS_CodecPort all;
import from NS_CodecPort_CtrlFunct all;
import from NS_Emulation all;
import from Native_Functions all;
import from IPL4asp_Types all;
import from PCUIF_Types all;
import from PCUIF_CodecPort all;
import from RAW_NS all;

modulepar {
	/* tolerate CellID absence/presence in BVC-RESET in violation to spec */
	boolean mp_tolerate_bvc_reset_cellid := false;
}

type component RAW_PCU_CT {
	/* PCUIF (we emulate the BTS part) */
	port PCUIF_CODEC_PT PCU;
	var ConnectionId g_pcu_conn_id := -1;
}

type component RAW_Test_CT extends RAW_NS_CT, RAW_PCU_CT {
}

function f_init_pcuif() runs on RAW_PCU_CT {
	var PCUIF_info_ind info_ind;
	map(self:PCU, system:PCU);


	info_ind := valueof(ts_PCUIF_INFO_default);

	/* Connect the Unix Domain Socket */
	g_pcu_conn_id := f_pcuif_listen(PCU, mp_pcu_sock_path);
	PCU.receive(UD_connected:?);

	/* Wait for PCU_VERSION and return INFO_IND */
	PCU.receive(t_SD_PCUIF(g_pcu_conn_id, tr_PCUIF_TXT_IND(0, PCU_VERSION, ?)));
	/* FIXME: make sure to use parameters from mp_gb_cfg.bvc[0].cell_id in the PCU INFO IND */
	var template PCUIF_Message info_ind_msg := ts_PCUIF_INFO_IND(0, info_ind);
	PCU.send(t_SD_PCUIF(g_pcu_conn_id, info_ind_msg));
}

function f_pcuif_tx(template (value) PCUIF_Message msg) runs on RAW_PCU_CT {
	PCU.send(t_SD_PCUIF(g_pcu_conn_id, msg));
}

/* ensure no matching message is received within 'tout' */
function f_ensure_no_ns(template PDU_NS ns := ?, integer idx := 0, float tout := 3.0)
runs on RAW_Test_CT {
	timer T := tout;
	T.start;
	alt {
	[] NSCP[idx].receive(t_NS_RecvFrom(ns)) {
		setverdict(fail, "NS-ALIVE from unconfigured (possibly initial) endpoint");
		}
	[] T.timeout {
		setverdict(pass);
		}
	}
}

/* test the NS-RESET procedure */
testcase TC_ns_reset() runs on RAW_Test_CT {
	f_init_ns_codec(mp_nsconfig);
	f_init_pcuif();


	/* Expect inbound NS-RESET procedure */
	as_rx_ns_reset_ack(oneshot := true);
	setverdict(pass);
}

/* ensure NS-RESET are re-transmitted */
testcase TC_ns_reset_retrans() runs on RAW_Test_CT {
	f_init_ns_codec(mp_nsconfig);
	f_init_pcuif();

	var integer i;
	for (i := 0; i < 3; i := i+1) {
		NSCP[0].receive(t_NS_RecvFrom(tr_NS_RESET(NS_CAUSE_OM_INTERVENTION,
							g_nsconfig[0].nsvci, g_nsconfig[0].nsei)));
	}

	/* Expect inbound NS-RESET procedure */
	as_rx_ns_reset_ack(oneshot := true);
	setverdict(pass);
}

/* test the inbound NS-ALIVE procedure after NS-RESET */
testcase TC_ns_alive() runs on RAW_Test_CT {
	f_init_ns_codec(mp_nsconfig);
	f_init_pcuif();

	/* Expect inbound NS-RESET procedure */
	as_rx_ns_reset_ack(oneshot := true);

	alt {
	/* wait for one ALIVE cycle, then ACK any further ALIVE in the background */
	[] NSCP[0].receive(t_NS_RecvFrom(t_NS_ALIVE)) { setverdict(pass); };
	[] NSCP[0].receive(t_NS_RecvFrom(t_NS_UNBLOCK)) { repeat; }
	}
}

/* Test for NS-RESET after NS-ALIVE timeout */
testcase TC_ns_alive_timeout_reset() runs on RAW_Test_CT {
	f_init_ns_codec(mp_nsconfig, guard_secs := 100.0);
	f_init_pcuif();

	/* Expect inbound NS-RESET procedure */
	as_rx_ns_reset_ack(oneshot := true);

	/* wait for at least one NS-ALIVE */
	alt {
	[] as_rx_alive_tx_ack(oneshot := true) { };
	[] NSCP[0].receive(t_NS_RecvFrom(t_NS_UNBLOCK)) { repeat; }
	}

	/* wait for NS-RESET to re-appear, ignoring any NS-ALIVE until then */
	alt {
	[] as_rx_ns_reset_ack(oneshot := true) { setverdict(pass); }
	[] NSCP[0].receive(t_NS_RecvFrom(t_NS_ALIVE)) { repeat; }
	[] NSCP[0].receive(t_NS_RecvFrom(t_NS_UNBLOCK)) { repeat; }
	}
}

/* test for NS-RESET/NS-ALIVE/NS-UNBLOCK */
testcase TC_ns_unblock() runs on RAW_Test_CT {
	f_init_ns_codec(mp_nsconfig);
	f_init_pcuif();

	/* Expect inbound NS-RESET procedure */
	as_rx_ns_reset_ack(oneshot := true);

	/* keep it alive */
	activate(as_rx_alive_tx_ack());

	as_rx_ns_unblock_ack(oneshot := true);
	setverdict(pass);
}

/* test for NS-UNBLOCK re-transmissions */
testcase TC_ns_unblock_retrans() runs on RAW_Test_CT {
	f_init_ns_codec(mp_nsconfig);
	f_init_pcuif();

	/* Expect inbound NS-RESET procedure */
	as_rx_ns_reset_ack(oneshot := true);

	/* keep it alive */
	activate(as_rx_alive_tx_ack());

	/* wait for first NS-UNBLOCK, don't respond */
	NSCP[0].receive(t_NS_RecvFrom(t_NS_UNBLOCK));

	/* wait for re-transmission of NS-UNBLOCK */
	as_rx_ns_unblock_ack(oneshot := true);
	setverdict(pass);
}

/* full bring-up of the Gb link for NS and BSSGP layer up to BVC-FC */
testcase TC_ns_full_bringup() runs on RAW_Test_CT {
	f_init_ns_codec(mp_nsconfig);
	f_init_pcuif();

	/* Expect inbound NS-RESET procedure */
	as_rx_ns_reset_ack(oneshot := true);

	/* keep it alive */
	activate(as_rx_alive_tx_ack());

	as_rx_ns_unblock_ack(oneshot := true);

	f_outgoing_ns_alive();

	/* Expect BVC-RESET for signaling (0) and ptp BVCI */
	if (mp_tolerate_bvc_reset_cellid) {
		as_rx_bvc_reset_tx_ack(0, mp_gb_cfg.bvc[0].cell_id, omit, oneshot := true);
	} else {
		as_rx_bvc_reset_tx_ack(0, omit, omit, oneshot := true);
	}
	as_rx_bvc_reset_tx_ack(mp_gb_cfg.bvc[0].bvci, mp_gb_cfg.bvc[0].cell_id, omit, oneshot := true);
	as_rx_bvc_unblock_tx_ack(mp_gb_cfg.bvc[0].bvci, oneshot := true);

	/* wait for one FLOW-CONTROL BVC and then ACK any further in the future */
	as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvc[0].bvci, oneshot := true);
	activate(as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvc[0].bvci));
	setverdict(pass);
}

/* test outbound (SGSN-originated) NS-BLOCK procedure */
testcase TC_ns_so_block() runs on RAW_Test_CT {
	f_init_ns_codec(mp_nsconfig);
	f_init_pcuif();

	/* Expect inbound NS-RESET procedure */
	as_rx_ns_reset_ack(oneshot := true);

	/* keep it alive */
	activate(as_rx_alive_tx_ack());

	as_rx_ns_unblock_ack(oneshot := true);

	f_outgoing_ns_alive();

	f_outgoing_ns_block(NS_CAUSE_EQUIPMENT_FAILURE);
	setverdict(pass);
}


control {
	execute( TC_ns_reset() );
	execute( TC_ns_reset_retrans() );
	execute( TC_ns_alive() );
	execute( TC_ns_alive_timeout_reset() );
	execute( TC_ns_unblock() );
	execute( TC_ns_unblock_retrans() );
	execute( TC_ns_full_bringup() );
	execute( TC_ns_so_block() );
}

}