blob: 25dee234850120152298aff9443f9b7e185700e0 [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
267 f_shutdown_helper();
268}
269
270/* verify that DTAP passes through both ways with the right cbits */
271private function f_verify_dtap() runs on MSC_ConnHdlr
272{
273 var octetstring l3_data := '00010203040506'O;
274 var PDU_BSSAP rx_bssap_dtap;
275
276 /* MS to NW */
277 RSL.send(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3_data));
278 BSSAP.receive(tr_BSSAP_DTAP) -> value rx_bssap_dtap;
279 if (not match(rx_bssap_dtap.pdu.dtap, l3_data)) {
280 setverdict(fail, "unexpected L3 data");
281 mtc.stop;
282 }
283
284 /* NW to MS */
285 l3_data := '0800dcba9876543210'O;
286 BSSAP.send(ts_BSSAP_DTAP(l3_data, '00'O));
287 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, tr_RslLinkID_DCCH(0), l3_data));
288}
289
290
291private function f_est_lchan_and_mode_modify_to_vamos() runs on MSC_ConnHdlr {
292 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux);
293 var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux);
294
295 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
296 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
297 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
298 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
299 g_pars.ass_codec_list.codecElements[0];
300 if (isvalue(g_pars.expect_mr_s0_s7)) {
301 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
302 g_pars.expect_mr_s0_s7;
303 }
304 }
305 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
306 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
307 log("expecting ASS COMPL like this: ", exp_compl);
308
309 f_establish_fully(ass_cmd, exp_compl);
310
311 f_lchan_ensure_established(BSCVTY, 0, 0, g_chan_nr);
312
313 var charstring current_long_lchan_str := f_long_lchan_str(0, 0, g_chan_nr);
314 f_vty_transceive(BSCVTY, current_long_lchan_str & " modify vamos tsc 2 3");
315
316 var RSL_Message rsl_rr;
317 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl_rr;
318
319 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl_rr.ies[2].body.l3_info.payload);
320
321 var integer current_subslot := f_rsl_chan_nr_to_subslot(g_chan_nr);
322
323 template PDU_ML3_NW_MS expect_rr_modify := tr_RRM_ModeModify(
324 tr_ChannelDescription2_V(timeslotNumber := int2bit(g_chan_nr.tn, 3)),
325 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) */),
326 extendedTSCSet := tr_ExtendedTSCSet_TV(cSDomainTSCSet := '01'B));
327
328 if (not match(l3, expect_rr_modify)) {
329 log("expected: ", expect_rr_modify);
330 log("got: ", l3);
331 setverdict(fail, "RR channelModeModify message is not as expected");
332 mtc.stop;
333 }
334 f_rsl_reply(ts_RRM_ModeModifyAck(l3.msgs.rrm.channelModeModify.channelDescription,
335 l3.msgs.rrm.channelModeModify.channelMode,
336 l3.msgs.rrm.channelModeModify.extendedTSCSet), rsl_rr);
337
338 var RSL_Message rsl;
339 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),
340 tsc_set := 1, /* 1 means TSC Set 2 (range 1-4 in spec tables and naming, 0-3 on the wire) */
341 tsc := 3));
342 RSL.send(ts_RSL_MODE_MODIFY_ACK(g_chan_nr));
343 f_sleep(1.0);
344
345 f_lchan_ensure_established(BSCVTY, 0, 0, g_chan_nr);
346 f_verify_dtap();
347}
348
349private function f_TC_mode_modify_to_vamos(charstring id) runs on MSC_ConnHdlr {
350 f_est_lchan_and_mode_modify_to_vamos();
351}
352
353/* Modify a primary lchan into VAMOS speech mode */
354testcase TC_mode_modify_to_vamos_fr() runs on test_CT {
355 var TestHdlrParams pars := f_gen_test_hdlr_pars();
356 var MSC_ConnHdlr vc_conn;
357
358 f_init(1, true);
359 f_sleep(1.0);
360
361 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
362 vc_conn := f_start_handler(refers(f_TC_mode_modify_to_vamos), pars);
363 vc_conn.done;
364 f_shutdown_helper();
365}
366
367/* Modify a primary lchan into VAMOS speech mode */
368testcase TC_mode_modify_to_vamos_hr() runs on test_CT {
369 var TestHdlrParams pars := f_gen_test_hdlr_pars();
370 var MSC_ConnHdlr vc_conn;
371
372 f_init(1, true);
373 f_sleep(1.0);
374
375 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
376 vc_conn := f_start_handler(refers(f_TC_mode_modify_to_vamos), pars);
377 vc_conn.done;
378 f_shutdown_helper();
379}
380
381/* Establish a primary lchan, and then do a re-assignment to a VAMOS shadow lchan. */
382private function f_reassign_secondary_to_primary_lchan(RslChannelNr new_chan_nr) runs on MSC_ConnHdlr
383{
384 var integer current_subslot := f_rsl_chan_nr_to_subslot(g_chan_nr);
385
386 var integer new_subslot := f_rsl_chan_nr_to_subslot(new_chan_nr);
387 var BIT5 new_rr_cbits := f_rsl_chan_nr_to_rr_cbits(new_chan_nr);
388
389 activate(as_Media_mgw());
390
391 f_rslem_register(0, new_chan_nr, RSL_PROC);
392 log("f_rslem_register(0, new_chan_nr = ", new_chan_nr, ")");
393
394 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot " & int2str(g_chan_nr.tn) & " vamos-sub-slot " & int2str(current_subslot)
395 & " reassign-to trx 0 timeslot " & int2str(new_chan_nr.tn) & " sub-slot " & int2str(new_subslot));
396 /* RSL CHAN ACT is ACKed by RSL emulation */
397
398 var RSL_Message rsl;
399 var RSL_IE_Body ie;
400 var boolean b_unused;
401 interleave {
402 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
403 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
404 var template PDU_ML3_NW_MS expect_rr_assignment := tr_RR_AssignmentCommand(
405 desc := tr_ChannelDescription2_V(timeslotNumber := int2bit(new_chan_nr.tn, 3),
406 channelTypeandTDMAOffset := new_rr_cbits),
407 mode := tr_ChannelMode_TV(mode := '01'O
408 /* 0 0 0 0 0 0 0 1 speech full rate or half rate version 1 (3GPP TS 44.018) */),
409 extendedTSCSet := omit);
410 if (not match(l3, expect_rr_assignment)) {
411 log("expected: ", expect_rr_assignment);
412 log("got: ", l3);
413 setverdict(fail, "RR assignmentCommand message is not as expected");
414 mtc.stop;
415 }
416
417 var PDU_ML3_MS_NW l3_tx := valueof(ts_RRM_AssignmentComplete('00'O));
418 RSL.send(ts_RSL_EST_IND(new_chan_nr, valueof(ts_RslLinkID_DCCH(0)),
419 enc_PDU_ML3_MS_NW(l3_tx)));
420
421 }
422 [] RSL.receive(tr_RSL_IPA_CRCX(new_chan_nr)) -> value rsl {
423 var uint7_t rtp_pt := 0;
424 if (f_rsl_find_ie(rsl, RSL_IE_IPAC_RTP_PAYLOAD, ie)) {
425 rtp_pt := ie.ipa_rtp_pt;
426 }
427 RSL.send(ts_RSL_IPA_CRCX_ACK(new_chan_nr, 123,
Vadim Yanitskiyfc631642021-07-03 02:42:45 +0200428 f_inet_addr("1.2.3.4"),
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200429 4321,
430 rtp_pt));
431 }
432 [] RSL.receive(tr_RSL_IPA_MDCX(new_chan_nr, ?)) -> value rsl{
433 /* Extract conn_id, ip, port, rtp_pt2 from request + use in response */
434 b_unused := f_rsl_find_ie(rsl, RSL_IE_IPAC_CONN_ID, ie);
435 var uint16_t conn_id := ie.ipa_conn_id;
436 /* mandatory */
437 b_unused := f_rsl_find_ie(rsl, RSL_IE_IPAC_REMOTE_IP, ie);
438 var HostPort peer;
Vadim Yanitskiyfc631642021-07-03 02:42:45 +0200439 peer.host := f_inet_ntoa(ie.ipa_remote_ip);
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200440 b_unused := f_rsl_find_ie(rsl, RSL_IE_IPAC_REMOTE_PORT, ie);
441 peer.port_nr := ie.ipa_remote_port;
442 var uint7_t rtp_pt := 0;
443 /* optional */
444 if (f_rsl_find_ie(rsl, RSL_IE_IPAC_RTP_PAYLOAD, ie)) {
445 rtp_pt := ie.ipa_rtp_pt;
446 }
447 RSL.send(ts_RSL_IPA_MDCX_ACK(new_chan_nr, conn_id,
Vadim Yanitskiyfc631642021-07-03 02:42:45 +0200448 f_inet_addr(peer.host),
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200449 peer.port_nr,
450 rtp_pt));
451 }
452 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
453 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200454 RSL.send(ts_ASP_RSL_UD(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr),
455 IPAC_PROTO_RSL_TRX0));
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200456 f_rslem_unregister(0, g_chan_nr, RSL_PROC);
457 g_chan_nr := new_chan_nr;
458 }
459 /* (There must be no RSL_MT_REL_REQ on the old lchan.) */
460 }
461
462 setverdict(pass);
463
464 f_sleep(1.0);
465 f_vty_transceive(BSCVTY, "show lchan summary");
466
467 f_verify_dtap();
468}
469
470private function f_est_and_reassign_to_secondary_lchan(RslChannelNr new_chan_nr) runs on MSC_ConnHdlr
471{
472 var integer new_subslot := f_rsl_chan_nr_to_subslot(new_chan_nr);
473 var BIT5 new_rr_cbits := f_rsl_chan_nr_to_rr_cbits(new_chan_nr);
474
475 var PDU_BSSAP ass_cmd := f_gen_ass_req();
476 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
477
478 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
479 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
480 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
481 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
482 g_pars.ass_codec_list.codecElements[0];
483 if (isvalue(g_pars.expect_mr_s0_s7)) {
484 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
485 g_pars.expect_mr_s0_s7;
486 }
487 }
488 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
489 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
490 log("expecting ASS COMPL like this: ", exp_compl);
491
492 f_establish_fully(ass_cmd, exp_compl);
493
494 var integer current_subslot := f_rsl_chan_nr_to_subslot(g_chan_nr);
495
496 f_sleep(1.0);
497
498 activate(as_Media_mgw());
499
500 f_rslem_register(0, new_chan_nr, RSL_PROC);
501 log("f_rslem_register(0, new_chan_nr = ", new_chan_nr, ")");
502
503 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot " & int2str(g_chan_nr.tn) & " sub-slot " & int2str(current_subslot)
504 & " reassign-to trx 0 timeslot " & int2str(new_chan_nr.tn) & " vamos-sub-slot " & int2str(new_subslot) & " tsc 4 2");
505 /* RSL CHAN ACT is ACKed by RSL emulation */
506
507 var RSL_Message rsl;
508 var RSL_IE_Body ie;
509 var boolean b_unused;
510 interleave {
511 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
512 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
513 var template PDU_ML3_NW_MS expect_rr_assignment := tr_RR_AssignmentCommand(
514 desc := tr_ChannelDescription2_V(timeslotNumber := int2bit(new_chan_nr.tn, 3),
515 channelTypeandTDMAOffset := new_rr_cbits),
516 mode := tr_ChannelMode_TV(mode := 'C1'O
517 /* 1 1 0 0 0 0 0 1 speech full rate or half rate version 1 in VAMOS mode (3GPP TS 44.018) */),
518 extendedTSCSet := tr_ExtendedTSCSet_TV(cSDomainTSCSet := '11'B
519 /* 3 means TSC Set 4 (range 1-4 in spec tables and naming, 0-3 on the wire) */));
520 if (not match(l3, expect_rr_assignment)) {
521 log("expected: ", expect_rr_assignment);
522 log("got: ", l3);
523 setverdict(fail, "RR assignmentCommand message is not as expected");
524 mtc.stop;
525 }
526
527 var PDU_ML3_MS_NW l3_tx := valueof(ts_RRM_AssignmentComplete('00'O));
528 RSL.send(ts_RSL_EST_IND(new_chan_nr, valueof(ts_RslLinkID_DCCH(0)),
529 enc_PDU_ML3_MS_NW(l3_tx)));
530
531 }
532 [] RSL.receive(tr_RSL_IPA_CRCX(new_chan_nr)) -> value rsl {
533 var uint7_t rtp_pt := 0;
534 if (f_rsl_find_ie(rsl, RSL_IE_IPAC_RTP_PAYLOAD, ie)) {
535 rtp_pt := ie.ipa_rtp_pt;
536 }
537 RSL.send(ts_RSL_IPA_CRCX_ACK(new_chan_nr, 123,
Vadim Yanitskiyfc631642021-07-03 02:42:45 +0200538 f_inet_addr("1.2.3.4"),
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200539 4321,
540 rtp_pt));
541 }
542 [] RSL.receive(tr_RSL_IPA_MDCX(new_chan_nr, ?)) -> value rsl{
543 /* Extract conn_id, ip, port, rtp_pt2 from request + use in response */
544 b_unused := f_rsl_find_ie(rsl, RSL_IE_IPAC_CONN_ID, ie);
545 var uint16_t conn_id := ie.ipa_conn_id;
546 /* mandatory */
547 b_unused := f_rsl_find_ie(rsl, RSL_IE_IPAC_REMOTE_IP, ie);
548 var HostPort peer;
Vadim Yanitskiyfc631642021-07-03 02:42:45 +0200549 peer.host := f_inet_ntoa(ie.ipa_remote_ip);
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200550 b_unused := f_rsl_find_ie(rsl, RSL_IE_IPAC_REMOTE_PORT, ie);
551 peer.port_nr := ie.ipa_remote_port;
552 var uint7_t rtp_pt := 0;
553 /* optional */
554 if (f_rsl_find_ie(rsl, RSL_IE_IPAC_RTP_PAYLOAD, ie)) {
555 rtp_pt := ie.ipa_rtp_pt;
556 }
557 RSL.send(ts_RSL_IPA_MDCX_ACK(new_chan_nr, conn_id,
Vadim Yanitskiyfc631642021-07-03 02:42:45 +0200558 f_inet_addr(peer.host),
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200559 peer.port_nr,
560 rtp_pt));
561 }
562 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
563 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200564 RSL.send(ts_ASP_RSL_UD(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr),
565 IPAC_PROTO_RSL_TRX0));
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200566 f_rslem_unregister(0, g_chan_nr, RSL_PROC);
567 g_chan_nr := new_chan_nr;
568 }
569 /* (There must be no RSL_MT_REL_REQ on the old lchan.) */
570 }
571
572 setverdict(pass);
573
574 f_sleep(1.0);
575 f_vty_transceive(BSCVTY, "show lchan summary");
576
577 f_verify_dtap();
578}
579
580/* Establish a primary lchan, and then do a re-assignment to a VAMOS shadow lchan.
581 * Also re-assign back to a primary lchan. */
582private function f_TC_assign_to_secondary_lchan_fr(charstring id) runs on MSC_ConnHdlr {
583 f_est_and_reassign_to_secondary_lchan(valueof(t_RslChanNr_Osmo_VAMOS_Bm(2)));
584 f_reassign_secondary_to_primary_lchan(valueof(t_RslChanNr_Bm(3)));
585 f_perform_clear(RSL);
586 f_sleep(1.0);
587}
588
589/* Establish a primary lchan, and then do a re-assignment to a VAMOS shadow lchan. */
590testcase TC_assign_to_secondary_lchan_fr() runs on test_CT {
591 var TestHdlrParams pars := f_gen_test_hdlr_pars();
592 var MSC_ConnHdlr vc_conn;
593
594 f_init(1, true);
595 f_sleep(1.0);
596
597 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
598 vc_conn := f_start_handler(refers(f_TC_assign_to_secondary_lchan_fr), pars);
599 vc_conn.done;
600 f_shutdown_helper();
601}
602
603/* Establish a primary lchan, and then do a re-assignment to a VAMOS shadow lchan.
604 * Also re-assign back to a primary lchan. */
605private function f_TC_assign_to_secondary_lchan_hr(charstring id) runs on MSC_ConnHdlr {
606 f_est_and_reassign_to_secondary_lchan(valueof(t_RslChanNr_Osmo_VAMOS_Lm(6, 0)));
607 f_reassign_secondary_to_primary_lchan(valueof(t_RslChanNr_Lm(6, 1)));
608 f_perform_clear(RSL);
609 f_sleep(1.0);
610}
611
612/* Establish a primary lchan, and then do a re-assignment to a VAMOS shadow lchan. */
613testcase TC_assign_to_secondary_lchan_hr() runs on test_CT {
614 var TestHdlrParams pars := f_gen_test_hdlr_pars();
615 var MSC_ConnHdlr vc_conn;
616
617 f_init(1, true);
618 f_sleep(1.0);
619
620 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
621 vc_conn := f_start_handler(refers(f_TC_assign_to_secondary_lchan_hr), pars);
622 vc_conn.done;
623 f_shutdown_helper();
624}
625
626/* First, primary lchan of TC_vamos_multiplex_tch_f_tch_f() */
627private function f_TC_vamos_multiplex_tch_f_tch_f1(charstring id) runs on MSC_ConnHdlr {
628 f_est_lchan_and_mode_modify_to_vamos();
629 f_logp(BSCVTY, "f_est_lchan_and_mode_modify_to_vamos done");
630}
631
632/* Second, VAMOS shadow lchan of TC_vamos_multiplex_tch_f_tch_f() */
633private function f_TC_vamos_multiplex_tch_f_tch_f2(charstring id) runs on MSC_ConnHdlr {
634 f_est_and_reassign_to_secondary_lchan(valueof(t_RslChanNr_Osmo_VAMOS_Bm(1)));
635}
636
637/* Establish a primary lchan and modify it to VAMOS speech mode. Then establish
638 * another primary lchan, and re-assign it to the VAMOS secondary lchan of the
639 * first primary lchan. */
640testcase TC_vamos_multiplex_tch_f_tch_f() runs on test_CT {
641 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
642 var MSC_ConnHdlr vc_conn1;
643
644 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
645 var MSC_ConnHdlr vc_conn2;
646 pars2.imsi := '001014234234234'H;
647 pars2.media_nr := 2;
648
649 f_init(1, true);
650 f_sleep(1.0);
651
652 pars1.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
653 pars2.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
654 vc_conn1 := f_start_handler(refers(f_TC_vamos_multiplex_tch_f_tch_f1), pars1);
655 vc_conn1.done;
656
657 vc_conn2 := f_start_handler(refers(f_TC_vamos_multiplex_tch_f_tch_f2), pars2);
658 vc_conn2.done;
659 f_shutdown_helper();
660}
661
662/* First, primary lchan of TC_vamos_multiplex_tch_h_tch_h_tch_h_tch_h() */
663private function f_TC_vamos_multiplex_tch_h_tch_h1(charstring id) runs on MSC_ConnHdlr {
664 f_est_lchan_and_mode_modify_to_vamos();
665 f_logp(BSCVTY, "f_est_lchan_and_mode_modify_to_vamos done");
666}
667
668/* Second, VAMOS shadow lchan of TC_vamos_multiplex_tch_h_tch_h_tch_h_tch_h() */
669private function f_TC_vamos_multiplex_tch_h_tch_h2(charstring id) runs on MSC_ConnHdlr {
670 f_est_and_reassign_to_secondary_lchan(valueof(t_RslChanNr_Osmo_VAMOS_Lm(5, 0)));
671}
672
673private function f_TC_vamos_multiplex_tch_h_tch_h4(charstring id) runs on MSC_ConnHdlr {
674 f_est_and_reassign_to_secondary_lchan(valueof(t_RslChanNr_Osmo_VAMOS_Lm(5, 1)));
675}
676
677/* Establish a primary lchan and modify it to VAMOS speech mode. Then establish
678 * another primary lchan, and re-assign it to the VAMOS secondary lchan of the
679 * first primary lchan. */
680testcase TC_vamos_multiplex_tch_h_tch_h_tch_h_tch_h() runs on test_CT {
681 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
682 var MSC_ConnHdlr vc_conn1;
683 pars1.imsi := '001011111111111'H;
684 pars1.media_nr := 1;
685
686 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
687 var MSC_ConnHdlr vc_conn2;
688 pars2.imsi := '001012222222222'H;
689 pars2.media_nr := 2;
690
691 var TestHdlrParams pars3 := f_gen_test_hdlr_pars();
692 var MSC_ConnHdlr vc_conn3;
693 pars3.imsi := '001013333333333'H;
694 pars3.media_nr := 3;
695
696 var TestHdlrParams pars4 := f_gen_test_hdlr_pars();
697 var MSC_ConnHdlr vc_conn4;
698 pars4.imsi := '001014444444444'H;
699 pars4.media_nr := 4;
700
701 f_init(1, true);
702 f_sleep(1.0);
703
704 pars1.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
705 pars2.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
706 pars3.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
707 pars4.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
708
709 vc_conn1 := f_start_handler(refers(f_TC_vamos_multiplex_tch_h_tch_h1), pars1);
710 vc_conn1.done;
711
712 vc_conn2 := f_start_handler(refers(f_TC_vamos_multiplex_tch_h_tch_h2), pars2);
713 vc_conn2.done;
714
715 /* Also fill up the second subslot of the TCH/H timeslot */
716 vc_conn3 := f_start_handler(refers(f_TC_vamos_multiplex_tch_h_tch_h1), pars3);
717 vc_conn3.done;
718
719 vc_conn4 := f_start_handler(refers(f_TC_vamos_multiplex_tch_h_tch_h4), pars4);
720 vc_conn4.done;
721 f_shutdown_helper();
722}
723
724control {
725 execute( TC_chan_act_to_vamos() );
726 execute( TC_mode_modify_to_vamos_fr() );
727 execute( TC_mode_modify_to_vamos_hr() );
728 execute( TC_assign_to_secondary_lchan_fr() );
729 execute( TC_assign_to_secondary_lchan_hr() );
730 execute( TC_vamos_multiplex_tch_f_tch_f() );
731 execute( TC_vamos_multiplex_tch_h_tch_h_tch_h_tch_h() );
732}
733
734}