blob: 6814295bbfc49f8aeb43206a6ef69371e6c158f0 [file] [log] [blame]
Harald Welte5a1d7272023-05-10 19:49:44 +02001module BTS_Tests_ASCI {
2
3/* ASCI Integration Tests for OsmoBTS
4 *
5 * (C) 2023 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
6 * All Rights Reserved
7 *
8 * SPDX-License-Identifier: AGPL-3.0+
9 *
10 * Authors: Harald Welte; Andreas Eversberg
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU Affero General Public License as published by
14 * the Free Software Foundation; either version 3 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Affero General Public License for more details.
21 *
22 * You should have received a copy of the GNU Affero General Public License
23 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 */
25
26import from Misc_Helpers all;
27import from General_Types all;
28import from Osmocom_Types all;
29import from GSM_Types all;
30import from L1CTL_PortType all;
31import from L1CTL_Types all;
32import from LAPDm_Types all;
33import from IPA_Emulation all;
34import from GSM_RR_Types all;
35import from L3_Templates all;
36
37import from MobileL3_CommonIE_Types all;
38
39import from RSL_Emulation all;
40import from RSL_Types all;
41
42import from BTS_Tests all;
43
44
45
46/* convert from boolean value to BIT1 */
47private function bool2bit1(boolean inp) return BIT1 {
48 if (inp) {
49 return '1'B;
50 } else {
51 return '0'B;
52 }
53}
54
55/* encode a VBS/VGCS call reference into it's OCT5 representation */
56private function f_enc_gcr(integer call_ref, boolean is_group_call, boolean ack_required := false)
57return OCT5
58{
59 var DescriptiveGroupOrBroadcastCallReference_V v := {
60 binaryCodingOfGroupOrBroadcastCallReference := int2bit(call_ref, 27),
61 sF := bool2bit1(is_group_call),
62 aF := bool2bit1(ack_required),
63 callPriority := '000'B,
64 cipheringInformation := '0000'B,
65 spare := '0000'B
66 }
67 return bit2oct(encvalue(v));
68}
69
70/* Send Notification command to start and stop notifying an ASCI call.
71 * When it starts, it is expected that NCH is received by MS. Also it is expected that NCH is received again.
72 * When it stops, it is expected that NCH is not received anymore. */
73testcase TC_vbs_notification() runs on test_CT
74{
75 timer T;
76
77 f_init();
78 f_init_l1ctl();
79 f_l1_tune(L1CTL);
80
81 var OCT5 gcr := f_enc_gcr(hex2int('2342'H), false, false);
82 var OCT3 chan_desc := '234266'O;
83 var octetstring notif_nch := '090620B42230000091A1330B2B2B2B2B2B2B2B2B2B2B2B'O;
84 var integer recv_count := 0;
85
86 log("Sending RSL NOTIF_CMD (start)");
87 RSL_CCHAN.send(ts_ASP_RSL_UD(ts_RSL_NOTIF_CMD_START(gcr, chan_desc)));
88
89 /* NCH must be received twice. */
90 T.start(2.0);
91 alt {
92 [] L1CTL.receive(tr_L1CTL_DATA_IND(t_RslChanNr_PCH_AGCH(0), ?, notif_nch)) {
93 log("Received matching NOTIFICATION/NCH.");
94 recv_count := recv_count + 1;
95 if (recv_count != 2) {
96 repeat;
97 }
98 T.stop;
99 }
100 [] L1CTL.receive { repeat; }
101 [] T.timeout {
102 setverdict(fail, "Timeout waiting for NCH message");
103 }
104 }
105
106 log("Sending RSL NOTIF_CMD (stop)");
107 RSL_CCHAN.send(ts_ASP_RSL_UD(ts_RSL_NOTIF_CMD_STOP(gcr)));
108
109 /* Flush pending messages and be sure that the sending of notifications has stopped. */
110 f_sleep(1.0);
111 L1CTL.clear;
112
113 /* NCH must not be received. */
114 T.start(2.0);
115 alt {
116 [] L1CTL.receive(tr_L1CTL_DATA_IND(t_RslChanNr_PCH_AGCH(0), ?, notif_nch)) {
117 T.stop;
118 setverdict(fail, "Received unexpected NOTIFICATION/NCH.");
119 }
120 [] L1CTL.receive { repeat; }
121 [] T.timeout {
122 log("Not received NOTIFICATION/NCH. (as expected)");
123 setverdict(pass);
124 }
125 }
126
127 Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
128}
129
Andreas Eversberg4801baa2023-07-17 11:45:38 +0200130/* Sub function to clean up MS and BTS. */
131private function f_vgcs_cleanup() runs on ConnHdlr
132{
133 /* Cleanup L1CTL. */
134 f_L1CTL_RESET(L1CTL);
135 f_l1_tune(L1CTL);
136
137 /* Cleanup VGCS Channel. */
138 f_rsl_chan_deact();
139}
140
141/* A VGCS channel is activated. The BSC sends UPLINK FREE message and UPLINK BUSY message.
142 * When the UPLINK FREE message is sent, the MS is expected to receive several UPLINK FREE messages.
143 * Then the UPLINK BUSY message is sent, the MS is expected to receive one UPLINK BUSY message.
144 */
145private function f_TC_vgcs_uplink_free_and_busy(charstring id) runs on ConnHdlr
146{
147 var octetstring uplink_free := '082B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B'O;
148 var octetstring uplink_busy := '062A'O;
149
150 f_l1_tune(L1CTL);
151 RSL.clear;
152
153 /* Activate channel on the BTS side */
154 log("Activating VGCS channel.");
155 f_rsl_chan_act(g_pars.chan_mode);
156
157 /* enable dedicated mode */
158 f_l1ctl_est_dchan(L1CTL, g_pars);
159
160 /* Send one UPLINK FREE message and expect them to be repeated. */
161 log("Send UPLINK FREE.");
162 RSL.send(ts_RSL_UNITDATA_REQ(g_chan_nr, ts_RslLinkID_DCCH(0), uplink_free));
163 for (var integer i := 0; i < 20; i := i + 1) {
164 f_l1_exp_lapdm(tr_LAPDm_Bter_UI(uplink_free));
165 log("Received UPLINK FREE.");
166 }
167
168 /* Send one UPLINK BUSY message and expect it to be received. */
169 log("Send UPLINK BUSY.");
170 RSL.send(ts_RSL_UNITDATA_REQ(g_chan_nr, ts_RslLinkID_DCCH(0), uplink_busy));
171 f_l1_exp_lapdm(tr_LAPDm_UI(0, cr_MT_CMD, uplink_busy));
172 log("Received UPLINK BUSY.");
173
174 /* Deactivate and cleanup. */
175 f_vgcs_cleanup();
176}
177testcase TC_vgcs_uplink_free_and_busy() runs on test_CT
178{
179 var template RSL_IE_ChannelMode ch_mode;
180 var ConnHdlrPars pars;
181 var ConnHdlr vc_conn;
182
183 f_init();
184
185 ch_mode := ts_RSL_ChanMode(RSL_CHRT_TCH_F_GROUP, RSL_CMOD_SP_GSM1);
186 pars := valueof(t_Pars(t_RslChanNr_Bm(1), ch_mode));
187 vc_conn := f_start_handler(refers(f_TC_vgcs_uplink_free_and_busy), pars);
188 vc_conn.done;
189
190 Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
191}
192
Andreas Eversberg7766e3d2023-07-18 09:02:14 +0200193/* Sub function to test talker detect. */
194private function f_vgcs_talker_detect() runs on ConnHdlr
195{
196 var octetstring uplink_free := '082B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B'O;
197 var octetstring uplink_access := 'C0'O;
198 var template octetstring uplink_grant := '0609C0*'O;
199 var RSL_Message rm;
200 var GsmFrameNumber fn;
201
202 f_l1_tune(L1CTL);
203 RSL.clear;
204
205 /* Activate channel on the BTS side. */
206 log("Activating VGCS channel.");
207 f_rsl_chan_act(g_pars.chan_mode);
208
209 /* Enable dedicated mode. */
210 f_l1ctl_est_dchan(L1CTL, g_pars);
211
212 /* Send one UPLINK FREE message and expect them to be repeated. */
213 log("Send UPLINK FREE.");
214 RSL.send(ts_RSL_UNITDATA_REQ(g_chan_nr, ts_RslLinkID_DCCH(0), uplink_free));
215 f_l1_exp_lapdm(tr_LAPDm_Bter_UI(uplink_free));
216 log("Received UPLINK FREE.");
217
218 /* Send UPLINK ACCESS on VGCS channel. */
219 log("Send UPLINK ACCESS.");
220 fn := f_L1CTL_RACH(L1CTL, oct2int(uplink_access), chan_nr := g_pars.chan_nr);
221
222 /* Receive UPLINK GRANT by the MS. */
223 f_l1_exp_lapdm(tr_LAPDm_UI(0, cr_MT_CMD, uplink_grant));
224 log("Received VGCS UPLINK GRANT.");
225
226 /* Wait for talker detection. */
227 timer T := 1.0;
228 T.start;
229 alt {
230 [] RSL.receive(tr_RSL_TALKER_DET(g_pars.chan_nr, ?)) -> value rm {
231 log("RSL Talker Detect has been detected: ", rm);
232 T.stop;
233 }
234 [] RSL.receive(tr_RSL_CHAN_RQD(?, ?, ?, ?)) -> value rm {
235 setverdict(fail, "RSL_CHAN_RQD was not expected: ", rm);
236 T.stop;
237 }
238 [] RSL.receive { repeat; }
239 [] T.timeout {
240 setverdict(fail, "Timeout waiting for RSL Talker Detect.");
241 }
242 }
243}
244
245/* A VGCS channel is activated. The BSC sends UPLINK FREE message. The MS sends RACH on VGCS channel.
246 * The MS receives VGCS UPLINK GRAND, but does not respond to it. It is expeced that the BSC receivce RSL CONN FAIL.
247 */
248private function f_TC_vgcs_talker_fail(charstring id) runs on ConnHdlr
249{
250 var RSL_Message rm;
251
252 /* Perform link establishment and talker detection. */
253 f_vgcs_talker_detect();
254
255 /* Leave dedicated channel, to force link timeout. */
256 f_L1CTL_RESET(L1CTL);
257 f_l1_tune(L1CTL);
258
259 /* Wait for link timeout. */
260 timer T := 40.0;
261 T.start;
262 alt {
263 [] RSL.receive(tr_RSL_CONN_FAIL_IND(g_pars.chan_nr, ?)) -> value rm {
264 log("RSL Conn Fail Ind has been detected as expected: ", rm);
265 T.stop;
266 }
267 [] RSL.receive { repeat; }
268 [] T.timeout {
269 setverdict(fail, "Timeout waiting for RSL Conn Fail Ind.");
270 }
271 }
272
273 /* Deactivate and cleanup. */
274 f_vgcs_cleanup();
275}
276testcase TC_vgcs_talker_fail() runs on test_CT
277{
278 var template RSL_IE_ChannelMode ch_mode;
279 var ConnHdlrPars pars;
280 var ConnHdlr vc_conn;
281
282 f_init();
283
284 ch_mode := ts_RSL_ChanMode(RSL_CHRT_TCH_F_GROUP, RSL_CMOD_SP_GSM1);
285 pars := valueof(t_Pars(t_RslChanNr_Bm(1), ch_mode));
286 pars.t_guard := 60.0;
287 vc_conn := f_start_handler(refers(f_TC_vgcs_talker_fail), pars);
288 vc_conn.done;
289
290 Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
291}
292
Andreas Eversberg083202a2023-07-18 14:47:57 +0200293/* A VGCS channel is activated. The BSC sends UPLINK FREE message. The MS sends RACH on VGCS channel.
294 * The MS receives VGCS UPLINK GRAND and establishes layer 2. Then the BSC forces to releases the uplink.
295 */
296private function f_TC_vgcs_talker_est_rel(charstring id) runs on ConnHdlr
297{
298 var octetstring uplink_free := '082B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B'O;
299 var octetstring l3 := '01020304'O;
300 template RslLinkId link_id := ts_RslLinkID_DCCH(0);
301 var RSL_Message rm;
302
303 /* Perform link establishment and talker detection. */
304 f_vgcs_talker_detect();
305
306 /* Establish layer 2. It also detects, if RSL Est Ind is received. */
307 f_est_rll_mo(0, valueof(link_id), l3);
308
309 /* Release link by BSC. */
310 RSL.send(ts_RSL_REL_REQ(g_chan_nr, link_id, RSL_REL_MODE_LOCAL));
311
312 log("Send UPLINK FREE.");
313 RSL.send(ts_RSL_UNITDATA_REQ(g_chan_nr, link_id, uplink_free));
314 f_l1_exp_lapdm(tr_LAPDm_Bter_UI(uplink_free));
315 log("Received UPLINK FREE.");
316
317 /* Deactivate and cleanup. */
318 f_vgcs_cleanup();
319}
320testcase TC_vgcs_talker_est_rel() runs on test_CT
321{
322 var template RSL_IE_ChannelMode ch_mode;
323 var ConnHdlrPars pars;
324 var ConnHdlr vc_conn;
325
326 f_init();
327
328 ch_mode := ts_RSL_ChanMode(RSL_CHRT_TCH_F_GROUP, RSL_CMOD_SP_GSM1);
329 pars := valueof(t_Pars(t_RslChanNr_Bm(1), ch_mode));
330 vc_conn := f_start_handler(refers(f_TC_vgcs_talker_est_rel), pars);
331 vc_conn.done;
332
333 Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
334}
335
Andreas Eversberg92c2dca2023-07-18 15:29:57 +0200336private function f_TC_vgcs_listener_det(charstring id) runs on ConnHdlr
337{
338 var octetstring uplink_access := '25'O;
339 var RSL_Message rm;
340 var GsmFrameNumber fn;
341
342 f_l1_tune(L1CTL);
343 RSL.clear;
344
345 /* Activate channel on the BTS side. */
346 log("Activating VGCS channel.");
347 f_rsl_chan_act(g_pars.chan_mode);
348
349 /* Enable dedicated mode. */
350 f_l1ctl_est_dchan(L1CTL, g_pars);
351
352 /* Send UPLINK ACCESS on VGCS channel. */
353 log("Send UPLINK ACCESS.");
354 fn := f_L1CTL_RACH(L1CTL, oct2int(uplink_access), chan_nr := g_pars.chan_nr);
355
356 /* Wait for listener detection. */
357 timer T := 2.0;
358 T.start;
359 alt {
360 [] RSL.receive(tr_RSL_LISTENER_DET(g_pars.chan_nr, ?)) -> value rm {
361 log("RSL Talker Listener has been detected: ", rm);
362 T.stop;
363 }
364 [] RSL.receive(tr_RSL_CHAN_RQD(?, ?, ?, ?)) -> value rm {
365 setverdict(fail, "RSL_CHAN_RQD was not expected: ", rm);
366 T.stop;
367 }
368 [] RSL.receive { repeat; }
369 [] T.timeout {
370 setverdict(fail, "Timeout waiting for RSL Listener Detect.");
371 }
372 }
373
374 /* Send UPLINK ACCESS on VGCS channel. */
375 log("Send second UPLINK ACCESS.");
376 fn := f_L1CTL_RACH(L1CTL, oct2int(uplink_access), chan_nr := g_pars.chan_nr);
377
378 /* Wait for listener detection. */
379 T.start;
380 alt {
381 [] RSL.receive(tr_RSL_LISTENER_DET(g_pars.chan_nr, ?)) {
382 setverdict(fail, "RSL Listener Detect has been detected, but not expected!");
383 T.stop;
384 }
385 [] RSL.receive(tr_RSL_CHAN_RQD(?, ?, ?, ?)) -> value rm {
386 setverdict(fail, "RSL_CHAN_RQD was not expected: ", rm);
387 T.stop;
388 }
389 [] RSL.receive { repeat; }
390 [] T.timeout {
391 log("Timeout waiting for RSL Listener Detect, as expected.");
392 }
393 }
394
395 /* Deactivate and cleanup. */
396 f_vgcs_cleanup();
397}
398testcase TC_vgcs_listener_det() runs on test_CT
399{
400 var template RSL_IE_ChannelMode ch_mode;
401 var ConnHdlrPars pars;
402 var ConnHdlr vc_conn;
403
404 f_init();
405
406 ch_mode := ts_RSL_ChanMode(RSL_CHRT_TCH_F_GROUP, RSL_CMOD_SP_GSM1);
407 pars := valueof(t_Pars(t_RslChanNr_Bm(1), ch_mode));
408 vc_conn := f_start_handler(refers(f_TC_vgcs_listener_det), pars);
409 vc_conn.done;
410
411 Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
412}
413
Harald Welte5a1d7272023-05-10 19:49:44 +0200414control {
415 execute( TC_vbs_notification() );
Andreas Eversberg4801baa2023-07-17 11:45:38 +0200416 execute( TC_vgcs_uplink_free_and_busy() );
Andreas Eversberg7766e3d2023-07-18 09:02:14 +0200417 execute( TC_vgcs_talker_fail() );
Andreas Eversberg083202a2023-07-18 14:47:57 +0200418 execute( TC_vgcs_talker_est_rel() );
Andreas Eversberg92c2dca2023-07-18 15:29:57 +0200419 execute( TC_vgcs_listener_det() );
Harald Welte5a1d7272023-05-10 19:49:44 +0200420
421}
422
423}