blob: ca722e7433e5c55a9c089117beac4ac9820dba9a [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();
Vadim Yanitskiy41b702f2022-02-07 14:16:14 +0600353 f_perform_clear(RSL);
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200354}
355
356/* Modify a primary lchan into VAMOS speech mode */
357testcase TC_mode_modify_to_vamos_fr() runs on test_CT {
358 var TestHdlrParams pars := f_gen_test_hdlr_pars();
359 var MSC_ConnHdlr vc_conn;
360
361 f_init(1, true);
362 f_sleep(1.0);
363
364 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
365 vc_conn := f_start_handler(refers(f_TC_mode_modify_to_vamos), pars);
366 vc_conn.done;
367 f_shutdown_helper();
368}
369
370/* Modify a primary lchan into VAMOS speech mode */
371testcase TC_mode_modify_to_vamos_hr() runs on test_CT {
372 var TestHdlrParams pars := f_gen_test_hdlr_pars();
373 var MSC_ConnHdlr vc_conn;
374
375 f_init(1, true);
376 f_sleep(1.0);
377
378 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
379 vc_conn := f_start_handler(refers(f_TC_mode_modify_to_vamos), pars);
380 vc_conn.done;
381 f_shutdown_helper();
382}
383
384/* Establish a primary lchan, and then do a re-assignment to a VAMOS shadow lchan. */
385private function f_reassign_secondary_to_primary_lchan(RslChannelNr new_chan_nr) runs on MSC_ConnHdlr
386{
387 var integer current_subslot := f_rsl_chan_nr_to_subslot(g_chan_nr);
388
389 var integer new_subslot := f_rsl_chan_nr_to_subslot(new_chan_nr);
390 var BIT5 new_rr_cbits := f_rsl_chan_nr_to_rr_cbits(new_chan_nr);
391
392 activate(as_Media_mgw());
393
394 f_rslem_register(0, new_chan_nr, RSL_PROC);
395 log("f_rslem_register(0, new_chan_nr = ", new_chan_nr, ")");
396
397 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot " & int2str(g_chan_nr.tn) & " vamos-sub-slot " & int2str(current_subslot)
398 & " reassign-to trx 0 timeslot " & int2str(new_chan_nr.tn) & " sub-slot " & int2str(new_subslot));
399 /* RSL CHAN ACT is ACKed by RSL emulation */
400
401 var RSL_Message rsl;
402 var RSL_IE_Body ie;
403 var boolean b_unused;
404 interleave {
405 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
406 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
407 var template PDU_ML3_NW_MS expect_rr_assignment := tr_RR_AssignmentCommand(
408 desc := tr_ChannelDescription2_V(timeslotNumber := int2bit(new_chan_nr.tn, 3),
409 channelTypeandTDMAOffset := new_rr_cbits),
410 mode := tr_ChannelMode_TV(mode := '01'O
411 /* 0 0 0 0 0 0 0 1 speech full rate or half rate version 1 (3GPP TS 44.018) */),
412 extendedTSCSet := omit);
413 if (not match(l3, expect_rr_assignment)) {
414 log("expected: ", expect_rr_assignment);
415 log("got: ", l3);
416 setverdict(fail, "RR assignmentCommand message is not as expected");
417 mtc.stop;
418 }
419
420 var PDU_ML3_MS_NW l3_tx := valueof(ts_RRM_AssignmentComplete('00'O));
421 RSL.send(ts_RSL_EST_IND(new_chan_nr, valueof(ts_RslLinkID_DCCH(0)),
422 enc_PDU_ML3_MS_NW(l3_tx)));
423
424 }
425 [] RSL.receive(tr_RSL_IPA_CRCX(new_chan_nr)) -> value rsl {
426 var uint7_t rtp_pt := 0;
427 if (f_rsl_find_ie(rsl, RSL_IE_IPAC_RTP_PAYLOAD, ie)) {
428 rtp_pt := ie.ipa_rtp_pt;
429 }
430 RSL.send(ts_RSL_IPA_CRCX_ACK(new_chan_nr, 123,
Vadim Yanitskiyfc631642021-07-03 02:42:45 +0200431 f_inet_addr("1.2.3.4"),
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200432 4321,
433 rtp_pt));
434 }
435 [] RSL.receive(tr_RSL_IPA_MDCX(new_chan_nr, ?)) -> value rsl{
436 /* Extract conn_id, ip, port, rtp_pt2 from request + use in response */
437 b_unused := f_rsl_find_ie(rsl, RSL_IE_IPAC_CONN_ID, ie);
438 var uint16_t conn_id := ie.ipa_conn_id;
439 /* mandatory */
440 b_unused := f_rsl_find_ie(rsl, RSL_IE_IPAC_REMOTE_IP, ie);
441 var HostPort peer;
Vadim Yanitskiyfc631642021-07-03 02:42:45 +0200442 peer.host := f_inet_ntoa(ie.ipa_remote_ip);
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200443 b_unused := f_rsl_find_ie(rsl, RSL_IE_IPAC_REMOTE_PORT, ie);
444 peer.port_nr := ie.ipa_remote_port;
445 var uint7_t rtp_pt := 0;
446 /* optional */
447 if (f_rsl_find_ie(rsl, RSL_IE_IPAC_RTP_PAYLOAD, ie)) {
448 rtp_pt := ie.ipa_rtp_pt;
449 }
450 RSL.send(ts_RSL_IPA_MDCX_ACK(new_chan_nr, conn_id,
Vadim Yanitskiyfc631642021-07-03 02:42:45 +0200451 f_inet_addr(peer.host),
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200452 peer.port_nr,
453 rtp_pt));
454 }
455 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
456 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200457 RSL.send(ts_ASP_RSL_UD(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr),
458 IPAC_PROTO_RSL_TRX0));
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200459 f_rslem_unregister(0, g_chan_nr, RSL_PROC);
460 g_chan_nr := new_chan_nr;
461 }
462 /* (There must be no RSL_MT_REL_REQ on the old lchan.) */
463 }
464
465 setverdict(pass);
466
467 f_sleep(1.0);
468 f_vty_transceive(BSCVTY, "show lchan summary");
469
470 f_verify_dtap();
471}
472
473private function f_est_and_reassign_to_secondary_lchan(RslChannelNr new_chan_nr) runs on MSC_ConnHdlr
474{
475 var integer new_subslot := f_rsl_chan_nr_to_subslot(new_chan_nr);
476 var BIT5 new_rr_cbits := f_rsl_chan_nr_to_rr_cbits(new_chan_nr);
477
478 var PDU_BSSAP ass_cmd := f_gen_ass_req();
479 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
480
481 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
482 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
483 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
484 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
485 g_pars.ass_codec_list.codecElements[0];
486 if (isvalue(g_pars.expect_mr_s0_s7)) {
487 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
488 g_pars.expect_mr_s0_s7;
489 }
490 }
491 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
492 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
493 log("expecting ASS COMPL like this: ", exp_compl);
494
495 f_establish_fully(ass_cmd, exp_compl);
496
497 var integer current_subslot := f_rsl_chan_nr_to_subslot(g_chan_nr);
498
499 f_sleep(1.0);
500
501 activate(as_Media_mgw());
502
503 f_rslem_register(0, new_chan_nr, RSL_PROC);
504 log("f_rslem_register(0, new_chan_nr = ", new_chan_nr, ")");
505
506 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot " & int2str(g_chan_nr.tn) & " sub-slot " & int2str(current_subslot)
507 & " reassign-to trx 0 timeslot " & int2str(new_chan_nr.tn) & " vamos-sub-slot " & int2str(new_subslot) & " tsc 4 2");
508 /* RSL CHAN ACT is ACKed by RSL emulation */
509
510 var RSL_Message rsl;
511 var RSL_IE_Body ie;
512 var boolean b_unused;
513 interleave {
514 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
515 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
516 var template PDU_ML3_NW_MS expect_rr_assignment := tr_RR_AssignmentCommand(
517 desc := tr_ChannelDescription2_V(timeslotNumber := int2bit(new_chan_nr.tn, 3),
518 channelTypeandTDMAOffset := new_rr_cbits),
519 mode := tr_ChannelMode_TV(mode := 'C1'O
520 /* 1 1 0 0 0 0 0 1 speech full rate or half rate version 1 in VAMOS mode (3GPP TS 44.018) */),
521 extendedTSCSet := tr_ExtendedTSCSet_TV(cSDomainTSCSet := '11'B
522 /* 3 means TSC Set 4 (range 1-4 in spec tables and naming, 0-3 on the wire) */));
523 if (not match(l3, expect_rr_assignment)) {
524 log("expected: ", expect_rr_assignment);
525 log("got: ", l3);
526 setverdict(fail, "RR assignmentCommand message is not as expected");
527 mtc.stop;
528 }
529
530 var PDU_ML3_MS_NW l3_tx := valueof(ts_RRM_AssignmentComplete('00'O));
531 RSL.send(ts_RSL_EST_IND(new_chan_nr, valueof(ts_RslLinkID_DCCH(0)),
532 enc_PDU_ML3_MS_NW(l3_tx)));
533
534 }
535 [] RSL.receive(tr_RSL_IPA_CRCX(new_chan_nr)) -> value rsl {
536 var uint7_t rtp_pt := 0;
537 if (f_rsl_find_ie(rsl, RSL_IE_IPAC_RTP_PAYLOAD, ie)) {
538 rtp_pt := ie.ipa_rtp_pt;
539 }
540 RSL.send(ts_RSL_IPA_CRCX_ACK(new_chan_nr, 123,
Vadim Yanitskiyfc631642021-07-03 02:42:45 +0200541 f_inet_addr("1.2.3.4"),
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200542 4321,
543 rtp_pt));
544 }
545 [] RSL.receive(tr_RSL_IPA_MDCX(new_chan_nr, ?)) -> value rsl{
546 /* Extract conn_id, ip, port, rtp_pt2 from request + use in response */
547 b_unused := f_rsl_find_ie(rsl, RSL_IE_IPAC_CONN_ID, ie);
548 var uint16_t conn_id := ie.ipa_conn_id;
549 /* mandatory */
550 b_unused := f_rsl_find_ie(rsl, RSL_IE_IPAC_REMOTE_IP, ie);
551 var HostPort peer;
Vadim Yanitskiyfc631642021-07-03 02:42:45 +0200552 peer.host := f_inet_ntoa(ie.ipa_remote_ip);
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200553 b_unused := f_rsl_find_ie(rsl, RSL_IE_IPAC_REMOTE_PORT, ie);
554 peer.port_nr := ie.ipa_remote_port;
555 var uint7_t rtp_pt := 0;
556 /* optional */
557 if (f_rsl_find_ie(rsl, RSL_IE_IPAC_RTP_PAYLOAD, ie)) {
558 rtp_pt := ie.ipa_rtp_pt;
559 }
560 RSL.send(ts_RSL_IPA_MDCX_ACK(new_chan_nr, conn_id,
Vadim Yanitskiyfc631642021-07-03 02:42:45 +0200561 f_inet_addr(peer.host),
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200562 peer.port_nr,
563 rtp_pt));
564 }
565 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
566 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200567 RSL.send(ts_ASP_RSL_UD(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr),
568 IPAC_PROTO_RSL_TRX0));
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200569 f_rslem_unregister(0, g_chan_nr, RSL_PROC);
570 g_chan_nr := new_chan_nr;
571 }
572 /* (There must be no RSL_MT_REL_REQ on the old lchan.) */
573 }
574
575 setverdict(pass);
576
577 f_sleep(1.0);
578 f_vty_transceive(BSCVTY, "show lchan summary");
579
580 f_verify_dtap();
581}
582
583/* Establish a primary lchan, and then do a re-assignment to a VAMOS shadow lchan.
584 * Also re-assign back to a primary lchan. */
585private function f_TC_assign_to_secondary_lchan_fr(charstring id) runs on MSC_ConnHdlr {
586 f_est_and_reassign_to_secondary_lchan(valueof(t_RslChanNr_Osmo_VAMOS_Bm(2)));
587 f_reassign_secondary_to_primary_lchan(valueof(t_RslChanNr_Bm(3)));
588 f_perform_clear(RSL);
589 f_sleep(1.0);
590}
591
592/* Establish a primary lchan, and then do a re-assignment to a VAMOS shadow lchan. */
593testcase TC_assign_to_secondary_lchan_fr() runs on test_CT {
594 var TestHdlrParams pars := f_gen_test_hdlr_pars();
595 var MSC_ConnHdlr vc_conn;
596
597 f_init(1, true);
598 f_sleep(1.0);
599
600 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
601 vc_conn := f_start_handler(refers(f_TC_assign_to_secondary_lchan_fr), pars);
602 vc_conn.done;
603 f_shutdown_helper();
604}
605
606/* Establish a primary lchan, and then do a re-assignment to a VAMOS shadow lchan.
607 * Also re-assign back to a primary lchan. */
608private function f_TC_assign_to_secondary_lchan_hr(charstring id) runs on MSC_ConnHdlr {
609 f_est_and_reassign_to_secondary_lchan(valueof(t_RslChanNr_Osmo_VAMOS_Lm(6, 0)));
610 f_reassign_secondary_to_primary_lchan(valueof(t_RslChanNr_Lm(6, 1)));
611 f_perform_clear(RSL);
612 f_sleep(1.0);
613}
614
615/* Establish a primary lchan, and then do a re-assignment to a VAMOS shadow lchan. */
616testcase TC_assign_to_secondary_lchan_hr() runs on test_CT {
617 var TestHdlrParams pars := f_gen_test_hdlr_pars();
618 var MSC_ConnHdlr vc_conn;
619
620 f_init(1, true);
621 f_sleep(1.0);
622
623 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
624 vc_conn := f_start_handler(refers(f_TC_assign_to_secondary_lchan_hr), pars);
625 vc_conn.done;
626 f_shutdown_helper();
627}
628
629/* First, primary lchan of TC_vamos_multiplex_tch_f_tch_f() */
630private function f_TC_vamos_multiplex_tch_f_tch_f1(charstring id) runs on MSC_ConnHdlr {
631 f_est_lchan_and_mode_modify_to_vamos();
632 f_logp(BSCVTY, "f_est_lchan_and_mode_modify_to_vamos done");
633}
634
635/* Second, VAMOS shadow lchan of TC_vamos_multiplex_tch_f_tch_f() */
636private function f_TC_vamos_multiplex_tch_f_tch_f2(charstring id) runs on MSC_ConnHdlr {
637 f_est_and_reassign_to_secondary_lchan(valueof(t_RslChanNr_Osmo_VAMOS_Bm(1)));
638}
639
640/* Establish a primary lchan and modify it to VAMOS speech mode. Then establish
641 * another primary lchan, and re-assign it to the VAMOS secondary lchan of the
642 * first primary lchan. */
643testcase TC_vamos_multiplex_tch_f_tch_f() runs on test_CT {
644 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
645 var MSC_ConnHdlr vc_conn1;
646
647 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
648 var MSC_ConnHdlr vc_conn2;
649 pars2.imsi := '001014234234234'H;
650 pars2.media_nr := 2;
651
652 f_init(1, true);
653 f_sleep(1.0);
654
655 pars1.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
656 pars2.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
657 vc_conn1 := f_start_handler(refers(f_TC_vamos_multiplex_tch_f_tch_f1), pars1);
658 vc_conn1.done;
659
660 vc_conn2 := f_start_handler(refers(f_TC_vamos_multiplex_tch_f_tch_f2), pars2);
661 vc_conn2.done;
662 f_shutdown_helper();
663}
664
665/* First, primary lchan of TC_vamos_multiplex_tch_h_tch_h_tch_h_tch_h() */
666private function f_TC_vamos_multiplex_tch_h_tch_h1(charstring id) runs on MSC_ConnHdlr {
667 f_est_lchan_and_mode_modify_to_vamos();
668 f_logp(BSCVTY, "f_est_lchan_and_mode_modify_to_vamos done");
669}
670
671/* Second, VAMOS shadow lchan of TC_vamos_multiplex_tch_h_tch_h_tch_h_tch_h() */
672private function f_TC_vamos_multiplex_tch_h_tch_h2(charstring id) runs on MSC_ConnHdlr {
673 f_est_and_reassign_to_secondary_lchan(valueof(t_RslChanNr_Osmo_VAMOS_Lm(5, 0)));
674}
675
676private function f_TC_vamos_multiplex_tch_h_tch_h4(charstring id) runs on MSC_ConnHdlr {
677 f_est_and_reassign_to_secondary_lchan(valueof(t_RslChanNr_Osmo_VAMOS_Lm(5, 1)));
678}
679
680/* Establish a primary lchan and modify it to VAMOS speech mode. Then establish
681 * another primary lchan, and re-assign it to the VAMOS secondary lchan of the
682 * first primary lchan. */
683testcase TC_vamos_multiplex_tch_h_tch_h_tch_h_tch_h() runs on test_CT {
684 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
685 var MSC_ConnHdlr vc_conn1;
686 pars1.imsi := '001011111111111'H;
687 pars1.media_nr := 1;
688
689 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
690 var MSC_ConnHdlr vc_conn2;
691 pars2.imsi := '001012222222222'H;
692 pars2.media_nr := 2;
693
694 var TestHdlrParams pars3 := f_gen_test_hdlr_pars();
695 var MSC_ConnHdlr vc_conn3;
696 pars3.imsi := '001013333333333'H;
697 pars3.media_nr := 3;
698
699 var TestHdlrParams pars4 := f_gen_test_hdlr_pars();
700 var MSC_ConnHdlr vc_conn4;
701 pars4.imsi := '001014444444444'H;
702 pars4.media_nr := 4;
703
704 f_init(1, true);
705 f_sleep(1.0);
706
707 pars1.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
708 pars2.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
709 pars3.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
710 pars4.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
711
712 vc_conn1 := f_start_handler(refers(f_TC_vamos_multiplex_tch_h_tch_h1), pars1);
713 vc_conn1.done;
714
715 vc_conn2 := f_start_handler(refers(f_TC_vamos_multiplex_tch_h_tch_h2), pars2);
716 vc_conn2.done;
717
718 /* Also fill up the second subslot of the TCH/H timeslot */
719 vc_conn3 := f_start_handler(refers(f_TC_vamos_multiplex_tch_h_tch_h1), pars3);
720 vc_conn3.done;
721
722 vc_conn4 := f_start_handler(refers(f_TC_vamos_multiplex_tch_h_tch_h4), pars4);
723 vc_conn4.done;
724 f_shutdown_helper();
725}
726
727control {
728 execute( TC_chan_act_to_vamos() );
729 execute( TC_mode_modify_to_vamos_fr() );
730 execute( TC_mode_modify_to_vamos_hr() );
731 execute( TC_assign_to_secondary_lchan_fr() );
732 execute( TC_assign_to_secondary_lchan_hr() );
733 execute( TC_vamos_multiplex_tch_f_tch_f() );
734 execute( TC_vamos_multiplex_tch_h_tch_h_tch_h_tch_h() );
735}
736
737}