blob: 99fe92d103de9786af25157ca2941c8210c0d15a [file] [log] [blame]
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +02001module BSC_Tests_VAMOS {
2
3/* Integration Tests for OsmoBSC
4 * (C) 2021 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
5 * All rights reserved.
6 *
7 * Released under the terms of GNU General Public License, Version 2 or
8 * (at your option) any later version.
9 *
10 * SPDX-License-Identifier: GPL-2.0-or-later
11 *
12 * This test suite tests OsmoBSC while emulating both multiple BTS + MS as
13 * well as the MSC. See README for more details.
14 *
15 * There are test cases that run in so-called 'handler mode' and test cases
16 * that run directly on top of the BSSAP and RSL CodecPorts. The "handler mode"
17 * tests abstract the multiplexing/demultiplexing of multiple SCCP connections
18 * and/or RSL channels and are hence suitable for higher-level test cases, while
19 * the "raw" tests directly on top of the CodecPorts are more suitable for lower-
20 * level testing.
21 */
22
23import from BSC_Tests all;
24
25import from Misc_Helpers all;
26import from General_Types all;
27import from Osmocom_Types all;
28import from GSM_Types all;
29import from IPL4asp_Types all;
30
31import from BSSAP_Types all;
32import from RAN_Adapter all;
33import from BSSAP_LE_Adapter all;
34import from BSSAP_LE_CodecPort all;
35import from BSSAP_LE_Types all;
36import from BSSLAP_Types all;
37import from BSSAP_CodecPort all;
38import from BSSMAP_Templates all;
39import from IPA_Emulation all;
40import from IPA_CodecPort all;
41import from IPA_Types all;
42import from IPA_Testing all;
43import from RSL_Types all;
44import from RSL_Emulation all;
45import from MGCP_Emulation all;
46import from MGCP_Templates all;
47import from MGCP_Types all;
48import from MGCP_CodecPort all;
49
50import from Osmocom_CTRL_Functions all;
51import from Osmocom_CTRL_Types all;
52import from Osmocom_CTRL_Adapter all;
53
54import from StatsD_Types all;
55import from StatsD_CodecPort all;
56import from StatsD_CodecPort_CtrlFunct all;
57import from StatsD_Checker all;
58
59import from Osmocom_VTY_Functions all;
60import from TELNETasp_PortType all;
61
62import from MobileL3_CommonIE_Types all;
63import from MobileL3_Types all;
64import from MobileL3_RRM_Types all;
65import from L3_Templates all;
66import from GSM_RR_Types all;
67
68import from SCCP_Templates all;
69import from BSSMAP_Templates all;
70import from BSSMAP_LE_Templates all;
71
72import from SCCPasp_Types all;
73
74import from GSM_SystemInformation all;
75import from GSM_RestOctets all;
76import from TCCConversion_Functions all;
77
78import from RAN_Emulation all;
79import from MSC_ConnectionHandler all;
80
81import from Native_Functions all;
82
83const integer NUM_BTS := 3;
84const integer NUM_MSC := 3;
85
86private function f_rsl_chan_nr_to_subslot(RslChannelNr chan_nr)
87return integer
88{
89 var integer subslot;
90 select (chan_nr) {
91 case (t_RslChanNr_Bm(?)) {
92 /* TCH/F, always subslot 0 */
93 subslot := 0;
94 }
95 case (t_RslChanNr_Lm(?, ?)) {
96 /* TCH/H */
97 subslot := chan_nr.u.lm.sub_chan;
98 }
99 case (t_RslChanNr_Osmo_VAMOS_Bm(?)) {
100 /* TCH/F, always subslot 0 */
101 subslot := 0;
102 }
103 case (t_RslChanNr_Osmo_VAMOS_Lm(?, ?)) {
104 /* TCH/H */
105 subslot := chan_nr.u.lm.sub_chan;
106 }
107 case else {
108 setverdict(fail, "unsupported RslChannelNr type in f_rsl_chan_nr_to_subslot()");
109 mtc.stop;
110 }
111 }
112 return subslot;
113}
114
115private function f_rsl_chan_nr_to_rsl_cbits(RslChannelNr chan_nr)
116return BIT5
117{
118 var BIT5 rsl_cbits;
119 select (chan_nr) {
120 case (t_RslChanNr_Bm(?)) {
121 rsl_cbits := '00001'B;
122 }
123 case (t_RslChanNr_Lm(?, ?)) {
124 rsl_cbits := int2bit(2 + chan_nr.u.lm.sub_chan, 5); /* '0001x'B */
125 }
126 case (t_RslChanNr_Osmo_VAMOS_Bm(?)) {
127 rsl_cbits := '11101'B;
128 }
129 case (t_RslChanNr_Osmo_VAMOS_Lm(?, ?)) {
130 rsl_cbits := int2bit(30 + chan_nr.u.lm.sub_chan, 5); /* '1111x'B */
131 }
132 case else {
133 setverdict(fail, "unsupported RslChannelNr type in f_rsl_chan_nr_to_rsl_cbits()");
134 mtc.stop;
135 }
136 }
137 return rsl_cbits;
138}
139
140private function f_rsl_chan_nr_to_rr_cbits(RslChannelNr chan_nr)
141return BIT5
142{
143 var BIT5 rr_cbits;
144 select (chan_nr) {
145 case (t_RslChanNr_Bm(?)) {
146 rr_cbits := '00001'B;
147 }
148 case (t_RslChanNr_Lm(?, ?)) {
149 rr_cbits := int2bit(2 + chan_nr.u.lm.sub_chan, 5); /* '0001x'B */
150 }
151 case (t_RslChanNr_Osmo_VAMOS_Bm(?)) {
152 rr_cbits := '00001'B;
153 /* In RR, there must *not* be Osmocom specific cbits */
154 }
155 case (t_RslChanNr_Osmo_VAMOS_Lm(?, ?)) {
156 rr_cbits := int2bit(2 + chan_nr.u.lm.sub_chan, 5); /* '0001x'B */
157 /* In RR, there must *not* be Osmocom specific cbits */
158 }
159 case else {
160 setverdict(fail, "unsupported RslChannelNr type in f_rsl_chan_nr_to_rr_cbits()");
161 mtc.stop;
162 }
163 }
164 return rr_cbits;
165}
166
167private function f_rsl_chan_nr_to_chrt(RslChannelNr chan_nr, boolean vamos)
168return RSL_ChanRateType
169{
170 var boolean fr;
171 select (chan_nr) {
172 case (t_RslChanNr_Bm(?)) {
173 fr := true;
174 }
175 case (t_RslChanNr_Lm(?, ?)) {
176 fr := false;
177 }
178 case (t_RslChanNr_Osmo_VAMOS_Bm(?)) {
179 fr := true;
180 }
181 case (t_RslChanNr_Osmo_VAMOS_Lm(?, ?)) {
182 fr := false;
183 }
184 case else {
185 setverdict(fail, "unsupported RslChannelNr type in f_rsl_chan_nr_to_chrt()");
186 mtc.stop;
187 }
188 }
189 if (fr) {
190 if (vamos) {
191 return RSL_CHRT_OSMO_TCH_F_VAMOS;
192 } else {
193 return RSL_CHRT_TCH_F;
194 }
195 } else {
196 if (vamos) {
197 return RSL_CHRT_OSMO_TCH_H_VAMOS;
198 } else {
199 return RSL_CHRT_TCH_H;
200 }
201 }
202}
203
204private function f_lchan_str(integer bts_nr, integer trx_nr, RslChannelNr chan_nr)
205return charstring
206{
207 var integer subslot := f_rsl_chan_nr_to_subslot(chan_nr);
208 return "lchan " & int2str(bts_nr) & " " & int2str(trx_nr) & " " & int2str(chan_nr.tn) & " " & int2str(subslot);
209}
210
211private function f_long_lchan_str(integer bts_nr, integer trx_nr, RslChannelNr chan_nr)
212return charstring
213{
214 var integer subslot := f_rsl_chan_nr_to_subslot(chan_nr);
215 return "bts " & int2str(bts_nr) & " trx " & int2str(trx_nr) & " timeslot " & int2str(chan_nr.tn) & " sub-slot " & int2str(subslot);
216}
217
218private function f_lchan_ensure_established(TELNETasp_PT vty, integer bts_nr, integer trx_nr, RslChannelNr chan_nr)
219{
220 var charstring lchan_str := f_lchan_str(bts_nr, trx_nr, chan_nr);
221 var charstring lchan_info := f_vty_transceive_ret(vty, "show " & lchan_str);
222 if (f_strstr(lchan_info, "State: ESTABLISHED") < 0) {
223 log("'show lchan' replied: ", lchan_info);
224 setverdict(fail, "lchan " & lchan_str & " is not in state ESTABLISHED");
225 mtc.stop;
226 }
227 setverdict(pass);
228}
229
230/* Activate a primary lchan in VAMOS speech mode */
231testcase TC_chan_act_to_vamos() runs on test_CT {
232 f_init_vty();
233
234 f_logp(BSCVTY, "TC_chan_act_to_vamos");
235
236 f_init(1, false);
237 f_sleep(1.0);
238
239 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 activate-vamos fr");
240
241 var RSL_Message rsl;
242
243 rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
244
245 var RSL_IE_Body chan_mode_ie;
246 if (f_rsl_find_ie(rsl, RSL_IE_CHAN_MODE, chan_mode_ie) == false) {
247 setverdict(fail, "Cannot find RSL_IE_CHAN_MODE");
248 mtc.stop;
249 }
250 if (chan_mode_ie.chan_mode.ch_rate_type != RSL_CHRT_OSMO_TCH_F_VAMOS) {
251 setverdict(fail, "expected chan_mode.ch_rate_type == RSL_CHRT_OSMO_TCH_F_VAMOS");
252 mtc.stop;
253 }
254
255 var RSL_IE_Body osmo_tsc_ie;
256 if (f_rsl_find_ie(rsl, RSL_IE_OSMO_TRAINING_SEQUENCE, osmo_tsc_ie) == false) {
257 setverdict(fail, "Cannot find RSL_IE_OSMO_TRAINING_SEQUENCE");
258 mtc.stop;
259 }
260
261 var RslChannelNr chan_nr := rsl.ies[0].body.chan_nr;
262 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 23+10));
263
264 f_sleep(1.0);
265 f_lchan_ensure_established(BSCVTY, 0, 0, chan_nr);
266
Vadim Yanitskiyce8eb852022-02-07 14:15:10 +0600267 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 deactivate");
268
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200269 f_shutdown_helper();
270}
271
272/* verify that DTAP passes through both ways with the right cbits */
273private function f_verify_dtap() runs on MSC_ConnHdlr
274{
275 var octetstring l3_data := '00010203040506'O;
276 var PDU_BSSAP rx_bssap_dtap;
277
278 /* MS to NW */
279 RSL.send(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3_data));
280 BSSAP.receive(tr_BSSAP_DTAP) -> value rx_bssap_dtap;
281 if (not match(rx_bssap_dtap.pdu.dtap, l3_data)) {
282 setverdict(fail, "unexpected L3 data");
283 mtc.stop;
284 }
285
286 /* NW to MS */
287 l3_data := '0800dcba9876543210'O;
288 BSSAP.send(ts_BSSAP_DTAP(l3_data, '00'O));
289 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, tr_RslLinkID_DCCH(0), l3_data));
290}
291
292
293private function f_est_lchan_and_mode_modify_to_vamos() runs on MSC_ConnHdlr {
294 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux);
295 var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux);
296
297 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
298 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
299 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
300 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
301 g_pars.ass_codec_list.codecElements[0];
302 if (isvalue(g_pars.expect_mr_s0_s7)) {
303 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
304 g_pars.expect_mr_s0_s7;
305 }
306 }
307 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
308 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
309 log("expecting ASS COMPL like this: ", exp_compl);
310
311 f_establish_fully(ass_cmd, exp_compl);
312
313 f_lchan_ensure_established(BSCVTY, 0, 0, g_chan_nr);
314
315 var charstring current_long_lchan_str := f_long_lchan_str(0, 0, g_chan_nr);
316 f_vty_transceive(BSCVTY, current_long_lchan_str & " modify vamos tsc 2 3");
317
318 var RSL_Message rsl_rr;
319 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl_rr;
320
321 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl_rr.ies[2].body.l3_info.payload);
322
323 var integer current_subslot := f_rsl_chan_nr_to_subslot(g_chan_nr);
324
325 template PDU_ML3_NW_MS expect_rr_modify := tr_RRM_ModeModify(
326 tr_ChannelDescription2_V(timeslotNumber := int2bit(g_chan_nr.tn, 3)),
327 tr_ChannelMode_V(mode := 'C1'O /* 1 1 0 0 0 0 0 1 speech full rate or half rate version 1 in VAMOS mode (3GPP TS 44.018) */),
328 extendedTSCSet := tr_ExtendedTSCSet_TV(cSDomainTSCSet := '01'B));
329
330 if (not match(l3, expect_rr_modify)) {
331 log("expected: ", expect_rr_modify);
332 log("got: ", l3);
333 setverdict(fail, "RR channelModeModify message is not as expected");
334 mtc.stop;
335 }
336 f_rsl_reply(ts_RRM_ModeModifyAck(l3.msgs.rrm.channelModeModify.channelDescription,
337 l3.msgs.rrm.channelModeModify.channelMode,
338 l3.msgs.rrm.channelModeModify.extendedTSCSet), rsl_rr);
339
340 var RSL_Message rsl;
341 RSL.receive(tr_RSL_MODE_MODIFY_REQ_with_OSMO_TSC(g_chan_nr, tr_RSL_ChanMode(f_rsl_chan_nr_to_chrt(g_chan_nr, true), RSL_CMOD_SP_GSM1),
342 tsc_set := 1, /* 1 means TSC Set 2 (range 1-4 in spec tables and naming, 0-3 on the wire) */
343 tsc := 3));
344 RSL.send(ts_RSL_MODE_MODIFY_ACK(g_chan_nr));
345 f_sleep(1.0);
346
347 f_lchan_ensure_established(BSCVTY, 0, 0, g_chan_nr);
348 f_verify_dtap();
349}
350
351private function f_TC_mode_modify_to_vamos(charstring id) runs on MSC_ConnHdlr {
352 f_est_lchan_and_mode_modify_to_vamos();
353}
354
355/* Modify a primary lchan into VAMOS speech mode */
356testcase TC_mode_modify_to_vamos_fr() runs on test_CT {
357 var TestHdlrParams pars := f_gen_test_hdlr_pars();
358 var MSC_ConnHdlr vc_conn;
359
360 f_init(1, true);
361 f_sleep(1.0);
362
363 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
364 vc_conn := f_start_handler(refers(f_TC_mode_modify_to_vamos), pars);
365 vc_conn.done;
366 f_shutdown_helper();
367}
368
369/* Modify a primary lchan into VAMOS speech mode */
370testcase TC_mode_modify_to_vamos_hr() runs on test_CT {
371 var TestHdlrParams pars := f_gen_test_hdlr_pars();
372 var MSC_ConnHdlr vc_conn;
373
374 f_init(1, true);
375 f_sleep(1.0);
376
377 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
378 vc_conn := f_start_handler(refers(f_TC_mode_modify_to_vamos), pars);
379 vc_conn.done;
380 f_shutdown_helper();
381}
382
383/* Establish a primary lchan, and then do a re-assignment to a VAMOS shadow lchan. */
384private function f_reassign_secondary_to_primary_lchan(RslChannelNr new_chan_nr) runs on MSC_ConnHdlr
385{
386 var integer current_subslot := f_rsl_chan_nr_to_subslot(g_chan_nr);
387
388 var integer new_subslot := f_rsl_chan_nr_to_subslot(new_chan_nr);
389 var BIT5 new_rr_cbits := f_rsl_chan_nr_to_rr_cbits(new_chan_nr);
390
391 activate(as_Media_mgw());
392
393 f_rslem_register(0, new_chan_nr, RSL_PROC);
394 log("f_rslem_register(0, new_chan_nr = ", new_chan_nr, ")");
395
396 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot " & int2str(g_chan_nr.tn) & " vamos-sub-slot " & int2str(current_subslot)
397 & " reassign-to trx 0 timeslot " & int2str(new_chan_nr.tn) & " sub-slot " & int2str(new_subslot));
398 /* RSL CHAN ACT is ACKed by RSL emulation */
399
400 var RSL_Message rsl;
401 var RSL_IE_Body ie;
402 var boolean b_unused;
403 interleave {
404 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
405 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
406 var template PDU_ML3_NW_MS expect_rr_assignment := tr_RR_AssignmentCommand(
407 desc := tr_ChannelDescription2_V(timeslotNumber := int2bit(new_chan_nr.tn, 3),
408 channelTypeandTDMAOffset := new_rr_cbits),
409 mode := tr_ChannelMode_TV(mode := '01'O
410 /* 0 0 0 0 0 0 0 1 speech full rate or half rate version 1 (3GPP TS 44.018) */),
411 extendedTSCSet := omit);
412 if (not match(l3, expect_rr_assignment)) {
413 log("expected: ", expect_rr_assignment);
414 log("got: ", l3);
415 setverdict(fail, "RR assignmentCommand message is not as expected");
416 mtc.stop;
417 }
418
419 var PDU_ML3_MS_NW l3_tx := valueof(ts_RRM_AssignmentComplete('00'O));
420 RSL.send(ts_RSL_EST_IND(new_chan_nr, valueof(ts_RslLinkID_DCCH(0)),
421 enc_PDU_ML3_MS_NW(l3_tx)));
422
423 }
424 [] RSL.receive(tr_RSL_IPA_CRCX(new_chan_nr)) -> value rsl {
425 var uint7_t rtp_pt := 0;
426 if (f_rsl_find_ie(rsl, RSL_IE_IPAC_RTP_PAYLOAD, ie)) {
427 rtp_pt := ie.ipa_rtp_pt;
428 }
429 RSL.send(ts_RSL_IPA_CRCX_ACK(new_chan_nr, 123,
Vadim Yanitskiyfc631642021-07-03 02:42:45 +0200430 f_inet_addr("1.2.3.4"),
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200431 4321,
432 rtp_pt));
433 }
434 [] RSL.receive(tr_RSL_IPA_MDCX(new_chan_nr, ?)) -> value rsl{
435 /* Extract conn_id, ip, port, rtp_pt2 from request + use in response */
436 b_unused := f_rsl_find_ie(rsl, RSL_IE_IPAC_CONN_ID, ie);
437 var uint16_t conn_id := ie.ipa_conn_id;
438 /* mandatory */
439 b_unused := f_rsl_find_ie(rsl, RSL_IE_IPAC_REMOTE_IP, ie);
440 var HostPort peer;
Vadim Yanitskiyfc631642021-07-03 02:42:45 +0200441 peer.host := f_inet_ntoa(ie.ipa_remote_ip);
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200442 b_unused := f_rsl_find_ie(rsl, RSL_IE_IPAC_REMOTE_PORT, ie);
443 peer.port_nr := ie.ipa_remote_port;
444 var uint7_t rtp_pt := 0;
445 /* optional */
446 if (f_rsl_find_ie(rsl, RSL_IE_IPAC_RTP_PAYLOAD, ie)) {
447 rtp_pt := ie.ipa_rtp_pt;
448 }
449 RSL.send(ts_RSL_IPA_MDCX_ACK(new_chan_nr, conn_id,
Vadim Yanitskiyfc631642021-07-03 02:42:45 +0200450 f_inet_addr(peer.host),
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200451 peer.port_nr,
452 rtp_pt));
453 }
454 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
455 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200456 RSL.send(ts_ASP_RSL_UD(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr),
457 IPAC_PROTO_RSL_TRX0));
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200458 f_rslem_unregister(0, g_chan_nr, RSL_PROC);
459 g_chan_nr := new_chan_nr;
460 }
461 /* (There must be no RSL_MT_REL_REQ on the old lchan.) */
462 }
463
464 setverdict(pass);
465
466 f_sleep(1.0);
467 f_vty_transceive(BSCVTY, "show lchan summary");
468
469 f_verify_dtap();
470}
471
472private function f_est_and_reassign_to_secondary_lchan(RslChannelNr new_chan_nr) runs on MSC_ConnHdlr
473{
474 var integer new_subslot := f_rsl_chan_nr_to_subslot(new_chan_nr);
475 var BIT5 new_rr_cbits := f_rsl_chan_nr_to_rr_cbits(new_chan_nr);
476
477 var PDU_BSSAP ass_cmd := f_gen_ass_req();
478 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
479
480 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
481 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
482 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
483 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
484 g_pars.ass_codec_list.codecElements[0];
485 if (isvalue(g_pars.expect_mr_s0_s7)) {
486 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
487 g_pars.expect_mr_s0_s7;
488 }
489 }
490 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
491 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
492 log("expecting ASS COMPL like this: ", exp_compl);
493
494 f_establish_fully(ass_cmd, exp_compl);
495
496 var integer current_subslot := f_rsl_chan_nr_to_subslot(g_chan_nr);
497
498 f_sleep(1.0);
499
500 activate(as_Media_mgw());
501
502 f_rslem_register(0, new_chan_nr, RSL_PROC);
503 log("f_rslem_register(0, new_chan_nr = ", new_chan_nr, ")");
504
505 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot " & int2str(g_chan_nr.tn) & " sub-slot " & int2str(current_subslot)
506 & " reassign-to trx 0 timeslot " & int2str(new_chan_nr.tn) & " vamos-sub-slot " & int2str(new_subslot) & " tsc 4 2");
507 /* RSL CHAN ACT is ACKed by RSL emulation */
508
509 var RSL_Message rsl;
510 var RSL_IE_Body ie;
511 var boolean b_unused;
512 interleave {
513 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
514 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
515 var template PDU_ML3_NW_MS expect_rr_assignment := tr_RR_AssignmentCommand(
516 desc := tr_ChannelDescription2_V(timeslotNumber := int2bit(new_chan_nr.tn, 3),
517 channelTypeandTDMAOffset := new_rr_cbits),
518 mode := tr_ChannelMode_TV(mode := 'C1'O
519 /* 1 1 0 0 0 0 0 1 speech full rate or half rate version 1 in VAMOS mode (3GPP TS 44.018) */),
520 extendedTSCSet := tr_ExtendedTSCSet_TV(cSDomainTSCSet := '11'B
521 /* 3 means TSC Set 4 (range 1-4 in spec tables and naming, 0-3 on the wire) */));
522 if (not match(l3, expect_rr_assignment)) {
523 log("expected: ", expect_rr_assignment);
524 log("got: ", l3);
525 setverdict(fail, "RR assignmentCommand message is not as expected");
526 mtc.stop;
527 }
528
529 var PDU_ML3_MS_NW l3_tx := valueof(ts_RRM_AssignmentComplete('00'O));
530 RSL.send(ts_RSL_EST_IND(new_chan_nr, valueof(ts_RslLinkID_DCCH(0)),
531 enc_PDU_ML3_MS_NW(l3_tx)));
532
533 }
534 [] RSL.receive(tr_RSL_IPA_CRCX(new_chan_nr)) -> value rsl {
535 var uint7_t rtp_pt := 0;
536 if (f_rsl_find_ie(rsl, RSL_IE_IPAC_RTP_PAYLOAD, ie)) {
537 rtp_pt := ie.ipa_rtp_pt;
538 }
539 RSL.send(ts_RSL_IPA_CRCX_ACK(new_chan_nr, 123,
Vadim Yanitskiyfc631642021-07-03 02:42:45 +0200540 f_inet_addr("1.2.3.4"),
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200541 4321,
542 rtp_pt));
543 }
544 [] RSL.receive(tr_RSL_IPA_MDCX(new_chan_nr, ?)) -> value rsl{
545 /* Extract conn_id, ip, port, rtp_pt2 from request + use in response */
546 b_unused := f_rsl_find_ie(rsl, RSL_IE_IPAC_CONN_ID, ie);
547 var uint16_t conn_id := ie.ipa_conn_id;
548 /* mandatory */
549 b_unused := f_rsl_find_ie(rsl, RSL_IE_IPAC_REMOTE_IP, ie);
550 var HostPort peer;
Vadim Yanitskiyfc631642021-07-03 02:42:45 +0200551 peer.host := f_inet_ntoa(ie.ipa_remote_ip);
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200552 b_unused := f_rsl_find_ie(rsl, RSL_IE_IPAC_REMOTE_PORT, ie);
553 peer.port_nr := ie.ipa_remote_port;
554 var uint7_t rtp_pt := 0;
555 /* optional */
556 if (f_rsl_find_ie(rsl, RSL_IE_IPAC_RTP_PAYLOAD, ie)) {
557 rtp_pt := ie.ipa_rtp_pt;
558 }
559 RSL.send(ts_RSL_IPA_MDCX_ACK(new_chan_nr, conn_id,
Vadim Yanitskiyfc631642021-07-03 02:42:45 +0200560 f_inet_addr(peer.host),
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200561 peer.port_nr,
562 rtp_pt));
563 }
564 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
565 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200566 RSL.send(ts_ASP_RSL_UD(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr),
567 IPAC_PROTO_RSL_TRX0));
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200568 f_rslem_unregister(0, g_chan_nr, RSL_PROC);
569 g_chan_nr := new_chan_nr;
570 }
571 /* (There must be no RSL_MT_REL_REQ on the old lchan.) */
572 }
573
574 setverdict(pass);
575
576 f_sleep(1.0);
577 f_vty_transceive(BSCVTY, "show lchan summary");
578
579 f_verify_dtap();
580}
581
582/* Establish a primary lchan, and then do a re-assignment to a VAMOS shadow lchan.
583 * Also re-assign back to a primary lchan. */
584private function f_TC_assign_to_secondary_lchan_fr(charstring id) runs on MSC_ConnHdlr {
585 f_est_and_reassign_to_secondary_lchan(valueof(t_RslChanNr_Osmo_VAMOS_Bm(2)));
586 f_reassign_secondary_to_primary_lchan(valueof(t_RslChanNr_Bm(3)));
587 f_perform_clear(RSL);
588 f_sleep(1.0);
589}
590
591/* Establish a primary lchan, and then do a re-assignment to a VAMOS shadow lchan. */
592testcase TC_assign_to_secondary_lchan_fr() runs on test_CT {
593 var TestHdlrParams pars := f_gen_test_hdlr_pars();
594 var MSC_ConnHdlr vc_conn;
595
596 f_init(1, true);
597 f_sleep(1.0);
598
599 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
600 vc_conn := f_start_handler(refers(f_TC_assign_to_secondary_lchan_fr), pars);
601 vc_conn.done;
602 f_shutdown_helper();
603}
604
605/* Establish a primary lchan, and then do a re-assignment to a VAMOS shadow lchan.
606 * Also re-assign back to a primary lchan. */
607private function f_TC_assign_to_secondary_lchan_hr(charstring id) runs on MSC_ConnHdlr {
608 f_est_and_reassign_to_secondary_lchan(valueof(t_RslChanNr_Osmo_VAMOS_Lm(6, 0)));
609 f_reassign_secondary_to_primary_lchan(valueof(t_RslChanNr_Lm(6, 1)));
610 f_perform_clear(RSL);
611 f_sleep(1.0);
612}
613
614/* Establish a primary lchan, and then do a re-assignment to a VAMOS shadow lchan. */
615testcase TC_assign_to_secondary_lchan_hr() runs on test_CT {
616 var TestHdlrParams pars := f_gen_test_hdlr_pars();
617 var MSC_ConnHdlr vc_conn;
618
619 f_init(1, true);
620 f_sleep(1.0);
621
622 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
623 vc_conn := f_start_handler(refers(f_TC_assign_to_secondary_lchan_hr), pars);
624 vc_conn.done;
625 f_shutdown_helper();
626}
627
628/* First, primary lchan of TC_vamos_multiplex_tch_f_tch_f() */
629private function f_TC_vamos_multiplex_tch_f_tch_f1(charstring id) runs on MSC_ConnHdlr {
630 f_est_lchan_and_mode_modify_to_vamos();
631 f_logp(BSCVTY, "f_est_lchan_and_mode_modify_to_vamos done");
632}
633
634/* Second, VAMOS shadow lchan of TC_vamos_multiplex_tch_f_tch_f() */
635private function f_TC_vamos_multiplex_tch_f_tch_f2(charstring id) runs on MSC_ConnHdlr {
636 f_est_and_reassign_to_secondary_lchan(valueof(t_RslChanNr_Osmo_VAMOS_Bm(1)));
637}
638
639/* Establish a primary lchan and modify it to VAMOS speech mode. Then establish
640 * another primary lchan, and re-assign it to the VAMOS secondary lchan of the
641 * first primary lchan. */
642testcase TC_vamos_multiplex_tch_f_tch_f() runs on test_CT {
643 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
644 var MSC_ConnHdlr vc_conn1;
645
646 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
647 var MSC_ConnHdlr vc_conn2;
648 pars2.imsi := '001014234234234'H;
649 pars2.media_nr := 2;
650
651 f_init(1, true);
652 f_sleep(1.0);
653
654 pars1.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
655 pars2.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
656 vc_conn1 := f_start_handler(refers(f_TC_vamos_multiplex_tch_f_tch_f1), pars1);
657 vc_conn1.done;
658
659 vc_conn2 := f_start_handler(refers(f_TC_vamos_multiplex_tch_f_tch_f2), pars2);
660 vc_conn2.done;
661 f_shutdown_helper();
662}
663
664/* First, primary lchan of TC_vamos_multiplex_tch_h_tch_h_tch_h_tch_h() */
665private function f_TC_vamos_multiplex_tch_h_tch_h1(charstring id) runs on MSC_ConnHdlr {
666 f_est_lchan_and_mode_modify_to_vamos();
667 f_logp(BSCVTY, "f_est_lchan_and_mode_modify_to_vamos done");
668}
669
670/* Second, VAMOS shadow lchan of TC_vamos_multiplex_tch_h_tch_h_tch_h_tch_h() */
671private function f_TC_vamos_multiplex_tch_h_tch_h2(charstring id) runs on MSC_ConnHdlr {
672 f_est_and_reassign_to_secondary_lchan(valueof(t_RslChanNr_Osmo_VAMOS_Lm(5, 0)));
673}
674
675private function f_TC_vamos_multiplex_tch_h_tch_h4(charstring id) runs on MSC_ConnHdlr {
676 f_est_and_reassign_to_secondary_lchan(valueof(t_RslChanNr_Osmo_VAMOS_Lm(5, 1)));
677}
678
679/* Establish a primary lchan and modify it to VAMOS speech mode. Then establish
680 * another primary lchan, and re-assign it to the VAMOS secondary lchan of the
681 * first primary lchan. */
682testcase TC_vamos_multiplex_tch_h_tch_h_tch_h_tch_h() runs on test_CT {
683 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
684 var MSC_ConnHdlr vc_conn1;
685 pars1.imsi := '001011111111111'H;
686 pars1.media_nr := 1;
687
688 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
689 var MSC_ConnHdlr vc_conn2;
690 pars2.imsi := '001012222222222'H;
691 pars2.media_nr := 2;
692
693 var TestHdlrParams pars3 := f_gen_test_hdlr_pars();
694 var MSC_ConnHdlr vc_conn3;
695 pars3.imsi := '001013333333333'H;
696 pars3.media_nr := 3;
697
698 var TestHdlrParams pars4 := f_gen_test_hdlr_pars();
699 var MSC_ConnHdlr vc_conn4;
700 pars4.imsi := '001014444444444'H;
701 pars4.media_nr := 4;
702
703 f_init(1, true);
704 f_sleep(1.0);
705
706 pars1.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
707 pars2.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
708 pars3.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
709 pars4.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
710
711 vc_conn1 := f_start_handler(refers(f_TC_vamos_multiplex_tch_h_tch_h1), pars1);
712 vc_conn1.done;
713
714 vc_conn2 := f_start_handler(refers(f_TC_vamos_multiplex_tch_h_tch_h2), pars2);
715 vc_conn2.done;
716
717 /* Also fill up the second subslot of the TCH/H timeslot */
718 vc_conn3 := f_start_handler(refers(f_TC_vamos_multiplex_tch_h_tch_h1), pars3);
719 vc_conn3.done;
720
721 vc_conn4 := f_start_handler(refers(f_TC_vamos_multiplex_tch_h_tch_h4), pars4);
722 vc_conn4.done;
723 f_shutdown_helper();
724}
725
726control {
727 execute( TC_chan_act_to_vamos() );
728 execute( TC_mode_modify_to_vamos_fr() );
729 execute( TC_mode_modify_to_vamos_hr() );
730 execute( TC_assign_to_secondary_lchan_fr() );
731 execute( TC_assign_to_secondary_lchan_hr() );
732 execute( TC_vamos_multiplex_tch_f_tch_f() );
733 execute( TC_vamos_multiplex_tch_h_tch_h_tch_h_tch_h() );
734}
735
736}