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