module BSC_Tests {

/* Integration Tests for OsmoBSC
 * (C) 2017-2018 by Harald Welte <laforge@gnumonks.org>
 * All rights reserved.
 *
 * Released under the terms of GNU General Public License, Version 2 or
 * (at your option) any later version.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 *
 * This test suite tests OsmoBSC while emulating both multiple BTS + MS as
 * well as the MSC. See README for more details.
 *
 * There are test cases that run in so-called 'handler mode' and test cases
 * that run directly on top of the BSSAP and RSL CodecPorts.  The "handler mode"
 * tests abstract the multiplexing/demultiplexing of multiple SCCP connections
 * and/or RSL channels and are hence suitable for higher-level test cases, while
 * the "raw" tests directly on top of the CodecPorts are more suitable for lower-
 * level testing.
 */

import from General_Types all;
import from Osmocom_Types all;
import from GSM_Types all;
import from IPL4asp_Types all;

import from BSSAP_Types all;
import from RAN_Adapter all;
import from BSSAP_CodecPort all;
import from BSSMAP_Templates all;
import from IPA_Emulation all;
import from IPA_CodecPort all;
import from IPA_Types all;
import from IPA_Testing all;
import from RSL_Types all;
import from RSL_Emulation all;
import from MGCP_Emulation all;
import from MGCP_Templates all;
import from MGCP_Types all;
import from MGCP_CodecPort all;

import from Osmocom_CTRL_Functions all;
import from Osmocom_CTRL_Types all;
import from Osmocom_CTRL_Adapter all;

import from Osmocom_VTY_Functions all;
import from TELNETasp_PortType all;

import from MobileL3_CommonIE_Types all;
import from MobileL3_Types all;
import from MobileL3_RRM_Types all;
import from L3_Templates all;
import from GSM_RR_Types all;

import from SCCP_Templates all;
import from BSSMAP_Templates all;

import from SCCPasp_Types all;

const integer NUM_BTS := 3;
const float T3101_MAX := 12.0;

/* make sure to sync this with the osmo-bts.cfg you're using */
const integer NUM_TCHH_PER_BTS := 2;
const integer NUM_TCHF_PER_BTS := 4;
const integer NUM_SDCCH_PER_BTS := 4;


/* per-BTS state which we keep */
type record BTS_State {
	/* component reference to the IPA_Client component used for RSL */
	IPA_Client rsl
}

type component test_CT extends CTRL_Adapter_CT {
	/* Array of per-BTS state */
	var BTS_State bts[NUM_BTS];
	/* RSL common Channel Port (for RSL_Emulation) */
	port RSL_CCHAN_PT RSL_CCHAN[NUM_BTS];
	/* array of per-BTS RSL test ports */
	port IPA_RSL_PT IPA_RSL[NUM_BTS];
	port IPA_CODEC_PT IPA; /* Required for compilation of TC_rsl_unknown_unit_id() */
	/* CTRL muxed over IPA in SCCPlite conn BSC<->MSC (or BSC-NAT) */
	port IPA_CTRL_PT SCCPLITE_IPA_CTRL;

	var MGCP_Emulation_CT vc_MGCP;
	port TELNETasp_PT BSCVTY;

	var RAN_Adapter g_bssap;
	/* for old legacy-tests only */
	port BSSAP_CODEC_PT BSSAP;

	/* are we initialized yet */
	var boolean g_initialized := false;

	/* Osmux is enabled through VTY */
	var boolean g_osmux_enabled := false;

	/*Configure T(tias) over VTY, seconds */
	var integer g_bsc_sccp_timer_ias :=  7 * 60;
	/*Configure T(tiar) over VTY, seconds */
	var integer g_bsc_sccp_timer_iar := 15 * 60;

	/* global test case guard timer */
	timer T_guard := 30.0;

}

modulepar {
	/* IP address at which the BSC can be reached */
	charstring mp_bsc_ip := "127.0.0.1";
	/* port number to which to establish the IPA OML connections */
	integer mp_bsc_oml_port := 3002;
	/* port number to which to establish the IPA RSL connections */
	integer mp_bsc_rsl_port := 3003;
	/* port number to which to establish the IPA CTRL connection */
	integer mp_bsc_ctrl_port := 4249;
	/* IP address at which the test binds */
	charstring mp_test_ip := "127.0.0.1";

	RAN_Configuration mp_bssap_cfg := {
		transport := BSSAP_TRANSPORT_AoIP,
		sccp_service_type := "mtp3_itu",
		sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" },
		own_pc := 185,
		own_ssn := 254,
		peer_pc := 187,
		peer_ssn := 254,
		sio := '83'O,
		rctx := 0
	};

	/* Whether to enable osmux tests. Can be dropped completely and enable
	   unconditionally once new version of osmo-bsc is released (current
	   version: 1.4.1) */
	boolean mp_enable_osmux_test := true;
	/* Value set in osmo-bsc.cfg "ms max power" */
	uint8_t mp_exp_ms_power_level := 7;
}

private function f_gen_test_hdlr_pars() return TestHdlrParams {

	var TestHdlrParams pars := valueof(t_def_TestHdlrPars);
	if (mp_bssap_cfg.transport == BSSAP_TRANSPORT_AoIP) {
		pars.aoip := true;
	} else {
		pars.aoip := false;
	}
	pars.exp_ms_power_level := mp_exp_ms_power_level;

	return pars;
}

private function f_shutdown_helper() runs on test_CT {
	all component.stop;
	setverdict(pass);
	mtc.stop;
}

private function f_legacy_bssap_reset() runs on test_CT {
	var BSSAP_N_UNITDATA_ind ud_ind;
	timer T := 5.0;
	BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap.sccp_addr_peer, g_bssap.sccp_addr_own, ts_BSSMAP_Reset(0, g_osmux_enabled)));
	T.start;
	alt {
	[] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap.sccp_addr_own, g_bssap.sccp_addr_peer, tr_BSSMAP_ResetAck(g_osmux_enabled))) {
		log("Received RESET-ACK in response to RESET, we're ready to go!");
		}
	[] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) -> value ud_ind {
		log("Respoding to inbound RESET with RESET-ACK");
		BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
			   ts_BSSMAP_ResetAck(g_osmux_enabled)));
		repeat;
		}
	[] BSSAP.receive { repeat; }
	[] T.timeout { setverdict(fail, "Waiting for RESET-ACK after sending RESET"); }
	}
}

type record IPA_Client {
	/* IPA Emulation component reference */
	IPA_Emulation_CT vc_IPA,
	/* Unit-ID and other CCM parameters to use for IPA client emulation */
	IPA_CCM_Parameters ccm_pars,
	/* String identifier for this IPA Client */
	charstring id,
	/* Associated RSL Emulation Component (if any). Only used in "Handler mode" */
	RSL_Emulation_CT vc_RSL optional
}

/*! Start the IPA/RSL related bits for one IPA_Client.
 *  \param clnt IPA_Client for which to establish
 *  \param bsc_host IP address / hostname of the BSC
 *  \param bsc_port TCP port number of the BSC
 *  \param i number identifying this BTS
 *  \param handler_mode Start an RSL_Emulation_CT component (true) or not (false) */
function f_ipa_rsl_start(inout IPA_Client clnt, charstring bsc_host, PortNumber bsc_port, integer i,
			 boolean handler_mode := false)
runs on test_CT {
	timer T := 10.0;

	clnt.id := "IPA" & int2str(i) & "-RSL";
	clnt.vc_IPA := IPA_Emulation_CT.create(clnt.id & "-IPA");
	clnt.ccm_pars := c_IPA_default_ccm_pars;
	clnt.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
	clnt.ccm_pars.unit_id := int2str(1234+i) & "/0/0";
	if (handler_mode) {
		clnt.vc_RSL := RSL_Emulation_CT.create(clnt.id & "-RSL");
		connect(clnt.vc_RSL:CCHAN_PT, self:RSL_CCHAN[i]);
	}

	map(clnt.vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
	if (handler_mode) {
		connect(clnt.vc_IPA:IPA_RSL_PORT, clnt.vc_RSL:IPA_PT);
	} else {
		connect(clnt.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[i]);
	}

	clnt.vc_IPA.start(IPA_Emulation.main_client(bsc_host, bsc_port, "", 10000+i, clnt.ccm_pars));
	if (handler_mode) {
		clnt.vc_RSL.start(RSL_Emulation.main());
		return;
	}

	/* wait for IPA RSL link to connect and send ID ACK */
	T.start;
	alt {
	[] IPA_RSL[i].receive(ASP_IPA_Event:{up_down := ASP_IPA_EVENT_ID_ACK}) {
		T.stop;
		IPA_RSL[i].send(ts_ASP_RSL_UD(IPAC_PROTO_RSL_TRX0,ts_RSL_PAGING_LOAD_IND(23)));
		}
	[] IPA_RSL[i].receive(ASP_IPA_Event:?) { repeat }
	[] IPA_RSL[i].receive { repeat }
	[] T.timeout {
		setverdict(fail, "Timeout RSL waiting for ASP_IPA_EVENT_ID_ACK");
		mtc.stop;
		}
	}
}

function f_ipa_rsl_stop(inout IPA_Client clnt) runs on test_CT {
	if (not isbound(clnt) or not isbound(clnt.vc_IPA)) {
		return;
	}
	clnt.vc_IPA.stop;
	if (isbound(clnt.vc_RSL)) {
		clnt.vc_RSL.stop;
	}
}

/* Wait for the OML connection to be brought up by the external osmo-bts-omldummy */
function f_wait_oml(integer bts_nr, charstring status, float secs_max) runs on test_CT {
	timer T := secs_max;
	T.start;
	while (true) {
		if (f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-connection-state") == status) {
			T.stop;
			/* the 'degraded' state exists from OML connection time, and we have to wait
			 * until all MO's are initialized */
			T.start(1.0);
			T.timeout;
			return;
		}
		f_sleep(0.1);
		if (not T.running) {
			setverdict(fail, "Timeout waiting for BTS" & int2str(bts_nr) & " oml-connection-state ", status);
			mtc.stop;
		}
	}
}

/* global altstep for global guard timer; also takes care of responding RESET witH RESET-ACK */
altstep as_Tguard() runs on test_CT {
	var BSSAP_N_UNITDATA_ind ud_ind;
	[] T_guard.timeout {
			setverdict(fail, "Timeout of T_guard");
			mtc.stop;
		}
	/* always respond with RESET ACK to RESET */
	[] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) -> value ud_ind {
		BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
			   ts_BSSMAP_ResetAck(g_osmux_enabled)));
		repeat;
		}
}

altstep no_bssmap_reset() runs on test_CT {
	[] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) {
		setverdict(fail, "unexpected BSSMAP Reset");
		mtc.stop;
	}
}

function f_init_mgcp(charstring id) runs on test_CT {
	id := id & "-MGCP";

	var MGCPOps ops := {
		create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
		unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
	};
	var MGCP_conn_parameters mgcp_pars := {
		callagent_ip := mp_bsc_ip,
		callagent_udp_port := -1,
		mgw_ip := mp_test_ip,
		mgw_udp_port := 2427,
		/* Enable it for SCCPlite, since we have 2 MGCP sockets towards MGW (UDP one +
		   the on  with MGCP over IPA forwarded from MSC one) */
		multi_conn_mode := (mp_bssap_cfg.transport == BSSAP_TRANSPORT_SCCPlite_SERVER)
	};

	vc_MGCP := MGCP_Emulation_CT.create(id);
	vc_MGCP.start(MGCP_Emulation.main(ops, mgcp_pars, id));
}

/* Enable or disable (current default) Osmux. When enabling, BSSMAP Reset
 * contains extra IE (OsmuxSupport) and osmo-bsc will handle AssignReq with
 * OsmuxCID IE.
 */
private function f_vty_allow_osmux(boolean allow) runs on test_CT {
	f_vty_enter_cfg_msc(BSCVTY, 0);
	if (allow) {
		f_vty_transceive(BSCVTY, "osmux on");
	} else {
		f_vty_transceive(BSCVTY, "osmux off");
	}
	f_vty_transceive(BSCVTY, "exit");
	f_vty_transceive(BSCVTY, "exit");
	g_osmux_enabled := allow;
}

function f_init_vty(charstring id := "foo") runs on test_CT {
	if (BSCVTY.checkstate("Mapped")) {
		/* skip initialization if already executed once */
		return;
	}
	map(self:BSCVTY, system:BSCVTY);
	f_vty_set_prompts(BSCVTY);
	f_vty_transceive(BSCVTY, "enable");
	f_cs7_inst_0_cfg(BSCVTY, {"sccp-timer ias " & int2str(g_bsc_sccp_timer_ias),
			  "sccp-timer iar " & int2str(g_bsc_sccp_timer_iar)});
}

/* global initialization function
 * \param nr_bts Number of BTSs we should start/bring up
 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false) */
function f_init(integer nr_bts := NUM_BTS, boolean handler_mode := false, boolean allow_osmux := false) runs on test_CT {
	var integer i;

	if (g_initialized) {
		return;
	}
	g_initialized := true;

	T_guard.start;
	activate(as_Tguard());

	f_init_vty("VirtMSC");
	if (mp_enable_osmux_test) {
		f_vty_allow_osmux(allow_osmux);
	}

	/* Call a function of our 'parent component' RAN_Adapter_CT to start the
	 * MSC-side BSSAP emulation */
	if (handler_mode) {
		var RanOps ranops := MSC_RanOps;
		ranops.use_osmux := g_osmux_enabled;
		f_ran_adapter_init(g_bssap, mp_bssap_cfg, "VirtMSC", ranops);
		connect(self:SCCPLITE_IPA_CTRL, g_bssap.vc_RAN:CTRL_CLIENT);
		f_ran_adapter_start(g_bssap);
	} else {
		f_ran_adapter_init(g_bssap, mp_bssap_cfg, "VirtMSC", omit);
		connect(self:BSSAP, g_bssap.vc_SCCP:SCCP_SP_PORT);
		f_ran_adapter_start(g_bssap);
		f_legacy_bssap_reset();
	}

	f_ipa_ctrl_start(mp_bsc_ip, mp_bsc_ctrl_port);

	f_init_mgcp("VirtMSC");

	for (i := 0; i < nr_bts; i := i+1) {
		/* wait until osmo-bts-omldummy has respawned */
		f_wait_oml(i, "degraded", 5.0);
		/* start RSL connection */
		f_ipa_rsl_start(bts[i].rsl, mp_bsc_ip, mp_bsc_rsl_port, i, handler_mode);
		/* wait until BSC tells us "connected" */
		f_wait_oml(i, "connected", 5.0);
	}

}

/* expect to receive a RSL message matching a specified template on a given BTS / stream */
function f_exp_ipa_rx(integer bts_nr, template RSL_Message t_rx, float t_secs := 2.0, IpaStreamId sid := IPAC_PROTO_RSL_TRX0)
runs on test_CT return RSL_Message {
	var ASP_RSL_Unitdata rx_rsl_ud;
	timer T := t_secs;

	T.start;
	alt {
	[] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(sid, t_rx)) -> value rx_rsl_ud {
		T.stop;
		}
	[] IPA_RSL[bts_nr].receive { repeat; }
	[] T.timeout {
		setverdict(fail, "Timeout expecting ", t_rx);
		mtc.stop;
		}
	}
	return rx_rsl_ud.rsl;
}

/* helper function to transmit RSL on a given BTS/stream */
function f_ipa_tx(integer bts_nr, template RSL_Message t_tx, IpaStreamId sid := IPAC_PROTO_RSL_TRX0)
runs on test_CT {
	IPA_RSL[bts_nr].send(ts_ASP_RSL_UD(sid, t_tx));
}


/* verify we get a CHAN_ACT after CHAN RQD */
testcase TC_chan_act_noreply() runs on test_CT {
	var BSSAP_N_UNITDATA_ind ud_ind;
	var RSL_Message rsl_unused;

	f_init(1);

	IPA_RSL[0].send(ts_ASP_RSL_UD(IPAC_PROTO_RSL_TRX0,ts_RSL_CHAN_RQD('23'O, 23)));
	rsl_unused := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
	setverdict(pass);
}

/* verify if the "chreq:total" counter increments as expected */
testcase TC_chan_act_counter() runs on test_CT {
	var BSSAP_N_UNITDATA_ind ud_ind;
	var integer chreq_total;
	var RSL_Message rsl_unused;

	f_init(1);

	chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
	IPA_RSL[0].send(ts_ASP_RSL_UD(IPAC_PROTO_RSL_TRX0,ts_RSL_CHAN_RQD('23'O, 23)));
	rsl_unused := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
	f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total", chreq_total+1);

	setverdict(pass);
}

/* CHAN RQD -> CHAN ACT -> CHAN ACT ACK -> RF CHAN REL */
testcase TC_chan_act_ack_noest() runs on test_CT {
	var RSL_Message rx_rsl;

	f_init(1);

	/* Send CHAN RQD and wait for allocation; acknowledge it */
	var RslChannelNr chan_nr := f_chreq_act_ack();

	/* expect BSC to disable the channel again if there's no RLL EST IND */
	rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);

	setverdict(pass);
}

/* Test behavior if MSC never answers to CR */
testcase TC_chan_act_ack_est_ind_noreply() runs on test_CT {
	var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
	var IpaStreamId sid := IPAC_PROTO_RSL_TRX0;
	var RSL_Message rx_rsl;
	var ASP_RSL_Unitdata rx_rsl_ud;

	f_init(1);

	/* Send CHAN RQD and wait for allocation; acknowledge it */
	var RslChannelNr chan_nr := f_chreq_act_ack();

	var octetstring l3 := '00010203040506'O
	f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));

	BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3)));

	/* expect BSC to disable the channel again if there's no response from MSC */
	/* MS waits 20s (T3210) at LU; 10s (T3230) at CM SERV REQ and 5s (T3220) AT detach */
	f_expect_chan_rel(0, chan_nr, expect_rll_rel_req := false);
	setverdict(pass);
}

/* Test behavior if MSC answers with CREF to CR */
testcase TC_chan_act_ack_est_ind_refused() runs on test_CT {
	var BSSAP_N_CONNECT_ind rx_c_ind;
	var RSL_Message rx_rsl;

	f_init(1);

	/* Send CHAN RQD and wait for allocation; acknowledge it */
	var RslChannelNr chan_nr := f_chreq_act_ack();

	var octetstring l3 := '00010203040506'O
	f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));

	BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
	BSSAP.send(ts_BSSAP_DISC_req(rx_c_ind.connectionId, 0));

	/* expect BSC to disable the channel */
	f_expect_chan_rel(0, chan_nr, expect_rll_rel_req := false);
	setverdict(pass);
}

/* CHAN RQD -> CHAN ACT -> CHAN ACT NACK -> RF CHAN REL */
testcase TC_chan_act_nack() runs on test_CT {
	var RSL_Message rx_rsl;
	var integer chact_nack;

	f_init(1);

	chact_nack := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack");

	f_ipa_tx(0, ts_RSL_CHAN_RQD('33'O, 33));
	rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
	var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;

	f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));

	/* wait for some time to hope the NACK arrives before the CTRL GET below */
	f_sleep(0.5);

	f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack", chact_nack+1);

	setverdict(pass);
}

/* Test for channel exhaustion due to RACH overload */
testcase TC_chan_exhaustion() runs on test_CT {
	var ASP_RSL_Unitdata rsl_ud;
	var integer i;
	var integer chreq_total, chreq_nochan;

	f_init(1);

	chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
	chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");

	/* GSM 04.08 Table 9.9a:
	 * RA = '33'O -> Establishment cause = 0011xxxx (MS dual rate capable and asks for "TCH/H or TCH/F").
	 * With current setup, expect 4xSDCCH + 4xTCH/F + 1xTCH/H to succeed */
	for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS; i := i+1) {
		var RslChannelNr chan_nr := f_chreq_act_ack('33'O, i);
	}

	IPA_RSL[0].clear;

	f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
				   chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);

	/* now expect additional channel activations to fail */
	f_ipa_tx(0, ts_RSL_CHAN_RQD('42'O, 42));

	alt {
	[] IPA_RSL[0].receive(tr_ASP_RSL_UD(IPAC_PROTO_RSL_TRX0,
				tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV))) {
		setverdict(fail, "Received CHAN ACT ACK without resources?!?");
		}
	[] IPA_RSL[0].receive(tr_ASP_RSL_UD(IPAC_PROTO_RSL_TRX0, tr_RSL_IMM_ASSIGN(?))) -> value rsl_ud {
		var GsmRrMessage rr;
		/* match on IMM ASS REJ */
		rr := dec_GsmRrMessage(rsl_ud.rsl.ies[1].body.full_imm_ass_info.payload);
		if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
			f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
						   chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS+1);
			f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel",
						   chreq_nochan+1);
			setverdict(pass);
		} else {
			repeat;
		}
		}
	[] IPA_RSL[0].receive { repeat; }
	}
}

/* Test channel deactivation due to silence from MS */
testcase TC_chan_deact_silence() runs on test_CT {
	var RslChannelNr chan_nr;

	f_init(1);

	/* Request for a dedicated channel */
	chan_nr := f_chreq_act_ack('23'O);

	/* Wait some time until the channel is released */
	f_sleep(2.0);

	/* Expect CHANnel RELease */
	alt {
	[] IPA_RSL[0].receive(tr_ASP_RSL_UD(IPAC_PROTO_RSL_TRX0,
			      tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
		log("Received CHANnel RELease");
		setverdict(pass);
		}
	[] IPA_RSL[0].receive(tr_ASP_RSL_UD(IPAC_PROTO_RSL_TRX0,
			      tr_RSL_IMM_ASSIGN(?))) {
		/* See OS#3709, OsmoBSC should not send Immediate
		 * Assignment Reject since a dedicated channel was
		 * already allocated, and Immediate Assignment was
		 * already sent. */
		setverdict(fail, "Unexpected Immediate Assignment!");
		}
	[] IPA_RSL[0].receive {
		setverdict(fail, "Unexpected RSL message!");
		}
	}
}

/***********************************************************************
 * Assignment Testing
 ***********************************************************************/

/* Verify that the BSC refuses any BSSAP connection from the MSC (They are all BSC->MSC direction,
 * except for the inter-BSC handover, MT side) */
testcase TC_outbound_connect() runs on test_CT {
	f_init(1);

	BSSAP.send(ts_BSSAP_CONNECT_req(g_bssap.sccp_addr_peer, g_bssap.sccp_addr_own, 2342, ts_BSSMAP_AssignmentReq));
	BSSAP.receive(tr_BSSAP_DISC_ind(2342, ?, ?));
	setverdict(pass);
}

/* Test behavior if MSC answers with CREF to CR */
testcase TC_assignment_cic_only() runs on test_CT {
	var BSSAP_N_CONNECT_ind rx_c_ind;
	var RSL_Message rx_rsl;
	var DchanTuple dt;

	f_init(1);

	dt := f_est_dchan('23'O, 23, '00000000'O);
	if (mp_bssap_cfg.transport == BSSAP_TRANSPORT_AoIP) {
		/* send assignment without AoIP IEs */
		BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(ts_BSSMAP_IE_CIC(0, 1))));
	} else {
		/* Send assignmetn without CIC in IPA case */
		var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
						valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
		BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(omit, tla)));
	}
	alt {
	[] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
		setverdict(fail, "AoIP BSC cannot accept ASSIGNMENT without AoIP Transport IE");
		}
	/* TODO: Actually expect GSM0808_CAUSE_REQ_A_IF_TYPE_NOT_SUPP */
	[] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
		setverdict(pass);
		}
	[] BSSAP.receive { repeat; }
	}
}

/* generate an assignment request for either AoIP or SCCPlite */
function f_gen_ass_req(boolean osmux_enabled := false) return PDU_BSSAP {
	var PDU_BSSAP ass_cmd;
	var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
	if (mp_bssap_cfg.transport == BSSAP_TRANSPORT_AoIP) {
		var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
						valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
		if (osmux_enabled) {
			ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla, osmux_cid));
		} else {
			ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla));
		}
	} else {
		var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
		ass_cmd := valueof(ts_BSSMAP_AssignmentReq(cic, omit));
	}
	return ass_cmd;
}

function f_gen_handover_req() return PDU_BSSAP {
	var PDU_BSSAP ho_req;
	if (mp_bssap_cfg.transport == BSSAP_TRANSPORT_AoIP) {
		var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
						valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
		ho_req := valueof(ts_BSSMAP_HandoverRequest(omit, tla));
	} else {
		var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
		ho_req := valueof(ts_BSSMAP_HandoverRequest(cic, omit));
	}
	return ho_req;
}

/* generate an assignment complete template for either AoIP or SCCPlite */
function f_gen_exp_compl(boolean expect_osmux := false) return template PDU_BSSAP {
	var template PDU_BSSAP exp_compl;
	var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
	if (mp_bssap_cfg.transport == BSSAP_TRANSPORT_AoIP) {
		if (expect_osmux) {
			exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, osmux_cid);
		} else {
			exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, omit);
		}
	} else {
		/* CIC is optional "*" as the MSC allocated it */
		exp_compl := tr_BSSMAP_AssignmentComplete(*, omit);
	}
	return exp_compl;
}

/* Run everything required up to sending a caller-specified assignment command and expect response */
function f_assignment_exp(PDU_BSSAP ass_cmd, template PDU_BSSAP exp, charstring fail_text)
runs on test_CT {
	var BSSAP_N_CONNECT_ind rx_c_ind;
	var RSL_Message rx_rsl;
	var DchanTuple dt;

	f_init(1);

	dt := f_est_dchan('23'O, 23, '00000000'O);
	/* send assignment without AoIP IEs */
	BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
	alt {
	[] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
		if (ischosen(exp.pdu.bssmap.assignmentComplete)) {
			setverdict(pass);
		} else {
			setverdict(fail, fail_text);
		}
		}
	[] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
		if (ischosen(exp.pdu.bssmap.assignmentFailure)) {
			setverdict(pass);
		} else {
			setverdict(fail, fail_text);
		}
		}
	[] BSSAP.receive { repeat; }
	}
}
testcase TC_assignment_csd() runs on test_CT {
	var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
	var PDU_BSSAP ass_cmd := f_gen_ass_req();
	ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
	//exp_fail.pdu.bssmap.assignmentFailure.cause.causeValue := int2bit(enum2int(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_UNAVAIL), 7);
	f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for CSD");
}

testcase TC_assignment_ctm() runs on test_CT {
	var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
	var PDU_BSSAP ass_cmd := f_gen_ass_req();
	ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCTM);
	//exp_fail.pdu.bssmap.assignmentFailure.cause.causeValue := int2bit(enum2int(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_UNAVAIL), 7);
	f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for Speech+CTM");
}

type record DchanTuple {
	integer sccp_conn_id,
	RslChannelNr rsl_chan_nr
}

/* Send CHAN RQD and wait for allocation; acknowledge it */
private function f_chreq_act_ack(OCT1 ra := '23'O, GsmFrameNumber fn := 23)
runs on test_CT return RslChannelNr {
	var RSL_Message rx_rsl;
	f_ipa_tx(0, ts_RSL_CHAN_RQD(ra, fn));
	rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
	var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
	f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
	rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
	return chan_nr;
}

/* helper function to establish a dedicated channel via BTS and MSC */
function f_est_dchan(OCT1 ra, GsmFrameNumber fn, octetstring l3)
runs on test_CT return DchanTuple {
	var BSSAP_N_CONNECT_ind rx_c_ind;
	var DchanTuple dt;

	/* Send CHAN RQD and wait for allocation; acknowledge it */
	dt.rsl_chan_nr := f_chreq_act_ack(ra, fn);

	f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));

	BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
	dt.sccp_conn_id := rx_c_ind.connectionId;
	BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));

	return dt;
}

/* expect RF CAN REL from BTS, acknowledge it and clear the MSC side */
private function f_exp_chan_rel_and_clear(DchanTuple dt, integer bts_nr := 0) runs on test_CT {
	var RSL_Message rx_rsl;
	/* expect BSC to disable the channel */
	rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
	/* respond with CHAN REL ACK */
	f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));

	/* expect Clear Complete from BSC */
	BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));

	/* MSC disconnects as instructed. */
	BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
}

/* Test behavior of channel release after unilateral RLL REL IND (DISC from MS) */
testcase TC_chan_rel_rll_rel_ind() runs on test_CT {
	var BSSAP_N_DATA_ind rx_di;
	var DchanTuple dt;

	f_init(1);

	dt := f_est_dchan('23'O, 23, '00010203040506'O);

	/* simulate RLL REL IND */
	f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));

	/* expect Clear Request on MSC side */
	BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;

	/* Instruct BSC to clear channel */
	var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
	BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));

	/* expect BSC to disable the channel */
	f_exp_chan_rel_and_clear(dt, 0);

	/* wait for SCCP emulation to do its job */
	f_sleep(1.0);

	setverdict(pass);
}

/* Test behavior of channel release after CONN FAIL IND from BTS */
testcase TC_chan_rel_conn_fail() runs on test_CT {
	var BSSAP_N_DATA_ind rx_di;
	var DchanTuple dt;

	f_init(1);

	dt := f_est_dchan('23'O, 23, '00010203040506'O);

	/* simulate CONN FAIL IND */
	f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
	/* TODO: different cause values? */

	/* expect Clear Request from BSC */
	BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;

	/* Instruct BSC to clear channel */
	var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
	BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));

	/* expect BSC to disable the channel */
	f_exp_chan_rel_and_clear(dt, 0);

	/* wait for SCCP emulation to do its job */
	f_sleep(1.0);

	setverdict(pass);
}

/* Test behavior of early CONN FAIL IND from BTS (before EST IND!) */
/* See also https://www.osmocom.org/issues/3182 */
testcase TC_early_conn_fail() runs on test_CT {
	var RSL_Message rx_rsl;
	var DchanTuple dt;

	f_init(1);

	/* BTS->BSC: Send CHAN RQD and wait for allocation; acknowledge it */
	dt.rsl_chan_nr := f_chreq_act_ack(f_rnd_octstring(1), 23);

	/* BTS->BSC: simulate CONN FAIL IND */
	f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));

	/* BTS->BSC: Expect RF channel release from BSC on Abis */
	rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), 10.0);

	/* BTS<-BSC: respond with CHAN REL ACK */
	f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));

	setverdict(pass);
}

/* Test behavior of late CONN FAIL IND from BTS (ater REL IND!) */
/* See also https://www.osmocom.org/issues/3182 */
testcase TC_late_conn_fail() runs on test_CT {
	var RSL_Message rx_rsl;
	var DchanTuple dt;

	f_init(1);

	dt := f_est_dchan('23'O, 23, '00010203040506'O);

	/* BSC<-MSC: Instruct BSC to clear connection */
	BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(0)));

	/* BTS->BSC: expect BSC to deactivate SACCH */
	rx_rsl := f_exp_ipa_rx(0, tr_RSL_DEACT_SACCH(dt.rsl_chan_nr));

	/* BTS->BSC: simulate a late CONN FAIL IND from BTS */
	f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));

	/* BTS<-BSC: Expect RF channel release from BSC on Abis */
	rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), 10.0);
	/* BTS->BSC: respond with CHAN REL ACK */
	f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));

	/* BSC->MSC: expect Clear Complete from BSC */
	BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));

	/* BSC<-MSC: MSC disconnects as requested. */
	BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));

	setverdict(pass);
}

function f_expect_chan_rel(integer bts_nr, RslChannelNr rsl_chan_nr,
			   boolean expect_deact_sacch := true,
			   boolean expect_rr_chan_rel := true,
			   boolean expect_rll_rel_req := true,
			   boolean handle_rll_rel := true,
			   boolean is_csfb := false
			   ) runs on test_CT {

	var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
	var boolean got_deact_sacch := false;
	var boolean got_rr_chan_rel := false;
	var boolean got_rll_rel_req := false;
	log("f_expect_chan_rel() expecting: expect_deact_sacch=", expect_deact_sacch, " expect_rr_chan_rel=", expect_rr_chan_rel,
	    " expect_rll_rel_req=", expect_rll_rel_req);
	alt {
	[] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(IPAC_PROTO_RSL_TRX0,
					tr_RSL_DEACT_SACCH(rsl_chan_nr))) {
		got_deact_sacch := true;
		repeat;
	}
	[is_csfb] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(IPAC_PROTO_RSL_TRX0, tr_RSL_DATA_REQ(rsl_chan_nr, ?, decmatch tr_RRM_RR_RELEASE_CSFB))) {
		got_rr_chan_rel := true;
		repeat;
	}
	[not is_csfb] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(IPAC_PROTO_RSL_TRX0, tr_RSL_DATA_REQ(rsl_chan_nr, ?, decmatch tr_RRM_RR_RELEASE))) {
		got_rr_chan_rel := true;
		repeat;
	}
	[] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(IPAC_PROTO_RSL_TRX0,
					tr_RSL_REL_REQ(rsl_chan_nr, ?))) {
		got_rll_rel_req := true;
		/* FIXME: Why are we getting this for LinkID SACCH? */
		if (handle_rll_rel) {
			f_ipa_tx(0, ts_RSL_REL_CONF(rsl_chan_nr, main_dcch));
		}
		repeat;
	}
	[] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(IPAC_PROTO_RSL_TRX0,
						tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
		/* respond with CHAN REL ACK */
		f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(rsl_chan_nr));
		}
	/* ignore any user data */
	[] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(IPAC_PROTO_RSL_TRX0, tr_RSL_MsgTypeR(?))) {
		repeat;
		}
	}

	log("f_expect_chan_rel() summary: got_deact_sacch=", got_deact_sacch, " got_rr_chan_rel=", got_rr_chan_rel,
	    " got_rll_rel_req=", got_rll_rel_req);

	if (expect_deact_sacch != got_deact_sacch) {
		setverdict(fail, "f_expect_chan_rel(): expect_deact_sacch=", expect_deact_sacch, " got_deact_sacch=", got_deact_sacch);
	}
	if (expect_rr_chan_rel != got_rr_chan_rel) {
		setverdict(fail, "f_expect_chan_rel(): expect_rr_chan_rel=", expect_rr_chan_rel, " got_rr_chan_rel=", got_rr_chan_rel);
	}
	if (expect_rll_rel_req != got_rll_rel_req) {
		setverdict(fail, "f_expect_chan_rel(): expect_rll_rel_req=", expect_rll_rel_req, " got_rll_rel_req=", got_rll_rel_req);
	}
}

/* Test behavior of channel release after hard Clear Command from MSC */
testcase TC_chan_rel_hard_clear() runs on test_CT {
	var BSSAP_N_DATA_ind rx_di;
	var DchanTuple dt;

	f_init(1);

	dt := f_est_dchan('23'O, 23, '00010203040506'O);

	/* Instruct BSC to clear channel */
	var BssmapCause cause := 0;
	BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));

	/* expect Clear Complete from BSC on A */
	BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
		/* release the SCCP connection */
		BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
	}

	f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
	setverdict(pass);
}

/* Test behavior of channel release after Clear Command with CSFB indicator from MSC */
testcase TC_chan_rel_hard_clear_csfb() runs on test_CT {
	var BSSAP_N_DATA_ind rx_di;
	var DchanTuple dt;

	f_init(1);

	dt := f_est_dchan('23'O, 23, '00010203040506'O);

	/* Instruct BSC to clear channel */
	var BssmapCause cause := 0;
	BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));

	/* expect Clear Complete from BSC on A */
	BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
		/* release the SCCP connection */
		BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
	}

	f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false, is_csfb := true);
	setverdict(pass);
}

/* Test behavior of channel release after hard RLSD from MSC */
testcase TC_chan_rel_hard_rlsd() runs on test_CT {
	var DchanTuple dt;

	f_init(1);

	dt := f_est_dchan('23'O, 23, '00010203040506'O);

	/* release the SCCP connection */
	BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));

	f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
	setverdict(pass);
}

/* Test behavior of channel release after hard RLSD from MSC and MS is not responding to RLL REL REQ */
testcase TC_chan_rel_hard_rlsd_ms_dead() runs on test_CT {
	var DchanTuple dt;

	f_init(1);

	dt := f_est_dchan('23'O, 23, '00010203040506'O);

	/* release the SCCP connection */
	BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));

	f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
	setverdict(pass);
}

/* Test behavior of channel release after BSSMAP RESET from MSC */
testcase TC_chan_rel_a_reset() runs on test_CT {
	var DchanTuple dt;

	f_init(1);

	dt := f_est_dchan('23'O, 23, '00010203040506'O);

	/* Clear the queue, it might still contain stuff like IMMEDIATE ASSIGN */
	IPA_RSL[0].clear;

	/* perform BSSAP RESET, expect RESET ACK and DISC.ind on connection */
	BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap.sccp_addr_peer, g_bssap.sccp_addr_own, ts_BSSMAP_Reset(0, g_osmux_enabled)));
	interleave {
	[] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap.sccp_addr_own, g_bssap.sccp_addr_peer, tr_BSSMAP_ResetAck(g_osmux_enabled))) { }
	[] BSSAP.receive(tr_BSSAP_DISC_ind(dt.sccp_conn_id, ?, ?)) { }
	}

	f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
	setverdict(pass);
}

/* Verify T(iar) triggers and releases the channel */
testcase TC_chan_rel_sccp_tiar_timeout() runs on test_CT {
	var DchanTuple dt;

	/* Set T(iar) in BSC low enough that it will trigger before other side
	   has time to keep alive with a T(ias). Keep recommended ratio of
	   T(iar) >= T(ias)*2 */
	g_bsc_sccp_timer_ias := 2;
	g_bsc_sccp_timer_iar := 5;

	f_init(1);

	dt := f_est_dchan('23'O, 23, '00010203040506'O);
	f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
	setverdict(pass);
}

/* Test behavior if RSL EST IND for non-active channel */
testcase TC_rll_est_ind_inact_lchan() runs on test_CT {
	timer T := 2.0;

	f_init(1);

	var octetstring l3 := '00010203040506'O;
	var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
	f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));

	T.start;
	alt {
	[] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
		setverdict(fail, "MSC received COMPL L3 for non-active lchan");
		}
	[] BSSAP.receive {}
	[] IPA_RSL[0].receive {}
	[] T.timeout {}
	}

	setverdict(pass);
}

/* Test behavior if RSL EST IND for invalid SAPI */
testcase TC_rll_est_ind_inval_sapi1() runs on test_CT {
	var RslChannelNr chan_nr;

	f_init(1);

	chan_nr := f_chreq_act_ack()

	var octetstring l3 := '00010203040506'O;
	f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(1)), l3));

	timer T := 2.0;
	T.start;
	alt {
	[] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
		setverdict(fail, "MSC received COMPL L3 for invalid SAPI 1");
		}
	[] BSSAP.receive { repeat; }
	[] IPA_RSL[0].receive { repeat; }
	[] T.timeout {}
	}

	setverdict(pass);
}

/* Test behavior if RSL EST IND for invalid SAPI */
testcase TC_rll_est_ind_inval_sapi3() runs on test_CT {
	timer T := 2.0;

	f_init(1);

	var RslChannelNr chan_nr := f_chreq_act_ack();

	var octetstring l3 := '00010203040506'O;
	f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(3)), l3));

	T.start;
	alt {
	[] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
		setverdict(fail, "MSC received COMPL L3 for invalid SAPI 3");
		}
	[] BSSAP.receive { repeat; }
	[] IPA_RSL[0].receive { repeat; }
	[] T.timeout {}
	}

	setverdict(pass);
}

/* Test behavior if RSL EST IND for invalid SACCH */
testcase TC_rll_est_ind_inval_sacch() runs on test_CT {
	timer T := 2.0;

	f_init(1);

	var RslChannelNr chan_nr := f_chreq_act_ack();

	var octetstring l3 := '00010203040506'O;
	f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_SACCH(0)), l3));

	T.start;
	alt {
	[] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
		setverdict(fail, "MSC received COMPL L3 for invalid Link SACCH");
		}
	[] BSSAP.receive { repeat; }
	[] IPA_RSL[0].receive { repeat; }
	[] T.timeout {}
	}

	setverdict(pass);
}




testcase TC_ctrl_msc_connection_status() runs on test_CT {
	var charstring ctrl_resp;

	f_init(1);

	/* See https://osmocom.org/issues/2729 */
	f_ctrl_get_exp(IPA_CTRL, "msc_connection_status", "connected");
	setverdict(pass);
}

testcase TC_ctrl_msc0_connection_status() runs on test_CT {
	var charstring ctrl_resp;

	f_init(1);

	f_ctrl_get_exp(IPA_CTRL, "msc.0.connection_status", "connected");
	setverdict(pass);
}

testcase TC_ctrl() runs on test_CT {
	var charstring ctrl_resp;

	f_init(1);

	/* all below values must match the osmo-bsc.cfg config file used */

	f_ctrl_get_exp(IPA_CTRL, "mcc", "001");
	f_ctrl_get_exp(IPA_CTRL, "mnc", "01");
	f_ctrl_get_exp(IPA_CTRL, "number-of-bts", "4");

	var integer bts_nr := 0;
	f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "location-area-code", "1");
	f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "cell-identity", "0");
	f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "oml-connection-state", "connected");
	f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "gprs-mode", "gprs");
	f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "rf_state", "operational,unlocked,on");
	f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "arfcn", "871");
	f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "max-power-reduction", "20");

	var integer uptime := str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime"));
	f_sleep(2.0);
	if (str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime")) < uptime+1) {
		setverdict(fail, "oml-uptime not incrementing as expected");
	}
	/* TODO: Disconnect RSL, imply that OML is disconnected and check for uptime zero? */

	f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", 0);

	setverdict(pass);
}

/* Verify that Upon receival of SET "location", BSC forwards a TRAP
  "location-state" over the SCCPlite IPA conn */
testcase TC_ctrl_location() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	var integer bts_nr := 0;

	f_init(1, true);
	f_sleep(1.0);

	f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234567,fix3d,0.340000,0.560000,0.780000");
	f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
			"1234567,fix3d,0.340000,0.560000,0.780000,operational,unlocked,on,001,01");

	f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "1");
	f_sleep(2.0);

	f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234888,fix3d,0.350000,0.570000,0.790000");
	f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
			"1234888,fix3d,0.350000,0.570000,0.790000,operational,locked,off,001,01");

	/* should match the one from  config */
	f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "0");

	setverdict(pass);
}

function f_bssap_tx_ud(template PDU_BSSAP bssap) runs on test_CT {
	BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap.sccp_addr_peer, g_bssap.sccp_addr_own, bssap));
}


/***********************************************************************
 * Paging Testing
 ***********************************************************************/

type record Cell_Identity {
	GsmMcc		mcc,
	GsmMnc		mnc,
	GsmLac		lac,
	GsmCellId	ci
};
private const Cell_Identity cid := { '001'H, '01'H, 1, 0 };
private const Cell_Identity unknown_cid := { '678'H, 'f90'H, 1, 0 };

type set of integer BtsIdList;

private function f_bts_in_list(integer bts_id, BtsIdList bts_ids) return boolean {
	for (var integer j := 0; j < sizeof(bts_ids); j := j + 1) {
		if (bts_id == bts_ids[j]) {
			return true;
		}
	}
	return false;
}

/* core paging test helper function; used by most paging test cases */
private function f_pageing_helper(hexstring imsi,
				  template BSSMAP_FIELD_CellIdentificationList cid_list,
				  BtsIdList bts_ids := { 0 },
				  template RSL_ChanNeeded rsl_chneed := omit,
				  template OCT4 tmsi := omit) runs on test_CT
{
	var template BSSMAP_IE_ChannelNeeded bssmap_chneed;
	var MobileIdentity mi;
	var template octetstring id_enc; /* FIXME */
	var RSL_Message rx_rsl;
	var integer paging_group := hex2int(imsi[lengthof(imsi)-1]);
	var integer i;

	f_init();

	/* Clear the queue, it might still contain stuff like BCCH FILLING */
	for (i := 0; i < NUM_BTS; i := i + 1) {
		IPA_RSL[i].clear;
	}

	if (isvalue(rsl_chneed)) {
		/* The values of 08.08 3.2.2.36 and 08.58 9.3.40 are luckily identical */
		bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
	} else {
		bssmap_chneed := omit;
	}

	f_bssap_tx_ud(ts_BSSMAP_Paging(imsi, cid_list, tmsi, bssmap_chneed));

/* FIXME: Disabled due to bugs in both GSM_RR_Types and MobileL3_CommonIE_Types IMSI encoder
	if (isvalue(tmsi)) {
		mi := valueof(t_Osmo_MI_TMSI(oct2int(valueof(tmsi))));
	} else {
		mi := valueof(ts_Osmo_MI_IMSI(imsi));
	}
	id_enc := enc_MobileIdentity(mi);
*/
	id_enc := ?;
	for (i := 0; i < sizeof(bts_ids); i := i + 1) {
		rx_rsl := f_exp_ipa_rx(bts_ids[i], tr_RSL_PAGING_CMD(id_enc));
		/* check channel type, paging group */
		if (rx_rsl.ies[1].body.paging_group != paging_group) {
			setverdict(fail, "Paging for wrong paging group");
		}
		if (ispresent(rsl_chneed) and
		    rx_rsl.ies[3].body.chan_needed.chan_needed != valueof(rsl_chneed)) {
			setverdict(fail, "RSL Channel Needed != BSSMAP Channel Needed");
		}
	}
	f_sleep(2.0);
	/* do a quick check on all not-included BTSs if they received paging */
	for (i := 0; i < NUM_BTS; i := i + 1) {
		timer T := 0.1;
		if (f_bts_in_list(i, bts_ids)) {
			continue;
		}
		T.start;
		alt {
		[] IPA_RSL[i].receive(tr_ASP_RSL_UD(IPAC_PROTO_RSL_TRX0, tr_RSL_PAGING_CMD(id_enc))) {
			setverdict(fail, "Paging on BTS ", i, " which is not part of ", bts_ids);
			}
		[] IPA_RSL[i].receive { repeat; }
		[] T.timeout { }
		}
	}

	setverdict(pass);
}

const BtsIdList c_BtsId_all := { 0, 1, 2 };
const BtsIdList c_BtsId_none := { };
const BtsIdList c_BtsId_LAC1 := { 0, 1 };
const BtsIdList c_BtsId_LAC2 := { 2 };

/* PAGING by IMSI + TMSI */
testcase TC_paging_imsi_nochan() runs on test_CT {
	var BSSMAP_FIELD_CellIdentificationList cid_list;
	cid_list := valueof(ts_BSSMAP_CIL_noCell);
	f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, omit);
	f_shutdown_helper();
}

/* PAGING by IMSI + TMSI */
testcase TC_paging_tmsi_nochan() runs on test_CT {
	var BSSMAP_FIELD_CellIdentificationList cid_list;
	cid_list := valueof(ts_BSSMAP_CIL_noCell);
	f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, 'A1B2C301'O);
	f_shutdown_helper();
}

/* Paging with different "channel needed' values */
testcase TC_paging_tmsi_any() runs on test_CT {
	var BSSMAP_FIELD_CellIdentificationList cid_list;
	cid_list := valueof(ts_BSSMAP_CIL_noCell);
	f_pageing_helper('001010100000002'H, cid_list, c_BtsId_all, RSL_CHANNEED_ANY, 'A1B2C302'O);
	f_shutdown_helper();
}
testcase TC_paging_tmsi_sdcch() runs on test_CT {
	var BSSMAP_FIELD_CellIdentificationList cid_list;
	cid_list := valueof(ts_BSSMAP_CIL_noCell);
	f_pageing_helper('001010100000003'H, cid_list, c_BtsId_all, RSL_CHANNEED_SDCCH, 'A1B2C303'O);
	f_shutdown_helper();
}
testcase TC_paging_tmsi_tch_f() runs on test_CT {
	var BSSMAP_FIELD_CellIdentificationList cid_list;
	cid_list := valueof(ts_BSSMAP_CIL_noCell);
	f_pageing_helper('001010000000004'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_F, 'A1B2C304'O);
	f_shutdown_helper();
}
testcase TC_paging_tmsi_tch_hf() runs on test_CT {
	var BSSMAP_FIELD_CellIdentificationList cid_list;
	cid_list := valueof(ts_BSSMAP_CIL_noCell);
	f_pageing_helper('001010000000005'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_ForH, 'A1B2C305'O);
	f_shutdown_helper();
}

/* Paging by CGI */
testcase TC_paging_imsi_nochan_cgi() runs on test_CT {
	var template BSSMAP_FIELD_CellIdentificationList cid_list;
	cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(cid.mcc, cid.mnc, cid.lac, cid.ci) } };
	f_pageing_helper('001010000000006'H, cid_list, { 0 });
	f_shutdown_helper();
}

/* Paging by LAC+CI */
testcase TC_paging_imsi_nochan_lac_ci() runs on test_CT {
	var template BSSMAP_FIELD_CellIdentificationList cid_list;
	cid_list := { cIl_LAC_CI := { ts_BSSMAP_CI_LAC_CI(cid.lac, cid.ci) } };
	f_pageing_helper('001010000000007'H, cid_list, { 0 });
	f_shutdown_helper();
}

/* Paging by CI */
testcase TC_paging_imsi_nochan_ci() runs on test_CT {
	var template BSSMAP_FIELD_CellIdentificationList cid_list;
	cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(cid.ci) } };
	f_pageing_helper('001010000000008'H, cid_list, { 0 });
	f_shutdown_helper();
}

/* Paging by LAI */
testcase TC_paging_imsi_nochan_lai() runs on test_CT {
	var template BSSMAP_FIELD_CellIdentificationList cid_list;
	cid_list := { cIl_LAI := { ts_BSSMAP_CI_LAI(cid.mcc, cid.mnc, cid.lac) } };
	f_pageing_helper('001010000000009'H, cid_list, c_BtsId_LAC1);
	f_shutdown_helper();
}

/* Paging by LAC */
testcase TC_paging_imsi_nochan_lac() runs on test_CT {
	var template BSSMAP_FIELD_CellIdentificationList cid_list;
	cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(cid.lac) } };
	f_pageing_helper('001010000000010'H, cid_list, c_BtsId_LAC1);
	f_shutdown_helper();
}

/* Paging by "all in BSS" */
testcase TC_paging_imsi_nochan_all() runs on test_CT {
	var template BSSMAP_FIELD_CellIdentificationList cid_list;
	cid_list := { cIl_allInBSS := ''O };
	f_pageing_helper('001010000000011'H, cid_list, c_BtsId_all);
	f_shutdown_helper();
}

/* Paging by PLMN+LAC+RNC; We do not implement this; Verify nothing is paged */
testcase TC_paging_imsi_nochan_plmn_lac_rnc() runs on test_CT {
	var template BSSMAP_FIELD_CellIdentificationList cid_list;
	cid_list := { cIl_PLMN_LAC_RNC := { ts_BSSMAP_CI_PLMN_LAC_RNC(cid.mcc, cid.mnc, cid.lac, 12) } };
	f_pageing_helper('001010000000012'H, cid_list, c_BtsId_none);
	f_shutdown_helper();
}

/* Paging by RNC; We do not implement this; Verify nothing is paged */
testcase TC_paging_imsi_nochan_rnc() runs on test_CT {
	var template BSSMAP_FIELD_CellIdentificationList cid_list;
	cid_list := { cIl_RNC := { int2oct(13, 2) } };
	f_pageing_helper('001010000000013'H, cid_list, c_BtsId_none);
	f_shutdown_helper();
}

/* Paging by LAC+RNC; We do not implement; Verify nothing is paged */
testcase TC_paging_imsi_nochan_lac_rnc() runs on test_CT {
	var template BSSMAP_FIELD_CellIdentificationList cid_list;
	cid_list := { cIl_LAC_RNC := { ts_BSSMAP_CI_LAC_RNC(cid.lac, 14) } };
	f_pageing_helper('001010000000014'H, cid_list, c_BtsId_none);
	f_shutdown_helper();
}

/* Paging on multiple cells (multiple entries in list): Verify all of them page */
testcase TC_paging_imsi_nochan_lacs() runs on test_CT {
	var template BSSMAP_FIELD_CellIdentificationList cid_list;
	cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(1), ts_BSSMAP_CI_LAC(2) } };
	f_pageing_helper('001010000000015'H, cid_list, c_BtsId_all);
	f_shutdown_helper();
}

/* Paging on empty list: Verify none of them page */
testcase TC_paging_imsi_nochan_lacs_empty() runs on test_CT {
	var template BSSMAP_FIELD_CellIdentificationList cid_list;
	cid_list := { cIl_LAC := { } };
	f_pageing_helper('001010000000016'H, cid_list, c_BtsId_none);
	f_shutdown_helper();
}

/* Paging by CGI with unknown MCC/MNC: Verify nothing is paged. */
testcase TC_paging_imsi_nochan_cgi_unknown_cid() runs on test_CT {
	var template BSSMAP_FIELD_CellIdentificationList cid_list;
	cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(unknown_cid.mcc, unknown_cid.mnc, unknown_cid.lac, unknown_cid.ci) } };
	f_pageing_helper('001010000000006'H, cid_list, c_BtsId_none);
	f_shutdown_helper();
}

/* Verify paging retransmission interval + count */
/* Verify paging stops after channel establishment */
/* Test behavior under paging overload */

/* Verify PCH load */
testcase TC_paging_imsi_load() runs on test_CT {
	var BSSMAP_FIELD_CellIdentificationList cid_list;
	timer T := 4.0;
	timer T_retrans := 1.0;
	cid_list := valueof(ts_BSSMAP_CIL_noCell);
	f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);

	/* tell BSC there is no paging space anymore */
	f_ipa_tx(0, ts_RSL_PAGING_LOAD_IND(0));
	f_sleep(0.2);
	IPA_RSL[0].clear;

	/* Wait for 4 seconds if any more PAGING CMD are received on RSL. Normally,
	 * there would be 8 retransmissions during 4 seconds */
	T.start;
	T_retrans.start;
	alt {
	[] IPA_RSL[0].receive(tr_ASP_RSL_UD(IPAC_PROTO_RSL_TRX0, tr_RSL_PAGING_CMD(?))) {
		setverdict(fail, "Received PAGING after LOAD_IND(0)");
		mtc.stop;
		}
	[] T_retrans.timeout {
		/* re-trnsmit the zero-space LOAD IND to avoid BSC 'auto credit' */
		f_ipa_tx(0, ts_RSL_PAGING_LOAD_IND(0));
		T_retrans.start;
		repeat;
		}
	[] T.timeout {
		setverdict(pass);
		}
	}

	f_shutdown_helper();
}

/* Verify Paging Counter */
testcase TC_paging_counter() runs on test_CT {
	var BSSMAP_FIELD_CellIdentificationList cid_list;
	timer T := 4.0;
	var integer i;
	var integer paging_attempted_bsc;
	var integer paging_attempted_bts[NUM_BTS];
	var integer paging_expired_bts[NUM_BTS];
	cid_list := valueof(ts_BSSMAP_CIL_noCell);

	f_init();

	/* read counters before paging */
	paging_attempted_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted");
	for (i := 0; i < NUM_BTS; i := i+1) {
		paging_attempted_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted");
		paging_expired_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired");
	}

	f_pageing_helper('001230000000001'H, cid_list, c_BtsId_all);

	/* expect the attempted pages on BSC and each BTSs to have incremented by one */
	f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", paging_attempted_bsc+1);
	for (i := 0; i < NUM_BTS; i := i+1) {
		f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted",
						paging_attempted_bts[i]+1);
	}

	/* assume that 12s later the paging on all BTSs have expired and hence incremented by 1 */
	f_sleep(12.0);
	for (i := 0; i < NUM_BTS; i := i+1) {
		f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired",
						paging_expired_bts[i]+1);
	}

	f_shutdown_helper();
}


/* Verify paging stops after A-RESET */
testcase TC_paging_imsi_a_reset() runs on test_CT {
	var BSSMAP_FIELD_CellIdentificationList cid_list;
	timer T := 3.0;
	cid_list := valueof(ts_BSSMAP_CIL_noCell);
	f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);

	/* Perform a BSSMAP Reset and wait for ACK */
	BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap.sccp_addr_peer, g_bssap.sccp_addr_own, ts_BSSMAP_Reset(0, g_osmux_enabled)));
	alt {
	[] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap.sccp_addr_own, g_bssap.sccp_addr_peer, tr_BSSMAP_ResetAck(g_osmux_enabled))) { }
	[] BSSAP.receive { repeat; }
	}

	/* Wait to avoid a possible race condition if a paging message is
	 * received right before the reset ACK. */
	f_sleep(0.2);

	/* Clear the queue, it might still contain stuff like BCCH FILLING */
	for (var integer i := 0; i < sizeof(IPA_RSL); i := i+1) {
		IPA_RSL[i].clear;
	}

	/* Wait for 3 seconds if any more PAGING CMD are received on RSL */
	T.start;
	alt {
	[] IPA_RSL[0].receive(tr_ASP_RSL_UD(IPAC_PROTO_RSL_TRX0, tr_RSL_PAGING_CMD(?))) {
		setverdict(fail, "Received PAGING after A-RESET");
		mtc.stop;
		}
	[] IPA_RSL[1].receive(tr_ASP_RSL_UD(IPAC_PROTO_RSL_TRX0, tr_RSL_PAGING_CMD(?))) {
		setverdict(fail, "Received PAGING after A-RESET");
		mtc.stop;
		}
	[] IPA_RSL[2].receive(tr_ASP_RSL_UD(IPAC_PROTO_RSL_TRX0, tr_RSL_PAGING_CMD(?))) {
		setverdict(fail, "Received PAGING after A-RESET");
		mtc.stop;
		}
	[] T.timeout {
		setverdict(pass);
		}
	}

	f_shutdown_helper();
}

/* Verify how we handle unsolicited Paging Response. In case of an unsolicit
 * paging response we can not know which MSC is in charge, so we will blindly
 * pick the first configured MSC. This behavior is required in order to make
 * MT-CSFB calls working because in those cases the BSC can not know that the
 * MSC has already paged the subscriver via SGs. So any MT-CSFB call will look
 * like an unsolicited Paging Response to the MSC.
 */
testcase TC_paging_resp_unsol() runs on test_CT {

	f_init(1);
	timer T := 5.0;

	var BSSAP_N_CONNECT_ind rx_c_ind;
	var DchanTuple dt;
	var PDU_ML3_MS_NW l3 := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010008880018'H))));
	var octetstring rr_pag_resp := enc_PDU_ML3_MS_NW(l3);

	/* Send CHAN RQD and wait for allocation; acknowledge it */
	dt.rsl_chan_nr := f_chreq_act_ack();

	/* Send unsolicited Paging response (no matching Paging CMD stored in BSC) */
	f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), enc_PDU_ML3_MS_NW(l3)));


	/* Expevct a CR with a matching Paging response on the A-Interface */
	T.start;
	alt {
	[] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(rr_pag_resp))) {
		setverdict(pass);
		}
	[] BSSAP.receive {
		setverdict(fail, "Received unexpected message on A-Interface!");
		}
	[] T.timeout {
		setverdict(fail, "Received nothing on A-Interface!");
		}
	}

	setverdict(pass);
}

/* Test RSL link drop causes counter increment */
testcase TC_rsl_drop_counter() runs on test_CT {
	var integer rsl_fail;

	f_init(1);

	rsl_fail := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail");

	bts[0].rsl.vc_IPA.stop;

	f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail", rsl_fail+1);

	setverdict(pass);
}

/* TODO: Test OML link drop causes counter increment */

/* The body of TC_rsl_unknown_unit_id() and TC_oml_unknown_unit_id() tests. */
function f_ipa_unknown_unit_id(integer mp_bsc_ipa_port) runs on test_CT return boolean {
	timer T := 10.0;

	bts[0].rsl.id := "IPA-0-RSL";
	bts[0].rsl.vc_IPA := IPA_Emulation_CT.create(bts[0].rsl.id & "-IPA");
	bts[0].rsl.ccm_pars := c_IPA_default_ccm_pars;
	bts[0].rsl.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
	bts[0].rsl.ccm_pars.unit_id := "99/0/0"; /* value which is unknown at BTS */

	f_ipa_ctrl_start(mp_bsc_ip, mp_bsc_ctrl_port);

	f_init_mgcp("VirtMSC");

	/* start RSL/OML connection (XXX re-uses RSL port/protocol definitions for OML) */
	map(bts[0].rsl.vc_IPA:IPA_PORT, system:IPA);
	connect(bts[0].rsl.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[0]);
	bts[0].rsl.vc_IPA.start(IPA_Emulation.main_client(mp_bsc_ip, mp_bsc_ipa_port, "", 10000, bts[0].rsl.ccm_pars));

	/* wait for IPA OML link to connect and then disconnect */
	T.start;
	alt {
	[] IPA_RSL[0].receive(ASP_IPA_Event:{up_down := ASP_IPA_EVENT_DOWN}) {
		T.stop;
		return true;
	}
	[] IPA_RSL[0].receive { repeat }
	[] T.timeout {
		return false;
		}
	}
	return false;
}

/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
testcase TC_rsl_unknown_unit_id() runs on test_CT {
	if (f_ipa_unknown_unit_id(mp_bsc_rsl_port)) {
		setverdict(pass);
	} else {
		setverdict(fail, "Timeout RSL waiting for connection to close");
	}
}


/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
testcase TC_oml_unknown_unit_id() runs on test_CT {
	if (f_ipa_unknown_unit_id(mp_bsc_oml_port)) {
		setverdict(pass);
	} else {
		setverdict(fail, "Timeout OML waiting for connection to close");
	}
}


/***********************************************************************
 * "New world" test cases using RSL_Emulation + RAN_Emulation
 ***********************************************************************/

import from RAN_Emulation all;
import from RSL_Emulation all;
import from MSC_ConnectionHandler all;

type function void_fn(charstring id) runs on MSC_ConnHdlr;

/* helper function to create and connect a MSC_ConnHdlr component */
private function f_connect_handler(inout MSC_ConnHdlr vc_conn) runs on test_CT {
	connect(vc_conn:RAN, g_bssap.vc_RAN:PROC);
	connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
	connect(vc_conn:RSL, bts[0].rsl.vc_RSL:CLIENT_PT);
	connect(vc_conn:RSL_PROC, bts[0].rsl.vc_RSL:RSL_PROC);
	if (isvalue(bts[1])) {
		connect(vc_conn:RSL1, bts[1].rsl.vc_RSL:CLIENT_PT);
		connect(vc_conn:RSL1_PROC, bts[1].rsl.vc_RSL:RSL_PROC);
	}
	if (isvalue(bts[2])) {
		connect(vc_conn:RSL2, bts[2].rsl.vc_RSL:CLIENT_PT);
		connect(vc_conn:RSL2_PROC, bts[2].rsl.vc_RSL:RSL_PROC);
	}
	connect(vc_conn:BSSAP, g_bssap.vc_RAN:CLIENT);
	connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
	connect(vc_conn:MGCP_MULTI, vc_MGCP:MGCP_CLIENT_MULTI);
}

function f_start_handler(void_fn fn, template (omit) TestHdlrParams pars := omit)
runs on test_CT return MSC_ConnHdlr {
	var charstring id := testcasename();
	var MSC_ConnHdlr vc_conn;
	vc_conn := MSC_ConnHdlr.create(id);
	f_connect_handler(vc_conn);
	vc_conn.start(f_handler_init(fn, id, pars));
	return vc_conn;
}

/* first function inside ConnHdlr component; sets g_pars + starts function */
private function f_handler_init(void_fn fn, charstring id, template (omit) TestHdlrParams pars := omit)
runs on MSC_ConnHdlr {
	if (isvalue(pars)) {
		g_pars := valueof(pars);
	}
	fn.apply(id);
}

/* Establish signalling channel (non-assignment case) followed by cipher mode */
private function f_tc_ciph_mode_a5(charstring id) runs on MSC_ConnHdlr {
	var template PDU_BSSAP exp_compl := f_gen_exp_compl();
	var PDU_BSSAP ass_cmd := f_gen_ass_req();
	ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
	ass_cmd.pdu.bssmap.assignmentRequest.circuitIdentityCode := omit;
	ass_cmd.pdu.bssmap.assignmentRequest.aoIPTransportLayer := omit;
	exp_compl.pdu.bssmap.assignmentComplete.circuitIdentityCode := omit;
	exp_compl.pdu.bssmap.assignmentComplete.aoIPTransportLayer := omit;

	f_establish_fully(ass_cmd, exp_compl);
}
testcase TC_ciph_mode_a5_0() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	var TestHdlrParams pars := f_gen_test_hdlr_pars();
	pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));

	f_init(1, true);
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
	vc_conn.done;
}
testcase TC_ciph_mode_a5_1() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	var TestHdlrParams pars := f_gen_test_hdlr_pars();
	pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));

	f_init(1, true);
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
	vc_conn.done;
}
testcase TC_ciph_mode_a5_3() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	var TestHdlrParams pars := f_gen_test_hdlr_pars();
	pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));

	f_init(1, true);
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
	vc_conn.done;
}


/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
private function f_tc_assignment_fr_a5(charstring id) runs on MSC_ConnHdlr {
	var template PDU_BSSAP exp_compl := f_gen_exp_compl();
	var PDU_BSSAP ass_cmd := f_gen_ass_req();

	ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
	ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));

	f_establish_fully(ass_cmd, exp_compl);
}
testcase TC_assignment_fr_a5_0() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	var TestHdlrParams pars := f_gen_test_hdlr_pars();
	pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));

	f_init(1, true);
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
	vc_conn.done;
}
testcase TC_assignment_fr_a5_1() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	var TestHdlrParams pars := f_gen_test_hdlr_pars();
	pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));

	f_init(1, true);
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
	vc_conn.done;
}
testcase TC_assignment_fr_a5_3() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	var TestHdlrParams pars := f_gen_test_hdlr_pars();
	pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));

	f_init(1, true);
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
	vc_conn.done;
}

/* Expect ASSIGNMENT FAIL if mandatory IE is missing */
private function f_tc_assignment_fr_a5_1_codec_missing(charstring id) runs on MSC_ConnHdlr {
	g_pars := f_gen_test_hdlr_pars();
	var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
	var PDU_BSSAP ass_cmd := f_gen_ass_req();
	const OCT8 kc := '0001020304050607'O;

	ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
	/* Omit: ass_cmd.pdu.bssmap.assignmentRequest.codecList */

	f_establish_fully(ass_cmd, exp_fail);
}
testcase TC_assignment_fr_a5_1_codec_missing() runs on test_CT {
	var MSC_ConnHdlr vc_conn;

	f_init(1, true);
	f_sleep(1.0);

	vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5_1_codec_missing));
	vc_conn.done;
}

private function f_tc_assignment_fr_a5_4(charstring id) runs on MSC_ConnHdlr {
	g_pars := f_gen_test_hdlr_pars();
	var template PDU_BSSAP exp_compl := f_gen_exp_compl();
	var PDU_BSSAP ass_cmd := f_gen_ass_req();
	const OCT8 kc := '0001020304050607'O;
	const OCT16 kc128 := kc & kc;

	ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
	ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
	f_establish_fully(ass_cmd, exp_compl);
	f_cipher_mode('10'O, kc, kc128, true);
	/* TODO: expect GSM0808_CAUSE_CIPHERING_ALGORITHM_NOT_SUPPORTED cause value */
}
testcase TC_assignment_fr_a5_4() runs on test_CT {
	var MSC_ConnHdlr vc_conn;

	f_init(1, true);
	f_sleep(1.0);

	vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5_4));
	vc_conn.done;
}


private function f_tc_assignment_sign(charstring id) runs on MSC_ConnHdlr {
	g_pars := f_gen_test_hdlr_pars();
	var template PDU_BSSAP exp_compl := tr_BSSMAP_AssignmentComplete(omit, omit);
	var PDU_BSSAP ass_cmd := f_gen_ass_req();
	ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
	f_establish_fully(ass_cmd, exp_compl);
}

testcase TC_assignment_sign() runs on test_CT {
	var MSC_ConnHdlr vc_conn;

	f_init(1, true);
	f_sleep(1.0);

	vc_conn := f_start_handler(refers(f_tc_assignment_sign));
	vc_conn.done;
}

/***********************************************************************
 * Codec (list) testing
 ***********************************************************************/

/* check if the given rsl_mode is compatible with the a_elem */
private function f_match_codec(BSSMAP_FIELD_CodecElement a_elem, RSL_IE_ChannelMode rsl_mode)
return boolean {
	select (a_elem.codecType) {
	case (GSM_FR) {
		if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM1))) {
			return true;
		}
	}
	case (GSM_HR) {
		if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM1))) {
			return true;
		}
	}
	case (GSM_EFR) {
		if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM2))) {
			return true;
		}
	}
	case (FR_AMR) {
		if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM3))) {
			return true;
		}
	}
	case (HR_AMR) {
		if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM3))) {
			return true;
		}
	}
	case else { }
	}
	return false;
}

/* check if the given rsl_mode is compatible with the a_list */
private function f_match_codecs(BSSMAP_IE_SpeechCodecList a_list, RSL_IE_ChannelMode rsl_mode)
return boolean {
	for (var integer i := 0; i < sizeof(a_list); i := i+1) {
		if (f_match_codec(a_list.codecElements[i], rsl_mode)) {
			return true;
		}
	}
	return false;
}

/* determine BSSMAP_IE_ChannelType from *first* element of BSSMAP_FIELD_CodecElement */
function f_BSSMAP_chtype_from_codec(BSSMAP_FIELD_CodecElement a_elem)
return BSSMAP_IE_ChannelType {
	/* FIXME: actually look at all elements of BSSMAP_IE_SpeechCodecList */
	var BSSMAP_IE_ChannelType ret := valueof(ts_BSSMAP_IE_ChannelType);
	select (a_elem.codecType) {
	case (GSM_FR) {
		ret.channelRateAndType := ChRate_TCHF;
		ret.speechId_DataIndicator := Spdi_TCHF_FR;
	}
	case (GSM_HR) {
		ret.channelRateAndType := ChRate_TCHH;
		ret.speechId_DataIndicator := Spdi_TCHH_HR;
	}
	case (GSM_EFR) {
		ret.channelRateAndType := ChRate_TCHF;
		ret.speechId_DataIndicator := Spdi_TCHF_EFR;
	}
	case (FR_AMR) {
		ret.channelRateAndType := ChRate_TCHF;
		ret.speechId_DataIndicator := Spdi_TCHF_AMR;
	}
	case (HR_AMR) {
		ret.channelRateAndType := ChRate_TCHH;
		ret.speechId_DataIndicator := Spdi_TCHH_AMR;
	}
	case else {
		setverdict(fail, "Unsupported codec ", a_elem);
		mtc.stop;
	}
	}
	return ret;
}

private function f_rsl_chmod_tmpl_from_codec(BSSMAP_FIELD_CodecElement a_elem)
return template RSL_IE_Body {
	var template RSL_IE_Body mode_ie := {
		chan_mode := {
			len := ?,
			reserved := ?,
			dtx_d := ?,
			dtx_u := ?,
			spd_ind := RSL_SPDI_SPEECH,
			ch_rate_type := -,
			coding_alg_rate := -
		}
	}

	select (a_elem.codecType) {
	case (GSM_FR) {
		mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
		mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
	}
	case (GSM_HR) {
		mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
		mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
	}
	case (GSM_EFR) {
		mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
		mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM2;
	}
	case (FR_AMR) {
		mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
		mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
	}
	case (HR_AMR) {
		mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
		mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
	}
	}
	return mode_ie;
}

type record CodecListTest {
	BSSMAP_IE_SpeechCodecList codec_list,
	charstring id
}
type record of CodecListTest CodecListTests

private function f_TC_assignment_codec(charstring id) runs on MSC_ConnHdlr {
	var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux);
	var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux);

	/* puzzle together the ASSIGNMENT REQ for given codec[s] */
	if (mp_bssap_cfg.transport == BSSAP_TRANSPORT_AoIP) {
		ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
		exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
								g_pars.ass_codec_list.codecElements[0];
		if (isvalue(g_pars.expect_mr_s0_s7)) {
			exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
								g_pars.expect_mr_s0_s7;
		}
	}
	ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
				f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
	log("expecting ASS COMPL like this: ", exp_compl);

	f_establish_fully(ass_cmd, exp_compl);

	/* Verify that the RSL-side activation actually matches our expectations */
	var RSL_Message rsl := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);

	var RSL_IE_Body mode_ie;
	if (f_rsl_find_ie(rsl, RSL_IE_CHAN_MODE, mode_ie) == false) {
		setverdict(fail, "Couldn't find CHAN_MODE IE");
		mtc.stop;
	}
	var template RSL_IE_Body t_mode_ie := f_rsl_chmod_tmpl_from_codec(g_pars.ass_codec_list.codecElements[0]);
	if (not match(mode_ie, t_mode_ie)) {
		setverdict(fail, "RSL Channel Mode IE doesn't match expectation");
	}

	var RSL_IE_Body mr_conf;
	if (g_pars.expect_mr_conf_ie != omit) {
		if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == false) {
			setverdict(fail, "Missing MR CONFIG IE in RSL Chan Activ");
			mtc.stop;
		}
		log("found RSL MR CONFIG IE: ", mr_conf);

		if (not match(mr_conf, g_pars.expect_mr_conf_ie)) {
			setverdict(fail, "RSL MR CONFIG IE does not match expectation. Expected: ",
				g_pars.expect_mr_conf_ie);
		}
	} else {
		if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == true) {
			log("found RSL MR CONFIG IE: ", mr_conf);
			setverdict(fail, "Found MR CONFIG IE in RSL Chan Activ, expecting omit");
			mtc.stop;
		}
	}
}

private function f_TC_assignment_codec_fail(charstring id) runs on MSC_ConnHdlr {

	var PDU_BSSAP ass_cmd := f_gen_ass_req();
	var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;

	/* puzzle together the ASSIGNMENT REQ for given codec[s] */
	if (mp_bssap_cfg.transport == BSSAP_TRANSPORT_AoIP) {
		ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
	}
	ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
				f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
	log("expecting ASS FAIL like this: ", exp_fail);

	f_establish_fully(ass_cmd, exp_fail);
}

testcase TC_assignment_codec_fr() runs on test_CT {
	var TestHdlrParams pars := f_gen_test_hdlr_pars();
	var MSC_ConnHdlr vc_conn;

	f_init(1, true);
	f_sleep(1.0);

	pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
	vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
	vc_conn.done;
}

testcase TC_assignment_codec_hr() runs on test_CT {
	var TestHdlrParams pars := f_gen_test_hdlr_pars();
	var MSC_ConnHdlr vc_conn;

	f_init(1, true);
	f_sleep(1.0);

	pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
	vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
	vc_conn.done;
}

testcase TC_assignment_codec_efr() runs on test_CT {
	var TestHdlrParams pars := f_gen_test_hdlr_pars();
	var MSC_ConnHdlr vc_conn;

	f_init(1, true);
	f_sleep(1.0);

	pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecEFR}));
	vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
	vc_conn.done;
}

/* Allow 5,90k only (current default config) */
private function f_allow_amr_rate_5_90k() runs on test_CT {
	f_vty_enter_cfg_msc(BSCVTY, 0);
	f_vty_transceive(BSCVTY, "amr-config 12_2k forbidden");
	f_vty_transceive(BSCVTY, "amr-config 10_2k forbidden");
	f_vty_transceive(BSCVTY, "amr-config 7_95k forbidden");
	f_vty_transceive(BSCVTY, "amr-config 7_40k forbidden");
	f_vty_transceive(BSCVTY, "amr-config 6_70k forbidden");
	f_vty_transceive(BSCVTY, "amr-config 5_90k allowed");
	f_vty_transceive(BSCVTY, "amr-config 5_15k forbidden");
	f_vty_transceive(BSCVTY, "amr-config 4_75k forbidden");
	f_vty_transceive(BSCVTY, "exit");
	f_vty_transceive(BSCVTY, "exit");
}

/* Allow 4,75k, 5,90k, 4,70k and 12,2k, which are the most common rates
 * ("Config-NB-Code = 1") */
private function f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k() runs on test_CT {
	f_vty_enter_cfg_msc(BSCVTY, 0);
	f_vty_transceive(BSCVTY, "amr-config 12_2k allowed");
	f_vty_transceive(BSCVTY, "amr-config 10_2k forbidden");
	f_vty_transceive(BSCVTY, "amr-config 7_95k forbidden");
	f_vty_transceive(BSCVTY, "amr-config 7_40k allowed");
	f_vty_transceive(BSCVTY, "amr-config 6_70k forbidden");
	f_vty_transceive(BSCVTY, "amr-config 5_90k allowed");
	f_vty_transceive(BSCVTY, "amr-config 5_15k forbidden");
	f_vty_transceive(BSCVTY, "amr-config 4_75k allowed");
	f_vty_transceive(BSCVTY, "exit");
	f_vty_transceive(BSCVTY, "exit");
}

testcase TC_assignment_codec_amr_f() runs on test_CT {
	var TestHdlrParams pars := f_gen_test_hdlr_pars();
	var MSC_ConnHdlr vc_conn;

	/* Note: This setups the codec configuration. The parameter payload in
	 * mr_conf must be consistant with the parameter codecElements in pars
	 * and also must match the amr-config in osmo-bsc.cfg! */
	var RSL_IE_Body mr_conf := {
		other := {
			len := 2,
			payload := '2804'O
		}
	};

	pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
	pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
	pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
	pars.expect_mr_conf_ie := mr_conf;

	f_init(1, true);
	f_sleep(1.0);

	vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
	vc_conn.done;
}

testcase TC_assignment_codec_amr_h() runs on test_CT {
	var TestHdlrParams pars := f_gen_test_hdlr_pars();
	var MSC_ConnHdlr vc_conn;

	/* See note above */
	var RSL_IE_Body mr_conf := {
		other := {
			len := 2,
			payload := '2804'O
		}
	};

	pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
	pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
	pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
	pars.expect_mr_conf_ie := mr_conf;

	f_init(1, true);
	f_sleep(1.0);

	vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
	vc_conn.done;
}

function f_TC_assignment_codec_amr(boolean fr, octetstring mrconf, bitstring s8_s0, bitstring exp_s8_s0)
runs on test_CT {

	var TestHdlrParams pars := f_gen_test_hdlr_pars();
	var MSC_ConnHdlr vc_conn;

	/* See note above */
	var RSL_IE_Body mr_conf := {
		other := {
			len := lengthof(mrconf),
			payload := mrconf
		}
	};

	if (fr) {
		pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
	} else {
		pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
	}
	pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
	pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
	pars.expect_mr_conf_ie := mr_conf;
	pars.expect_mr_s0_s7 := exp_s8_s0;

	f_init(1, true);
	f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
	f_sleep(1.0);

	vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
	vc_conn.done;
	f_allow_amr_rate_5_90k();
}

function f_TC_assignment_codec_amr_fail(boolean fr, bitstring s8_s0)
runs on test_CT {

	var TestHdlrParams pars := f_gen_test_hdlr_pars();
	var MSC_ConnHdlr vc_conn;

	if (fr) {
		pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
	} else {
		pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
	}
	pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
	pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;

	f_init(1, true);
	f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
	f_sleep(1.0);

	vc_conn := f_start_handler(refers(f_TC_assignment_codec_fail), pars);
	vc_conn.done;
	f_allow_amr_rate_5_90k();
}


/* Set S1, we expect an AMR multirate configuration IE with all four rates
 * set. */
testcase TC_assignment_codec_amr_f_S1() runs on test_CT {
	 f_TC_assignment_codec_amr(true, '289520882208'O, '00000010'B, '00000010'B);
}

/* Set S1, we expect an AMR multirate configuration IE with the lower three
 * rates set. */
testcase TC_assignment_codec_amr_h_S1() runs on test_CT {
	 f_TC_assignment_codec_amr(false, '2815208820'O, '00000010'B, '00000010'B);
}

/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
testcase TC_assignment_codec_amr_f_S124() runs on test_CT {
	 f_TC_assignment_codec_amr(true, '289520882208'O, '00010110'B, '00000010'B);
}

/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
testcase TC_assignment_codec_amr_h_S124() runs on test_CT {
	 f_TC_assignment_codec_amr(false, '2815208820'O, '00010110'B, '00000010'B);
}

/* The following block of tests selects more and more rates until all four
 * possible rates are in the active set (full rate) */
testcase TC_assignment_codec_amr_f_S0() runs on test_CT {
	 f_TC_assignment_codec_amr(true, '2801'O, '00000001'B, '00000001'B);
}

testcase TC_assignment_codec_amr_f_S02() runs on test_CT {
	 f_TC_assignment_codec_amr(true, '28052080'O, '00000101'B, '00000101'B);
}

testcase TC_assignment_codec_amr_f_S024() runs on test_CT {
	 f_TC_assignment_codec_amr(true, '2815208820'O, '00010101'B, '00010101'B);
}

testcase TC_assignment_codec_amr_f_S0247() runs on test_CT {
	 f_TC_assignment_codec_amr(true, '289520882208'O, '10010101'B, '10010101'B);
}

/* The following block of tests selects more and more rates until all three
 * possible rates are in the active set (half rate) */
testcase TC_assignment_codec_amr_h_S0() runs on test_CT {
	 f_TC_assignment_codec_amr(false, '2801'O, '00000001'B, '00000001'B);
}

testcase TC_assignment_codec_amr_h_S02() runs on test_CT {
	 f_TC_assignment_codec_amr(false, '28052080'O, '00000101'B, '00000101'B);
}

testcase TC_assignment_codec_amr_h_S024() runs on test_CT {
	 f_TC_assignment_codec_amr(false, '2815208820'O, '00010101'B, '00010101'B);
}

/* The following block tests what happens when the MSC does offer rate
 * configurations that are not supported by the BSC. Normally such situations
 * should not happen because the MSC gets informed by the BSC in advance via
 * the L3 COMPLETE message which rates are applicable. The MSC should not try
 * to offer rates that are not applicable anyway. */

testcase TC_assignment_codec_amr_h_S0247() runs on test_CT {
	 /* Try to include 12,2k in into the active set even though the channel
	  * is half rate only. The BSC is expected to remove the 12,0k */
	 f_TC_assignment_codec_amr(false, '2815208820'O, '10010101'B, '00010101'B);
}

testcase TC_assignment_codec_amr_f_S01234567() runs on test_CT {
	 /* See what happens when all rates are selected at once. Since then
	  * Also S1 is selected, this setting will be prefered and we should
	  * get 12.2k, 7,40k, 5,90k, and 4,75k in the active set. */
	 f_TC_assignment_codec_amr(true, '289520882208'O, '11111111'B, '00000010'B);
}

testcase TC_assignment_codec_amr_f_S0234567() runs on test_CT {
	 /* Same as above, but with S1 missing, the MSC is then expected to
	  * select the currently supported rates, which are also 12.2k, 7,40k,
	  * 5,90k, and 4,75k, into the active set. */
	 f_TC_assignment_codec_amr(true, '289520882208'O, '11111101'B, '10010101'B);
}

testcase TC_assignment_codec_amr_f_zero() runs on test_CT {
	 /* Try to select no rates at all */
	 f_TC_assignment_codec_amr_fail(true, '00000000'B);
}

testcase TC_assignment_codec_amr_f_unsupp() runs on test_CT {
	 /* Try to select only unsupported rates */
	 f_TC_assignment_codec_amr_fail(true, '01101000'B);
}

testcase TC_assignment_codec_amr_h_S7() runs on test_CT {
	 /* Try to select 12,2k for half rate */
	 f_TC_assignment_codec_amr_fail(false, '10000000'B);
}

private function f_disable_all_tch_f() runs on test_CT {
	f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 borken");
	f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 borken");
	f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 borken");
	f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 borken");
}

private function f_disable_all_tch_h() runs on test_CT {
	f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 borken");
	f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 borken");
}

private function f_enable_all_tch() runs on test_CT {
	f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 unused");
	f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 unused");
	f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 unused");
	f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 unused");
	f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 unused");
	f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 unused");
}

/* Allow HR only */
private function f_TC_assignment_codec_xr_exhausted_req_hr(charstring id) runs on MSC_ConnHdlr {
	g_pars := f_gen_test_hdlr_pars();
	var PDU_BSSAP ass_cmd := f_gen_ass_req();
	var template PDU_BSSAP exp_compl := f_gen_exp_compl();
	ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
	ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
	ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
	ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
	f_establish_fully(ass_cmd, exp_compl);
}

/* Allow FR only */
private function f_TC_assignment_codec_xr_exhausted_req_fr(charstring id) runs on MSC_ConnHdlr {
	g_pars := f_gen_test_hdlr_pars();
	var PDU_BSSAP ass_cmd := f_gen_ass_req();
	var template PDU_BSSAP exp_compl := f_gen_exp_compl();
	ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
	ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
	ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
	ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
	f_establish_fully(ass_cmd, exp_compl);
}

/* Allow HR only (expect assignment failure) */
private function f_TC_assignment_codec_xr_exhausted_req_hr_fail(charstring id) runs on MSC_ConnHdlr {
	g_pars := f_gen_test_hdlr_pars();
	var PDU_BSSAP ass_cmd := f_gen_ass_req();
	var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
	ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
	ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
	ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
	ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
	f_establish_fully(ass_cmd, exp_fail);
}

/* Allow FR only (expect assignment failure) */
private function f_TC_assignment_codec_xr_exhausted_req_fr_fail(charstring id) runs on MSC_ConnHdlr {
	g_pars := f_gen_test_hdlr_pars();
	var PDU_BSSAP ass_cmd := f_gen_ass_req();
	var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
	ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
	ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
	ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
	ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
	f_establish_fully(ass_cmd, exp_fail);
}

/* Allow FR and HR, but prefer FR */
private function f_TC_assignment_codec_fr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
	g_pars := f_gen_test_hdlr_pars();
	var PDU_BSSAP ass_cmd := f_gen_ass_req();
	var template PDU_BSSAP exp_compl := f_gen_exp_compl();
	ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
	ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
	ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
	ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
	exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
	f_establish_fully(ass_cmd, exp_compl);
}

/* Allow FR and HR, but prefer HR */
private function f_TC_assignment_codec_fr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
	g_pars := f_gen_test_hdlr_pars();
	var PDU_BSSAP ass_cmd := f_gen_ass_req();
	var template PDU_BSSAP exp_compl := f_gen_exp_compl();
	ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
	ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
	ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
	ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
	exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
	f_establish_fully(ass_cmd, exp_compl);
}

/* Allow FR and HR, but prefer FR */
private function f_TC_assignment_codec_hr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
	g_pars := f_gen_test_hdlr_pars();
	var PDU_BSSAP ass_cmd := f_gen_ass_req();
	var template PDU_BSSAP exp_compl := f_gen_exp_compl();
	ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
	ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
	ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
	ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
	exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
	f_establish_fully(ass_cmd, exp_compl);
}

/* Allow FR and HR, but prefer HR */
private function f_TC_assignment_codec_hr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
	g_pars := f_gen_test_hdlr_pars();
	var PDU_BSSAP ass_cmd := f_gen_ass_req();
	var template PDU_BSSAP exp_compl := f_gen_exp_compl();
	ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
	ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
	ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
	ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
	exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
	f_establish_fully(ass_cmd, exp_compl);
}

/* Request a HR channel while all FR channels are exhausted, this is expected
 * to work without conflicts */
testcase TC_assignment_codec_fr_exhausted_req_hr() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	f_init(1, true);
	f_sleep(1.0);
	f_enable_all_tch();
	f_disable_all_tch_f();
	vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr));
	vc_conn.done;
	f_enable_all_tch();
	setverdict(pass);
}

/* Request a FR channel while all FR channels are exhausted, this is expected
 * to fail. */
testcase TC_assignment_codec_fr_exhausted_req_fr() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	f_init(1, true);
	f_sleep(1.0);
	f_enable_all_tch();
	f_disable_all_tch_f();
	vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr_fail));
	vc_conn.done;
	f_enable_all_tch();
	setverdict(pass);
}

/* Request a FR (prefered) or alternatively a HR channel while all FR channels
 * are exhausted, this is expected to be resolved by selecting a HR channel. */
testcase TC_assignment_codec_fr_exhausted_req_fr_hr() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	f_init(1, true);
	f_sleep(1.0);
	f_enable_all_tch();
	f_disable_all_tch_f();
	vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_fr_hr));
	vc_conn.done;
	f_enable_all_tch();
	setverdict(pass);
}

/* Request a HR (prefered) or alternatively a FR channel while all FR channels
 * are exhausted, this is expected to work without conflicts. */
testcase TC_assignment_codec_fr_exhausted_req_hr_fr() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	f_init(1, true);
	f_sleep(1.0);
	f_enable_all_tch();
	f_disable_all_tch_f();
	vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_hr_fr));
	vc_conn.done;
	f_enable_all_tch();
	setverdict(pass);
}

/* Request a FR channel while all HR channels are exhausted, this is expected
 * to work without conflicts */
testcase TC_assignment_codec_hr_exhausted_req_fr() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	f_init(1, true);
	f_sleep(1.0);
	f_enable_all_tch();
	f_disable_all_tch_h();
	vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr));
	vc_conn.done;
	f_enable_all_tch();
	setverdict(pass);
}

/* Request a HR channel while all HR channels are exhausted, this is expected
 * to fail. */
testcase TC_assignment_codec_hr_exhausted_req_hr() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	f_init(1, true);
	f_sleep(1.0);
	f_enable_all_tch();
	f_disable_all_tch_h();
	vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr_fail));
	vc_conn.done;
	f_enable_all_tch();
	setverdict(pass);
}

/* Request a HR (prefered) or alternatively a FR channel while all HR channels
 * are exhausted, this is expected to be resolved by selecting a FR channel. */
testcase TC_assignment_codec_hr_exhausted_req_hr_fr() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	f_init(1, true);
	f_sleep(1.0);
	f_enable_all_tch();
	f_disable_all_tch_h();
	vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_hr_fr));
	vc_conn.done;
	f_enable_all_tch();
	setverdict(pass);
}

/* Request a FR (prefered) or alternatively a HR channel while all HR channels
 * are exhausted, this is expected to work without conflicts. */
testcase TC_assignment_codec_hr_exhausted_req_fr_hr() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	f_init(1, true);
	f_sleep(1.0);
	f_enable_all_tch();
	f_disable_all_tch_h();
	vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_fr_hr));
	vc_conn.done;
	f_enable_all_tch();
	setverdict(pass);
}

/* Allow FR and HR, but prefer HR */
private function f_TC_assignment_codec_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
	g_pars := f_gen_test_hdlr_pars();
	var PDU_BSSAP ass_cmd := f_gen_ass_req();
	var template PDU_BSSAP exp_compl := f_gen_exp_compl();
	ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
	ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
	ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
	ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
	exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
	f_establish_fully(ass_cmd, exp_compl);
}

/* Allow FR and HR, but prefer FR */
private function f_TC_assignment_codec_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
	g_pars := f_gen_test_hdlr_pars();
	var PDU_BSSAP ass_cmd := f_gen_ass_req();
	var template PDU_BSSAP exp_compl := f_gen_exp_compl();
	ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
	ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
	ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
	ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
	exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
	f_establish_fully(ass_cmd, exp_compl);
}

/* Request a HR (prefered) or alternatively a FR channel, it is expected that
 * HR, which is the prefered type, is selected. */
testcase TC_assignment_codec_req_hr_fr() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	f_init(1, true);
	f_sleep(1.0);
	f_enable_all_tch();
	vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_hr_fr));
	vc_conn.done;
	setverdict(pass);
}

/* Request a FR (prefered) or alternatively a HR channel, it is expected that
 * FR, which is the prefered type, is selected. */
testcase TC_assignment_codec_req_fr_hr() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	f_init(1, true);
	f_sleep(1.0);
	f_enable_all_tch();
	vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_fr_hr));
	vc_conn.done;
	setverdict(pass);
}

testcase TC_assignment_osmux() runs on test_CT {
	var TestHdlrParams pars := f_gen_test_hdlr_pars();
	var MSC_ConnHdlr vc_conn;

	/* See note above */
	var RSL_IE_Body mr_conf := {
		other := {
			len := 2,
			payload := '2804'O
		}
	};

	pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
	pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
	pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
	pars.expect_mr_conf_ie := mr_conf;
	pars.use_osmux := true;

	f_init(1, true, true);
	f_sleep(1.0);

	vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
	vc_conn.done;
}

/* test the procedure of the MSC requesting a Classmark Update:
 * a) BSSMAP Classmark Request should result in RR CLASSMARK ENQUIRY,
 * b) L3 RR CLASSMARK CHANGE should result in BSSMAP CLASSMARK UPDATE */
private function f_tc_classmark(charstring id) runs on MSC_ConnHdlr {
	g_pars := f_gen_test_hdlr_pars();

	f_create_chan_and_exp();
	/* we should now have a COMPL_L3 at the MSC */
	BSSAP.receive(tr_BSSMAP_ComplL3);

	BSSAP.send(ts_BSSMAP_ClassmarkRequest);
	RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_CM_ENQUIRY));

	f_rsl_send_l3(ts_RRM_CM_CHG(valueof(ts_CM2)));
	BSSAP.receive(tr_BSSMAP_ClassmarkUpd(?, omit));
	setverdict(pass);
}
testcase TC_classmark() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	f_init(1, true);
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_tc_classmark));
	vc_conn.done;
}

private function f_est_single_l3(template PDU_ML3_MS_NW l3) runs on MSC_ConnHdlr {
	g_pars := f_gen_test_hdlr_pars();
	f_create_chan_and_exp();
	/* we should now have a COMPL_L3 at the MSC */
	BSSAP.receive(tr_BSSMAP_ComplL3);

	/* send the single message we want to send */
	f_rsl_send_l3(l3);
}

private function f_bssap_expect_nothing(float sec := 5.00) runs on MSC_ConnHdlr {
	timer T := sec;
	var PDU_BSSAP bssap;
	T.start;
	alt {
	[] BSSAP.receive(PDU_BSSAP:?) -> value bssap {
		setverdict(fail, "Unexpected BSSMAP ", bssap);
		mtc.stop;
		}
	[] T.timeout {
		setverdict(pass);
		}
	}
}

/* unsolicited ASSIGNMENT FAIL (without ASSIGN) from MS shouldn't bring BSC down */
private function f_tc_unsol_ass_fail(charstring id) runs on MSC_ConnHdlr {
	f_est_single_l3(ts_RRM_AssignmentFailure('00'O));
	f_bssap_expect_nothing();
}
testcase TC_unsol_ass_fail() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	f_init(1, true);
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_tc_unsol_ass_fail));
	vc_conn.done;
}


/* unsolicited ASSIGNMENT COMPLETE (without ASSIGN) from MS shouldn't bring BSC down */
private function f_tc_unsol_ass_compl(charstring id) runs on MSC_ConnHdlr {
	f_est_single_l3(ts_RRM_AssignmentComplete('00'O));
	f_bssap_expect_nothing();
}
testcase TC_unsol_ass_compl() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	f_init(1, true);
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_tc_unsol_ass_compl));
	vc_conn.done;
}


/* unsolicited HANDOVER FAIL (without ASSIGN) from MS shouldn't bring BSC down */
private function f_tc_unsol_ho_fail(charstring id) runs on MSC_ConnHdlr {
	f_est_single_l3(ts_RRM_HandoverFailure('00'O));
	f_bssap_expect_nothing();
}
testcase TC_unsol_ho_fail() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	f_init(1, true);
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_tc_unsol_ho_fail));
	vc_conn.done;
}


/* short message from MS should be ignored */
private function f_tc_err_82_short_msg(charstring id) runs on MSC_ConnHdlr {
	g_pars := f_gen_test_hdlr_pars();
	f_create_chan_and_exp();
	/* we should now have a COMPL_L3 at the MSC */
	BSSAP.receive(tr_BSSMAP_ComplL3);

	/* send short message */
	RSL.send(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), ''O));
	f_bssap_expect_nothing();
}
testcase TC_err_82_short_msg() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	f_init(1, true);
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_tc_err_82_short_msg));
	vc_conn.done;
}


/* 24.008 8.4 Unknown message must trigger RR STATUS */
private function f_tc_err_84_unknown_msg(charstring id) runs on MSC_ConnHdlr {
	f_est_single_l3(ts_RRM_UL_REL('00'O));
	timer T := 3.0
	alt {
	[] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_STATUS)) {
		setverdict(pass);
		}
	[] BSSAP.receive { setverdict(fail, "unexpected BSSAP"); }
	[] T.timeout { setverdict(fail, "Timeout waiting for RR STATUS"); }
	}
}
testcase TC_err_84_unknown_msg() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	f_init(1, true);
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_tc_err_84_unknown_msg));
	vc_conn.done;
}

/***********************************************************************
 * Handover
 ***********************************************************************/

/* execute a "bts <0-255> trx <0-255> timeslot <0-7> " command on given Dchan */
private function f_vty_ts_action(charstring suffix, integer bts_nr, integer trx_nr, integer ts_nr)
runs on test_CT {
	var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
				" timeslot "&int2str(ts_nr)&" ";
	f_vty_transceive(BSCVTY, cmd & suffix);
}

/* execute a "bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7>" command on given Dchan */
private function f_vty_ss_action(charstring suffix, integer bts_nr, integer trx_nr, RslChannelNr chan_nr)
runs on MSC_ConnHdlr {
	/* FIXME: resolve those from component-global state */
	var integer ts_nr := chan_nr.tn;
	var integer ss_nr;
	if (ischosen(chan_nr.u.ch0)) {
		ss_nr := 0;
	} else if (ischosen(chan_nr.u.lm)) {
		ss_nr := chan_nr.u.lm.sub_chan;
	} else if (ischosen(chan_nr.u.sdcch4)) {
		ss_nr := chan_nr.u.sdcch4.sub_chan;
	} else if (ischosen(chan_nr.u.sdcch8)) {
		ss_nr := chan_nr.u.sdcch8.sub_chan;
	} else {
		setverdict(fail, "Invalid ChanNr ", chan_nr);
		mtc.stop;
	}

	var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
				" timeslot "&int2str(ts_nr)&" sub-slot "&int2str(ss_nr)&" ";
	f_vty_transceive(BSCVTY, cmd & suffix);
}

/* Even though the VTY command to trigger handover takes a new BTS number as argument, behind the scenes osmo-bsc always
 * translates that to a target ARFCN+BSIC first. See bsc_vty.c trigger_ho_or_as(), which puts the selected BTS' neighbor
 * ident key (ARFCN + BSIC) in the struct passed on to handover_request(). handover_start() then resolves that to a
 * viable actual neighbor cell. So from the internal osmo-bsc perspective, we always request handover to an ARFCN + BSIC
 * pair, not really to a specific BTS number. */
private function f_vty_handover(integer bts_nr, integer trx_nr, RslChannelNr chan_nr,
				integer new_bts_nr)
runs on MSC_ConnHdlr {
	f_vty_ss_action("handover " & int2str(new_bts_nr), bts_nr, trx_nr, chan_nr);
}

/* intra-BSC hand-over between BTS0 and BTS1 */
private function f_tc_ho_int(charstring id) runs on MSC_ConnHdlr {
	g_pars := f_gen_test_hdlr_pars();
	var template PDU_BSSAP exp_compl := f_gen_exp_compl();
	var PDU_BSSAP ass_cmd := f_gen_ass_req();
	const OCT8 kc := '0001020304050607'O;

	ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
	ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));

	f_establish_fully(ass_cmd, exp_compl);
	f_bts_0_cfg({"neighbor bts 1"});

	var HandoverState hs := {
		rr_ho_cmpl_seen := false,
		handover_done := false,
		old_chan_nr := -
	};
	/* issue hand-over command on VTY */
	f_vty_handover(0, 0, g_chan_nr, 1);
	/* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
	f_rslem_suspend(RSL1_PROC);

	/* From the MGW perspective, a handover is is characterized by
	 * performing one MDCX operation with the MGW. So we expect to see
	 * one more MDCX during handover. */
	g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;

	alt {
	[] as_handover(hs);
	}

	/* Since this is an internal handover we expect the BSC to inform the
	 * MSC about the event */
	BSSAP.receive(tr_BSSMAP_HandoverPerformed);

	/* Check the amount of MGCP transactions is still consistant with the
	 * test expectation */
	f_check_mgcp_expectations()
	f_sleep(0.5);
}

testcase TC_ho_int() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	f_init(2, true);
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_tc_ho_int));
	vc_conn.done;
}

/* Expecting MGCP to DLCX the endpoint's two connections: towards BTS and towards MSC */
private function f_expect_dlcx_conns() runs on MSC_ConnHdlr {
	var MgcpCommand mgcp;
	var template MgcpResponse mgcp_resp;
	var MGCP_RecvFrom mrf;
	var template MgcpMessage msg_resp;
	var template MgcpMessage msg_dlcx := {
		command := tr_DLCX()
	}

	if (g_pars.aoip) {
		MGCP.receive(tr_DLCX()) -> value mgcp {
				log("Got first DLCX: ", mgcp);
				MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
			};

		MGCP.receive(tr_DLCX()) -> value mgcp {
				log("Got second DLCX: ", mgcp);
				MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
			};
	} else  {
		/* For SCCPLite, BSC doesn't handle the MSC-side */
		MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_dlcx)) -> value mrf {
			log("Got first DLCX: ", mrf.msg.command);
			msg_resp := {
				response := ts_DLCX_ACK2(mrf.msg.command.line.trans_id)
			}
			MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, msg_resp));
		};
	}

	BSSAP.receive(tr_BSSMAP_ClearComplete);
}

private function f_tc_ho_out_of_this_bsc(charstring id) runs on MSC_ConnHdlr {
	g_pars := f_gen_test_hdlr_pars();

	var PDU_BSSAP ass_req := f_gen_ass_req();
	ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
	ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
	var template PDU_BSSAP exp_compl := f_gen_exp_compl();
	f_establish_fully(ass_req, exp_compl);

	f_bts_0_cfg({"neighbor lac 99 arfcn 123 bsic any"});
	f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");

	BSSAP.receive(tr_BSSMAP_HandoverRequired);

	f_sleep(0.5);
	/* The MSC negotiates Handover Request and Handover Request Ack with
	 * the other BSS and comes back with a BSSMAP Handover Command
	 * containing an RR Handover Command coming from the target BSS... */

	var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
	log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
	var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
	log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
	BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));

	/* expect the Handover Command to go out on RR */
	var RSL_Message rsl_ho_cmd
	RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
	log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
	var RSL_IE_Body rsl_ho_cmd_l3;
	if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
		log("RSL message contains no L3 Info IE, expected RR Handover Command");
		setverdict(fail);
	} else {
		log("Found L3 Info: ", rsl_ho_cmd_l3);
		if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
			log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
			setverdict(fail);
		} else {
			log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
			setverdict(pass);
		}
	}

	/* When the other BSS has reported a completed handover, this side is
	 * torn down. */

	var myBSSMAP_Cause cause_val := GSM0808_CAUSE_HANDOVER_SUCCESSFUL;
	var BssmapCause cause := enum2int(cause_val);
	BSSAP.send(ts_BSSMAP_ClearCommand(cause));

	f_expect_dlcx_conns();
	setverdict(pass);
	f_sleep(1.0);
}
testcase TC_ho_out_of_this_bsc() runs on test_CT {
	var MSC_ConnHdlr vc_conn;

	f_init(1, true);
	f_sleep(1.0);

	vc_conn := f_start_handler(refers(f_tc_ho_out_of_this_bsc));
	vc_conn.done;
}

/* BSC asks for inter-BSC HO, but the MSC decides that it won't happen and
 * simply never sends a BSSMAP Handover Command. */
private function f_tc_ho_out_fail_no_msc_response(charstring id) runs on MSC_ConnHdlr {
	g_pars := f_gen_test_hdlr_pars();

	var PDU_BSSAP ass_req := f_gen_ass_req();
	ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
	ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
	var template PDU_BSSAP exp_compl := f_gen_exp_compl();
	f_establish_fully(ass_req, exp_compl);

	f_bts_0_cfg({"neighbor lac 99 arfcn 123 bsic any"});
	f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");

	BSSAP.receive(tr_BSSMAP_HandoverRequired);

	/* osmo-bsc should time out 10 seconds after the handover started.
	 * Let's give it a bit extra. */
	f_sleep(15.0);

	/* The old lchan and conn should still be active. See that arbitrary L3
	 * is still going through. */
	var octetstring l3 := '0123456789'O;
	RSL.send(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
	var template PDU_BSSAP exp_data := {
		    discriminator := '1'B,
		    spare := '0000000'B,
		    dlci := '00'O,
		    lengthIndicator := 5,
		    pdu := {
			dtap := l3
		    }
		};
	BSSAP.receive(exp_data);
	setverdict(pass);
	f_sleep(1.0);
}
testcase TC_ho_out_fail_no_msc_response() runs on test_CT {
	var MSC_ConnHdlr vc_conn;

	f_init(1, true);
	f_sleep(1.0);

	vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_msc_response));
	vc_conn.done;
}

/* BSC asks for inter-BSC HO, receives BSSMAP Handover Command, but MS reports
 * RR Handover Failure. */
private function f_tc_ho_out_fail_rr_ho_failure(charstring id) runs on MSC_ConnHdlr {
	g_pars := f_gen_test_hdlr_pars();

	var PDU_BSSAP ass_req := f_gen_ass_req();
	ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
	ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
	var template PDU_BSSAP exp_compl := f_gen_exp_compl();
	f_establish_fully(ass_req, exp_compl);

	f_bts_0_cfg({"neighbor lac 99 arfcn 123 bsic any"});
	f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");

	BSSAP.receive(tr_BSSMAP_HandoverRequired);

	f_sleep(0.5);
	/* The MSC negotiates Handover Request and Handover Request Ack with
	 * the other BSS and comes back with a BSSMAP Handover Command
	 * containing an RR Handover Command coming from the target BSS... */

	var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
	log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
	var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
	log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
	BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));

	/* expect the Handover Command to go out on RR */
	var RSL_Message rsl_ho_cmd
	RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
	log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
	var RSL_IE_Body rsl_ho_cmd_l3;
	if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
		log("RSL message contains no L3 Info IE, expected RR Handover Command");
		setverdict(fail);
	} else {
		log("Found L3 Info: ", rsl_ho_cmd_l3);
		if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
			log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
			setverdict(fail);
		} else {
			log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
			setverdict(pass);
		}
	}

	f_sleep(0.2);
	f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));

	/* Should tell the MSC about the failure */
	BSSAP.receive(tr_BSSMAP_HandoverFailure);

	f_sleep(1.0);

	/* The old lchan and conn should still be active. See that arbitrary L3
	 * is still going through. */
	var octetstring l3 := '0123456789'O;
	RSL.send(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
	var template PDU_BSSAP exp_data := {
		    discriminator := '1'B,
		    spare := '0000000'B,
		    dlci := '00'O,
		    lengthIndicator := 5,
		    pdu := {
			dtap := l3
		    }
		};
	BSSAP.receive(exp_data);
	setverdict(pass);
	f_sleep(1.0);

	setverdict(pass);
	f_sleep(1.0);
}
testcase TC_ho_out_fail_rr_ho_failure() runs on test_CT {
	var MSC_ConnHdlr vc_conn;

	f_init(1, true);
	f_sleep(1.0);

	vc_conn := f_start_handler(refers(f_tc_ho_out_fail_rr_ho_failure));
	vc_conn.done;
}

/* BSC asks for inter-BSC-out HO, receives BSSMAP Handover Command, but then no reply is received about HO outcome
 * (neither BSSMAP Clear Command for success nor RR Handover Failure). 48.008 3.1.5.3.3 "Abnormal Conditions" applies
 * and the lchan is released. */
private function f_tc_ho_out_fail_no_result_after_ho_cmd(charstring id) runs on MSC_ConnHdlr {
	g_pars := f_gen_test_hdlr_pars();

	var PDU_BSSAP ass_req := f_gen_ass_req();
	ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
	ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
	var template PDU_BSSAP exp_compl := f_gen_exp_compl();
	f_establish_fully(ass_req, exp_compl);

	f_bts_0_cfg({"neighbor lac 99 arfcn 123 bsic any"});
	f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");

	BSSAP.receive(tr_BSSMAP_HandoverRequired);

	f_sleep(0.5);
	/* The MSC negotiates Handover Request and Handover Request Ack with
	 * the other BSS and comes back with a BSSMAP Handover Command
	 * containing an RR Handover Command coming from the target BSS... */

	var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
	log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
	var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
	log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
	BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));

	/* expect the Handover Command to go out on RR */
	var RSL_Message rsl_ho_cmd
	RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
	log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
	var RSL_IE_Body rsl_ho_cmd_l3;
	if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
		log("RSL message contains no L3 Info IE, expected RR Handover Command");
		setverdict(fail);
	} else {
		log("Found L3 Info: ", rsl_ho_cmd_l3);
		if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
			log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
			setverdict(fail);
		} else {
			log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
			setverdict(pass);
		}
	}

	/* We get neither success nor failure report from the remote BSS.  Eventually T8 times out and we run into 3GPP
	 * TS 48.008 3.1.5.3.3 "Abnormal Conditions": Clear Request should go to the MSC, and RR should be released
	 * after Clear Command */

	var PDU_BSSAP rx_clear_request;
	BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
	log("Got BSSMAP Clear Request");
	/* Instruct BSC to clear channel */
	var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
	BSSAP.send(ts_BSSMAP_ClearCommand(cause));

	var MgcpCommand mgcp;
	interleave {
	[] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
			log("Got Deact SACCH");
		}
	[] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
			log("Got RR Release");
		}
	[] RSL.receive(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL)) {
			log("Got RF Chan Rel");
			RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
		}
	}

	f_expect_dlcx_conns();

	setverdict(pass);
	f_sleep(1.0);
}
testcase TC_ho_out_fail_no_result_after_ho_cmd() runs on test_CT {
	var MSC_ConnHdlr vc_conn;

	f_init(1, true);
	f_sleep(1.0);

	vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_result_after_ho_cmd));
	vc_conn.done;
}

private function f_tc_ho_into_this_bsc(charstring id) runs on MSC_ConnHdlr {
	/* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
	 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
	 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
	 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
	 * before we get started. */
	var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
	f_rslem_register(0, new_chan_nr);
	g_chan_nr := new_chan_nr;
	f_sleep(1.0);

	f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
	f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
	activate(as_Media());

	BSSAP.send(ts_BSSAP_Conn_Req(g_pars.handover.sccp_addr_bsc, g_pars.handover.sccp_addr_msc,
				     f_gen_handover_req()));
	BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);

	/* The RSL Emulation magically accepts the Chan Activ behind the scenes. */

	var PDU_BSSAP rx_bssap;
	var octetstring ho_command_str;

	BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;

	ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
	log("Received L3 Info in HO Request Ack: ", ho_command_str);
	var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
	log("L3 Info in HO Request Ack is ", ho_command);

	var GsmArfcn arfcn;
	var RslChannelNr actual_new_chan_nr;
	f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
			actual_new_chan_nr, arfcn);

	if (actual_new_chan_nr != new_chan_nr) {
		log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
		    " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
		setverdict(fail);
		return;
	}
	log("Handover Command chan_nr is", actual_new_chan_nr);

	/* Now the MSC forwards the RR Handover Command to the other BSC, which
	 * tells the MS to handover to the new lchan. Here comes the new MS on
	 * the new lchan with a Handover RACH: */

	/* send handover detect */

	RSL.send(ts_RSL_HANDO_DET(new_chan_nr));

	BSSAP.receive(tr_BSSMAP_HandoverDetect);

	/* send handover complete over the new channel */

	var PDU_ML3_MS_NW l3_tx := valueof(ts_RRM_HandoverComplete('00'O));
	RSL.send(ts_RSL_EST_IND(new_chan_nr, valueof(ts_RslLinkID_DCCH(0)),
				enc_PDU_ML3_MS_NW(l3_tx)));

	BSSAP.receive(tr_BSSMAP_HandoverComplete);
	setverdict(pass);
}
testcase TC_ho_into_this_bsc() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	var TestHdlrParams pars := f_gen_test_hdlr_pars();

	f_init(1, true);
	f_sleep(1.0);

	pars.handover.sccp_addr_msc := g_bssap.sccp_addr_own;
	pars.handover.sccp_addr_bsc := g_bssap.sccp_addr_peer;

	vc_conn := f_start_handler(refers(f_tc_ho_into_this_bsc), pars);
	vc_conn.done;
}

private function f_tc_ho_in_fail_msc_clears(charstring id) runs on MSC_ConnHdlr {
	var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
	f_rslem_register(0, new_chan_nr);
	g_chan_nr := new_chan_nr;
	f_sleep(1.0);

	f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
	f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
	activate(as_Media());

	BSSAP.send(ts_BSSAP_Conn_Req(g_pars.handover.sccp_addr_bsc, g_pars.handover.sccp_addr_msc,
				     f_gen_handover_req()));
	BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);

	/* The RSL Emulation magically accepts the Chan Activ behind the scenes. */

	var PDU_BSSAP rx_bssap;
	var octetstring ho_command_str;

	BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;

	ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
	log("Received L3 Info in HO Request Ack: ", ho_command_str);
	var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
	log("L3 Info in HO Request Ack is ", ho_command);

	var GsmArfcn arfcn;
	var RslChannelNr actual_new_chan_nr;
	f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
			actual_new_chan_nr, arfcn);

	if (actual_new_chan_nr != new_chan_nr) {
		log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
		    " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
		setverdict(fail);
		return;
	}
	log("Handover Command chan_nr is", actual_new_chan_nr);

	/* For deterministic test results, give some time for the MGW endpoint to be configured */
	f_sleep(1.0);

	/* Now the MSC forwards the RR Handover Command to the other BSC, which
	 * tells the MS to handover to the new lchan. In this case, the MS
	 * reports a Handover Failure to the old BSS, which forwards a BSSMAP
	 * Handover Failure to the MSC. The procedure according to 3GPP TS
	 * 48.008 3.1.5.3.2 "Handover Failure" is then that the MSC sends a
	 * BSSMAP Clear Command: */

	var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
	var BssmapCause cause := enum2int(cause_val);
	BSSAP.send(ts_BSSMAP_ClearCommand(cause));

	f_expect_dlcx_conns();
	setverdict(pass);
	f_sleep(1.0);

	setverdict(pass);
}
testcase TC_ho_in_fail_msc_clears() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	var TestHdlrParams pars := f_gen_test_hdlr_pars();

	f_init(1, true);
	f_sleep(1.0);

	pars.handover.sccp_addr_msc := g_bssap.sccp_addr_own;
	pars.handover.sccp_addr_bsc := g_bssap.sccp_addr_peer;

	vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears), pars);
	vc_conn.done;
}

private function f_tc_ho_in_fail_msc_clears_after_ho_detect(charstring id) runs on MSC_ConnHdlr {
	/* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
	 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
	 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
	 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
	 * before we get started. */
	var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
	f_rslem_register(0, new_chan_nr);
	g_chan_nr := new_chan_nr;
	f_sleep(1.0);

	f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
	f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
	activate(as_Media());

	BSSAP.send(ts_BSSAP_Conn_Req(g_pars.handover.sccp_addr_bsc, g_pars.handover.sccp_addr_msc,
				     f_gen_handover_req()));
	BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);

	/* The RSL Emulation magically accepts the Chan Activ behind the scenes. */

	var PDU_BSSAP rx_bssap;
	var octetstring ho_command_str;

	BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;

	ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
	log("Received L3 Info in HO Request Ack: ", ho_command_str);
	var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
	log("L3 Info in HO Request Ack is ", ho_command);

	var GsmArfcn arfcn;
	var RslChannelNr actual_new_chan_nr;
	f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
			actual_new_chan_nr, arfcn);

	if (actual_new_chan_nr != new_chan_nr) {
		log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
		    " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
		setverdict(fail);
		return;
	}
	log("Handover Command chan_nr is", actual_new_chan_nr);

	/* Now the MSC forwards the RR Handover Command to the other BSC, which
	 * tells the MS to handover to the new lchan. Here comes the new MS on
	 * the new lchan with a Handover RACH: */

	/* send handover detect */

	RSL.send(ts_RSL_HANDO_DET(new_chan_nr));

	BSSAP.receive(tr_BSSMAP_HandoverDetect);

	/* The MSC chooses to clear the connection now, maybe we got the
	 * Handover RACH on the new cell but the MS still signaled Handover
	 * Failure to the old BSS? */

	var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
	var BssmapCause cause := enum2int(cause_val);
	BSSAP.send(ts_BSSMAP_ClearCommand(cause));

	f_expect_dlcx_conns();
	setverdict(pass);
	f_sleep(1.0);
}
testcase TC_ho_in_fail_msc_clears_after_ho_detect() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	var TestHdlrParams pars := f_gen_test_hdlr_pars();

	f_init(1, true);
	f_sleep(1.0);

	pars.handover.sccp_addr_msc := g_bssap.sccp_addr_own;
	pars.handover.sccp_addr_bsc := g_bssap.sccp_addr_peer;

	vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears_after_ho_detect), pars);
	vc_conn.done;
}

/* The new BSS's lchan times out before the MSC decides that handover failed. */
private function f_tc_ho_in_fail_no_detect(charstring id) runs on MSC_ConnHdlr {
	var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
	f_rslem_register(0, new_chan_nr);
	g_chan_nr := new_chan_nr;
	f_sleep(1.0);

	f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
	f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
	activate(as_Media());

	BSSAP.send(ts_BSSAP_Conn_Req(g_pars.handover.sccp_addr_bsc, g_pars.handover.sccp_addr_msc,
				     f_gen_handover_req()));
	BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);

	/* The RSL Emulation magically accepts the Chan Activ behind the scenes. */

	var PDU_BSSAP rx_bssap;
	var octetstring ho_command_str;

	BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;

	ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
	log("Received L3 Info in HO Request Ack: ", ho_command_str);
	var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
	log("L3 Info in HO Request Ack is ", ho_command);

	var GsmArfcn arfcn;
	var RslChannelNr actual_new_chan_nr;
	f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
			actual_new_chan_nr, arfcn);

	if (actual_new_chan_nr != new_chan_nr) {
		log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
		    " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
		setverdict(fail);
		return;
	}
	log("Handover Command chan_nr is", actual_new_chan_nr);

	/* Now the MSC forwards the RR Handover Command to the other BSC, which
	 * tells the MS to handover to the new lchan. But the MS never shows up
	 * on the new lchan. */

	BSSAP.receive(tr_BSSMAP_HandoverFailure);

	/* Did osmo-bsc also send a Clear Request? */
	timer T := 0.5;
	T.start;
	alt {
	[] BSSAP.receive(tr_BSSMAP_ClearRequest);
	[] T.timeout { }
	}

	/* MSC plays along with a Clear Command (no matter whether osmo-bsc
	 * asked for it, this is a Handover Failure after all). */

	var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
	var BssmapCause cause := enum2int(cause_val);
	BSSAP.send(ts_BSSMAP_ClearCommand(cause));

	f_expect_dlcx_conns();
	setverdict(pass);
	f_sleep(1.0);

	setverdict(pass);
}
testcase TC_ho_in_fail_no_detect() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	var TestHdlrParams pars := f_gen_test_hdlr_pars();

	f_init(1, true);
	f_sleep(1.0);

	pars.handover.sccp_addr_msc := g_bssap.sccp_addr_own;
	pars.handover.sccp_addr_bsc := g_bssap.sccp_addr_peer;

	vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect), pars);
	vc_conn.done;
}

/* Same as f_tc_ho_in_fail_no_detect, but MSC fails to send a Clear Command */
private function f_tc_ho_in_fail_no_detect2(charstring id) runs on MSC_ConnHdlr {
	var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
	f_rslem_register(0, new_chan_nr);
	g_chan_nr := new_chan_nr;
	f_sleep(1.0);

	f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
	f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
	activate(as_Media());

	BSSAP.send(ts_BSSAP_Conn_Req(g_pars.handover.sccp_addr_bsc, g_pars.handover.sccp_addr_msc,
				     f_gen_handover_req()));
	BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);

	/* The RSL Emulation magically accepts the Chan Activ behind the scenes. */

	var PDU_BSSAP rx_bssap;
	var octetstring ho_command_str;

	BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;

	ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
	log("Received L3 Info in HO Request Ack: ", ho_command_str);
	var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
	log("L3 Info in HO Request Ack is ", ho_command);

	var GsmArfcn arfcn;
	var RslChannelNr actual_new_chan_nr;
	f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
			actual_new_chan_nr, arfcn);

	if (actual_new_chan_nr != new_chan_nr) {
		log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
		    " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
		setverdict(fail);
		return;
	}
	log("Handover Command chan_nr is", actual_new_chan_nr);

	/* Now the MSC forwards the RR Handover Command to the other BSC, which
	 * tells the MS to handover to the new lchan. But the MS never shows up
	 * on the new lchan. */

	BSSAP.receive(tr_BSSMAP_HandoverFailure);

	/* MSC plays dumb and sends no Clear Command */
	var PDU_BSSAP rx_clear_request;

	BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request {
		var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
		BSSAP.send(ts_BSSMAP_ClearCommand(cause));
	};
	f_expect_dlcx_conns();
	setverdict(pass);
	f_sleep(1.0);
}
testcase TC_ho_in_fail_no_detect2() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	var TestHdlrParams pars := f_gen_test_hdlr_pars();

	f_init(1, true);
	f_sleep(1.0);

	pars.handover.sccp_addr_msc := g_bssap.sccp_addr_own;
	pars.handover.sccp_addr_bsc := g_bssap.sccp_addr_peer;

	vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect2), pars);
	vc_conn.done;
}

type record of charstring Commands;

private function f_bts_0_cfg(Commands cmds := {}) runs on MSC_ConnHdlr
{
	f_vty_enter_cfg_bts(BSCVTY, 0);
	for (var integer i := 0; i < sizeof(cmds); i := i+1) {
		f_vty_transceive(BSCVTY, cmds[i]);
	}
	f_vty_transceive(BSCVTY, "end");
}

private function f_cs7_inst_0_cfg(TELNETasp_PT pt, Commands cmds := {})
{
	f_vty_enter_cfg_cs7_inst(pt, 0);
	for (var integer i := 0; i < sizeof(cmds); i := i+1) {
		f_vty_transceive(pt, cmds[i]);
	}
	f_vty_transceive(pt, "end");
}

private function f_probe_for_handover(charstring log_label,
				      charstring log_descr,
				      charstring handover_vty_cmd,
				      boolean expect_handover,
				      boolean is_inter_bsc_handover := false)
runs on MSC_ConnHdlr
{
	var RSL_Message rsl;

	var charstring log_msg := " (expecting handover)"
	if (not expect_handover) {
		log_msg := " (expecting NO handover)";
	}
	log("f_probe_for_handover starting: " & log_label & ": " & log_descr & log_msg);
	f_vty_transceive(BSCVTY, handover_vty_cmd);

	/* We're going to thwart any and all handover attempts, just be ready to handle (and ignore) handover target
	 * lchans to be established on bts 1 or bts 2. */
	f_rslem_suspend(RSL1_PROC);
	f_rslem_suspend(RSL2_PROC);

	timer T := 2.0;
	T.start;

	alt {
	[] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
		var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
		log("Rx L3 from net: ", l3);
		if (ischosen(l3.msgs.rrm.handoverCommand)) {
			var RslChannelNr new_chan_nr;
			var GsmArfcn arfcn;
			f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
					   new_chan_nr, arfcn);
			log("Handover to new chan ", new_chan_nr, " on ARFCN ", arfcn);
			log(l3.msgs.rrm.handoverCommand);

			/* Need to register for new lchan on new BTS -- it's either bts 1 or bts 2.  It doesn't really
			 * matter on which BTS it really is, we're not going to follow through an entire handover
			 * anyway. */
			f_rslem_register(0, new_chan_nr, RSL1_PROC);
			f_rslem_resume(RSL1_PROC);
			f_rslem_register(0, new_chan_nr, RSL2_PROC);
			f_rslem_resume(RSL2_PROC);

			if (expect_handover and not is_inter_bsc_handover) {
				setverdict(pass);
				log("f_probe_for_handover(" & log_label & "): Got RSL Handover Command as expected.");
			} else {
				setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got RSL Handover Command. "
						 & log_label & ": " & log_descr);
			}

			log("f_probe_for_handover(" & log_label & "): Ending the test: Handover Failure stops the procedure.");
			/* osmo-bsc has triggered Handover. That's all we need to know for this test, reply with
			 * Handover Failure. */
			f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));

			/* target BTS is told to release lchan again; don't care which BTS nor what messages. */
			f_sleep(0.5);
			RSL1.clear;
			RSL2.clear;
			log("f_probe_for_handover(" & log_label & "): done (got RSL Handover Command)");
			break;
		} else {
			repeat;
		}
		}
	[] BSSAP.receive(tr_BSSMAP_HandoverRequired) {
			if (expect_handover and is_inter_bsc_handover) {
				setverdict(pass);
				log("f_probe_for_handover(" & log_label & "): Got BSSMAP Handover Required as expected.");
			} else {
				setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got BSSMAP Handover Required. "
						 & log_label & ": " & log_descr);
			}

			log("f_probe_for_handover(" & log_label & "): done (got BSSMAP Handover Required)");

			/* Note: f_tc_ho_neighbor_config_start() sets T7, the timeout for BSSMAP Handover Required, to
			 * 1 second. There is no legal way to quickly abort a handover after a BSSMAP Handover Required,
			 * setting a short timeout and waiting is the only way. */
			log("f_probe_for_handover(" & log_label & "): waiting for inter-BSC HO to time out...");
			f_sleep(1.5);
			log("f_probe_for_handover(" & log_label & "): ...done");

			break;
		}
	[] T.timeout {
		if (expect_handover) {
			setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected Handover, but got none. "
					 & log_label & ": " & log_descr);
		} else {
			setverdict(pass);
			log("f_probe_for_handover(" & log_label & "): Got no Handover, as expected.");
		}
		log("f_probe_for_handover(" & log_label & "): done (got no Handover)");
		break;
		}
	}

	f_rslem_resume(RSL1_PROC);
	f_rslem_resume(RSL2_PROC);
	f_sleep(3.0);
	RSL.clear;

	log("f_probe_for_handover(" & log_label & "): done clearing");
}

/* Test the effect of various neighbor configuration scenarios:
 *
 * To avoid complexity, block off any actual handover operation, and always remain on the lchan at bts 0.
 * Reconfigure the neighbors for bts 0, trigger a Handover, and probe whether osmo-bsc does or doesn't start HO.
 */
private function f_tc_ho_neighbor_config_start() runs on MSC_ConnHdlr {
	g_pars := f_gen_test_hdlr_pars();
	var template PDU_BSSAP exp_compl := f_gen_exp_compl();
	var PDU_BSSAP ass_cmd := f_gen_ass_req();
	const OCT8 kc := '0001020304050607'O;

	ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
	ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));

	/* Establish lchan at bts 0 */
	f_establish_fully(ass_cmd, exp_compl);

	/* Shorten the inter-BSC Handover timeout, to not wait so long for inter-BSC Handovers */
	f_vty_enter_cfg_network(BSCVTY);
	f_vty_transceive(BSCVTY, "timer T7 1");
	f_vty_transceive(BSCVTY, "end");
}

private function f_tc_ho_neighbor_config_1(charstring id) runs on MSC_ConnHdlr {
	f_tc_ho_neighbor_config_start();

	/*
	 * bts 0 ARFCN 871 BSIC 10
	 * bts 1 ARFCN 871 BSIC 11
	 * bts 2 ARFCN 871 BSIC 12
	 * bts 3 ARFCN 871 BSIC 12  serves as ambiguity for bts 2, re-using the ARFCN+BSIC
	 */

	log("f_tc_ho_neighbor_config: 1. No 'neighbor' config");
	f_bts_0_cfg({"no neighbors"});
	f_probe_for_handover("1.a", "HO to bts 1 works, implicitly listed as neighbor (legacy behavior when none are configured)",
			"handover any to arfcn 871 bsic 11",
			true);

	f_probe_for_handover("1.b", "HO to unknown cell does not start",
			"handover any to arfcn 13 bsic 39",
			false);

	f_probe_for_handover("1.c", "HO to 871-12 is ambiguous = error",
			"handover any to arfcn 871 bsic 12",
			false);

	f_probe_for_handover("1.d", "HO to 871-11 still works (verify that this test properly cleans up)",
			"handover any to arfcn 871 bsic 11",
			true);
}
private function f_tc_ho_neighbor_config_2(charstring id) runs on MSC_ConnHdlr {
	f_tc_ho_neighbor_config_start();

	/*
	 * bts 0 ARFCN 871 BSIC 10
	 * bts 1 ARFCN 871 BSIC 11
	 * bts 2 ARFCN 871 BSIC 12
	 * bts 3 ARFCN 871 BSIC 12  serves as ambiguity for bts 2, re-using the ARFCN+BSIC
	 */

	log("f_tc_ho_neighbor_config: 2. explicit local neighbor: 'neighbor bts 1'");
	f_bts_0_cfg({"neighbor bts 1"});
	f_sleep(0.5);

	f_probe_for_handover("2.a", "HO to bts 1 works, explicitly listed as neighbor",
			"handover any to arfcn 871 bsic 11",
			true);

	f_probe_for_handover("2.b", "HO to bts 2 doesn't work, not listed as neighbor",
			"handover any to arfcn 871 bsic 12",
			false);
}
private function f_tc_ho_neighbor_config_3(charstring id) runs on MSC_ConnHdlr {
	f_tc_ho_neighbor_config_start();

	/*
	 * bts 0 ARFCN 871 BSIC 10
	 * bts 1 ARFCN 871 BSIC 11
	 * bts 2 ARFCN 871 BSIC 12
	 * bts 3 ARFCN 871 BSIC 12  serves as ambiguity for bts 2, re-using the ARFCN+BSIC
	 */

	log("f_tc_ho_neighbor_config: 3. explicit local neighbor: 'neighbor bts 2'");
	f_bts_0_cfg({"no neighbors", "neighbor bts 2"});
	f_sleep(0.5);

	f_probe_for_handover("3.a", "HO to bts 1 doesn't work, not listed as neighbor",
			"handover any to arfcn 871 bsic 11",
			false);
	f_probe_for_handover("3.b", "HO to bts 2 works, explicitly listed as neighbor; no ambiguity because bts 3 is not listed as neighbor",
			"handover any to arfcn 871 bsic 12",
			true);
}
private function f_tc_ho_neighbor_config_4(charstring id) runs on MSC_ConnHdlr {
	f_tc_ho_neighbor_config_start();

	/*
	 * bts 0 ARFCN 871 BSIC 10
	 * bts 1 ARFCN 871 BSIC 11
	 * bts 2 ARFCN 871 BSIC 12
	 * bts 3 ARFCN 871 BSIC 12  serves as ambiguity for bts 2, re-using the ARFCN+BSIC
	 */

	log("f_tc_ho_neighbor_config: 4. explicit remote neighbor: 'neighbor lac 99 arfcn 123 bsic 45'");
	f_bts_0_cfg({"no neighbors", "neighbor lac 99 arfcn 123 bsic 45"});
	f_sleep(0.5);

	f_probe_for_handover("4.a", "HO to bts 1 doesn't work, not listed as neighbor",
			"handover any to arfcn 871 bsic 11",
			false);
	f_probe_for_handover("4.b", "HO to bts 2 doesn't work, not listed as neighbor",
			"handover any to arfcn 871 bsic 12",
			false);
	f_probe_for_handover("4.c", "HO to 123-45 triggers inter-BSC HO",
			"handover any to arfcn 123 bsic 45",
			true, true);
}
private function f_tc_ho_neighbor_config_5(charstring id) runs on MSC_ConnHdlr {
	f_tc_ho_neighbor_config_start();

	/*
	 * bts 0 ARFCN 871 BSIC 10
	 * bts 1 ARFCN 871 BSIC 11
	 * bts 2 ARFCN 871 BSIC 12
	 * bts 3 ARFCN 871 BSIC 12  serves as ambiguity for bts 2, re-using the ARFCN+BSIC
	 */

	log("f_tc_ho_neighbor_config: 5. explicit remote neighbor re-using ARFCN+BSIC: 'neighbor lac 99 arfcn 871 bsic 12'");
	f_bts_0_cfg({"no neighbors", "neighbor lac 99 arfcn 871 bsic 12"});
	f_sleep(0.5);

	f_probe_for_handover("5.a", "HO to 871-12 triggers inter-BSC HO (ignoring local cells with same ARFCN+BSIC)",
			"handover any to arfcn 871 bsic 12",
			true, true);
}
private function f_tc_ho_neighbor_config_6(charstring id) runs on MSC_ConnHdlr {
	f_tc_ho_neighbor_config_start();

	/*
	 * bts 0 ARFCN 871 BSIC 10
	 * bts 1 ARFCN 871 BSIC 11
	 * bts 2 ARFCN 871 BSIC 12
	 * bts 3 ARFCN 871 BSIC 12  serves as ambiguity for bts 2, re-using the ARFCN+BSIC
	 */

	log("f_tc_ho_neighbor_config: 6. config error: explicit local and remote neighbors with ambiguous ARFCN+BSIC:"
	    & " 'neighbor bts 2; neighbor lac 99 arfcn 871 bsic 12'");
	f_bts_0_cfg({"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 871 bsic 12"});
	f_sleep(0.5);

	f_probe_for_handover("6.a", "HO to 871-12 is ambiguous = error",
			"handover any to arfcn 871 bsic 12",
			false);
}
private function f_tc_ho_neighbor_config_7(charstring id) runs on MSC_ConnHdlr {
	f_tc_ho_neighbor_config_start();

	/*
	 * bts 0 ARFCN 871 BSIC 10
	 * bts 1 ARFCN 871 BSIC 11
	 * bts 2 ARFCN 871 BSIC 12
	 * bts 3 ARFCN 871 BSIC 12  serves as ambiguity for bts 2, re-using the ARFCN+BSIC
	 */

	log("f_tc_ho_neighbor_config: 7. explicit local and remote neighbors:"
	    & " 'neighbor bts 2; neighbor lac 99 arfcn 123 bsic 45'");
	f_bts_0_cfg({"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 123 bsic 45"});
	f_sleep(0.5);

	f_probe_for_handover("7.a", "HO to 871-12 does HO to bts 2",
			"handover any to arfcn 871 bsic 12",
			true);
	f_probe_for_handover("7.b", "HO to 123-45 triggers inter-BSC HO",
			"handover any to arfcn 123 bsic 45",
			true, true);
}

testcase TC_ho_neighbor_config_1() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	f_init(3, true);
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_1));
	vc_conn.done;
}
testcase TC_ho_neighbor_config_2() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	f_init(3, true);
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_2));
	vc_conn.done;
}
testcase TC_ho_neighbor_config_3() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	f_init(3, true);
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_3));
	vc_conn.done;
}
testcase TC_ho_neighbor_config_4() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	f_init(3, true);
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_4));
	vc_conn.done;
}
testcase TC_ho_neighbor_config_5() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	f_init(3, true);
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_5));
	vc_conn.done;
}
testcase TC_ho_neighbor_config_6() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	f_init(3, true);
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_6));
	vc_conn.done;
}
testcase TC_ho_neighbor_config_7() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	f_init(3, true);
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_7));
	vc_conn.done;
}

/* OS#3041: Open and close N connections in a normal fashion, and expect no
 * BSSMAP Reset just because of that. */
testcase TC_bssap_rlsd_does_not_cause_bssmap_reset() runs on test_CT {
	var default d;
	var integer i;
	var DchanTuple dt;

	f_init();

	/* Wait for initial BSSMAP Reset to pass */
	f_sleep(4.0);

	d := activate(no_bssmap_reset());

	/* Setup up a number of connections and RLSD them again from the MSC
	 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
	 * Let's do it some more times for good measure. */
	for (i := 0; i < 4; i := i+1) {
		/* Since we're doing a lot of runs, give each one a fresh
		 * T_guard from the top. */
		T_guard.start;

		/* Setup a BSSAP connection and clear it right away. This is
		 * the MSC telling the BSC about a planned release, it's not an
		 * erratic loss of a connection. */
		dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);

		/* MSC disconnects (RLSD). */
		BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
	}

	/* In the buggy behavior, a timeout of 2 seconds happens between above
	 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
	 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
	f_sleep(4.0);

	deactivate(d);
	f_shutdown_helper();
}

/* OS#3041: Open and close N connections in a normal fashion, and expect no
 * BSSMAP Reset just because of that. Invoke the release by a BSSMAP Clear from
 * the MSC. */
testcase TC_bssmap_clear_does_not_cause_bssmap_reset() runs on test_CT {
	var default d;
	var integer i;
	var DchanTuple dt;
	var BSSAP_N_DATA_ind rx_di;
	var myBSSMAP_Cause cause_val := GSM0808_CAUSE_CALL_CONTROL;
	var BssmapCause cause := enum2int(cause_val);

	f_init();

	/* Wait for initial BSSMAP Reset to pass */
	f_sleep(4.0);

	d := activate(no_bssmap_reset());

	/* Setup up a number of connections and RLSD them again from the MSC
	 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
	 * Let's do it some more times for good measure. */
	for (i := 0; i < 8; i := i+1) {
		/* Since we're doing a lot of runs, give each one a fresh
		 * T_guard from the top. */
		T_guard.start;

		/* Setup a BSSAP connection and clear it right away. This is
		 * the MSC telling the BSC about a planned release, it's not an
		 * erratic loss of a connection. */
		dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);

		/* Instruct BSC to clear channel */
		BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));

		/* expect BSC to disable the channel */
		f_exp_chan_rel_and_clear(dt, 0);
	}

	/* In the buggy behavior, a timeout of 2 seconds happens between above
	 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
	 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
	f_sleep(4.0);

	deactivate(d);
	f_shutdown_helper();
}

/* OS#3041: Open and close N connections in a normal fashion, and expect no
 * BSSMAP Reset just because of that. Close connections from the MS side with a
 * Release Ind on RSL. */
testcase TC_ms_rel_ind_does_not_cause_bssmap_reset() runs on test_CT {
	var default d;
	var integer i;
	var DchanTuple dt;
	var BSSAP_N_DATA_ind rx_di;
	var integer j;

	f_init();

	/* Wait for initial BSSMAP Reset to pass */
	f_sleep(4.0);

	d := activate(no_bssmap_reset());

	/* Setup up a number of connections and RLSD them again from the MSC
	 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
	 * Let's do it some more times for good measure. */
	for (i := 0; i < 8; i := i+1) {
		/* Since we're doing a lot of runs, give each one a fresh
		 * T_guard from the top. */
		T_guard.start;

		/* Setup a BSSAP connection and clear it right away. This is
		 * the MSC telling the BSC about a planned release, it's not an
		 * erratic loss of a connection. */
		dt := f_est_dchan('23'O, 23, '00010203040506'O);

		/* simulate RLL REL IND */
		f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));

		/* expect Clear Request on MSC side */
		BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;

		/* Instruct BSC to clear channel */
		var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
		BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));

		/* expect BSC to disable the channel */
		f_exp_chan_rel_and_clear(dt, 0);
	}

	/* In the buggy behavior, a timeout of 2 seconds happens between above
	 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
	 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
	f_sleep(4.0);

	deactivate(d);
	f_shutdown_helper();
}

/***********************************************************************
 * IPA style dynamic PDCH
 ***********************************************************************/

private function f_dyn_ipa_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
				    template (omit) RSL_Cause nack := omit)
runs on test_CT {
	var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
	var RSL_Message rsl_unused;
	/* ask BSC via VTY to activate a given IPA style chan as PDCH */
	f_vty_ts_action("pdch activate", bts_nr, trx_nr, ts_nr);
	/* expect the BSC to issue the related RSL command */
	rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
	if (istemplatekind(nack, "omit")) {
		/* respond with a related acknowledgement */
		f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
	} else {
		f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_NACK(chan_nr, valueof(nack)));
	}
}

private function f_dyn_ipa_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
				      template (omit) RSL_Cause nack := omit)
runs on test_CT {
	var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
	var RSL_Message rsl_unused;
	/* ask BSC via VTY to activate a given IPA style chan as PDCH */
	f_vty_ts_action("pdch deactivate", bts_nr, trx_nr, ts_nr);
	/* expect the BSC to issue the related RSL command */
	rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_DEACT(chan_nr));
	if (istemplatekind(nack, "omit")) {
		/* respond with a related acknowledgement */
		f_ipa_tx(0, ts_RSL_IPA_PDCH_DEACT_ACK(chan_nr));
	} else {
		f_ipa_tx(0, ts_RSL_IPA_PDCH_DEACT_NACK(chan_nr, valueof(nack)));
	}
}

private function f_ts_dyn_mode_get(integer bts_nr, integer trx_nr, integer ts_nr)
runs on test_CT return charstring {
	var charstring cmd, resp;
	cmd := "show timeslot "&int2str(bts_nr)&" "&int2str(trx_nr)&" "&int2str(ts_nr);
	return f_vty_transceive_match_regexp_retry(BSCVTY, cmd, "*\((*)\)*", 0, 4, 1.0);
}

private function f_ts_dyn_mode_assert(integer bts_nr, integer trx_nr, integer ts_nr,
					template charstring exp)
runs on test_CT {
	var charstring mode := f_ts_dyn_mode_get(bts_nr, trx_nr, ts_nr);
	if (not match(mode, exp)) {
		setverdict(fail, "Unexpected TS Mode: ", mode);
		mtc.stop;
	}
}

private function f_ts_set_chcomb(integer bts_nr, integer trx_nr, integer ts_nr, charstring chcomb)
runs on test_CT {
	f_vty_enter_cfg_ts(BSCVTY, bts_nr, trx_nr, ts_nr);
	f_vty_transceive(BSCVTY, "phys_chan_config " & chcomb);
	f_vty_transceive(BSCVTY, "end");
}

private const charstring TCHF_MODE := "TCH/F mode";
private const charstring TCHH_MODE := "TCH/H mode";
private const charstring PDCH_MODE := "PDCH mode";
private const charstring NONE_MODE := "NONE mode";

/* Test IPA PDCH activation / deactivation triggered by VTY */
testcase TC_dyn_pdch_ipa_act_deact() runs on test_CT {
	var RSL_Message rsl_unused;

	/* change Timeslot 6 before f_init() starts RSL */
	f_init_vty();
	f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
	f_vty_transceive(BSCVTY, "drop bts connection 0 oml");

	f_init(1, false);
	f_sleep(1.0);

	var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));

	log("TCH/F_PDCH pchan starts out in TCH/F mode:");
	f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
	/* The BSC will activate the dynamic PDCH by default, so confirm that */
	rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
	f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
	f_sleep(1.0);
	log("TCH/F_PDCH pchan, PDCH ACT was ACKed, so now in PDCH mode:");
	f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);

	/* De-activate it via VTY */
	f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
	f_sleep(1.0);
	log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
	f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);

	/* re-activate it via VTY */
	f_dyn_ipa_pdch_act(0, 0, chan_nr.tn);
	f_sleep(1.0);
	log("TCH/F_PDCH pchan, PDCH ACT via VTY, so now in PDCH mode:");
	f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);

	/* and finally de-activate it again */
	f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
	f_sleep(1.0);
	log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
	f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);

	/* clean up config */
	f_ts_set_chcomb(0, 0, 6, "PDCH");

	setverdict(pass);
}

/* Test IPA PDCH activation NACK */
testcase TC_dyn_pdch_ipa_act_nack() runs on test_CT {
	var RSL_Message rsl_unused;

	/* change Timeslot 6 before f_init() starts RSL */
	f_init_vty();
	f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
	f_vty_transceive(BSCVTY, "drop bts connection 0 oml");

	f_init(1, false);
	f_sleep(1.0);

	var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));

	f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
	/* The BSC will activate the dynamic PDCH by default, so confirm that */
	rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
	f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
	f_sleep(1.0);
	f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);

	/* De-activate it via VTY */
	f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
	f_sleep(1.0);
	f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);

	/* re-activate it via VTY, but fail that; check BSC still assumes TCH/F mode */
	f_dyn_ipa_pdch_act(0, 0, chan_nr.tn, RSL_ERR_EQUIPMENT_FAIL);
	f_sleep(1.0);
	f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);

	/* clean up config */
	f_ts_set_chcomb(0, 0, 6, "PDCH");

	setverdict(pass);
}


/***********************************************************************
 * Osmocom style dynamic PDCH
 ***********************************************************************/

private function f_dyn_osmo_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
				     template (omit) RSL_Cause nack := omit)
runs on test_CT {
	var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
	var RSL_Message rsl_unused;
	/* ask BSC via VTY to activate a given IPA style chan as PDCH */
	/* FIXME: no VTY command to activate Osmocom PDCH !! */
	/* expect the BSC to issue the related RSL command */
	rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT(chan_nr, ?));
	if (istemplatekind(nack, "omit")) {
		/* respond with a related acknowledgement */
		f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
	} else {
		f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, valueof(nack)));
	}
}

private function f_dyn_osmo_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
				       template (omit) RSL_Cause nack := omit)
runs on test_CT {
	var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
	var RSL_Message rsl_unused;
	/* ask BSC via VTY to activate a given IPA style chan as PDCH */
	/* FIXME: no VTY command to activate Osmocom PDCH !! */
	/* expect the BSC to issue the related RSL command */
	rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
	if (istemplatekind(nack, "omit")) {
		/* respond with a related acknowledgement */
		f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
	} else {
		//f_ipa_tx(0, ts_RSL_RF_CHAN_REL_NACK(chan_nr, valueof(nack)));
	}
}

/* Test Osmocom dyn PDCH activation / deactivation triggered by VTY */
testcase TC_dyn_pdch_osmo_act_deact() runs on test_CT {
	var RSL_Message rsl_unused;

	/* change Timeslot 6 before f_init() starts RSL */
	f_init_vty();
	f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
	f_vty_transceive(BSCVTY, "drop bts connection 0 oml");

	f_init(1, false);
	f_sleep(1.0);

	var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));

	log("TCH/F_TCH/H_PDCH pchan starts out in disabled mode:");
	f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
	/* The BSC will activate the dynamic PDCH by default, so confirm that */
	rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));

	f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
	f_sleep(1.0);
	log("TCH/F_TCH/H_PDCH requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
	f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);

	/* clean up config */
	f_ts_set_chcomb(0, 0, 6, "PDCH");

	setverdict(pass);
}

/* Test Osmocom dyn PDCH activation NACK behavior */
testcase TC_dyn_pdch_osmo_act_nack() runs on test_CT {
	var RSL_Message rsl_unused;

	/* change Timeslot 6 before f_init() starts RSL */
	f_init_vty();
	f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
	f_vty_transceive(BSCVTY, "drop bts connection 0 oml");

	f_init(1, false);
	f_sleep(1.0);

	var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));

	f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
	/* The BSC will activate the dynamic PDCH by default, so confirm that */
	rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));

	/* NACK this activation and expect the "show timeslot" mode still to be NONE */
	f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
	f_sleep(1.0);
	f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);

	/* clean up config */
	f_ts_set_chcomb(0, 0, 6, "PDCH");

	setverdict(pass);
}

testcase TC_chopped_ipa_ping() runs on test_CT {
	const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port, mp_bsc_ctrl_port};
	for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
		IPA_Testing.f_run_TC_chopped_ipa_ping(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
	}
}

testcase TC_chopped_ipa_payload() runs on test_CT {
	const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port
					/* TODO: mp_bsc_ctrl_port does not work yet */};
	for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
		IPA_Testing.f_run_TC_chopped_ipa_payload(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
	}
}

/* Verify the BSC sends the MS Power Parameters IE during CHAN ACT to make sure
   the BTS does autonomous MS power control loop */
testcase TC_assignment_verify_ms_power_params_ie() runs on test_CT {
	var MSC_ConnHdlr vc_conn;
	var TestHdlrParams pars := f_gen_test_hdlr_pars();
	//pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
	pars.exp_ms_power_params := true;

	f_init(1, true);
	f_sleep(1.0);
	vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
	vc_conn.done;
}

/* Dyn PDCH todo:
   * activate OSMO as TCH/F
   * activate OSMO as TCH/H
   * does the BSC-located PCU socket get the updated INFO?
   * what if no PCU is connected at the time?
   * is the info correct on delayed PCU (re)connect?
 */

control {
	/* CTRL interface testing */
	execute( TC_ctrl_msc_connection_status() );
	execute( TC_ctrl_msc0_connection_status() );
	execute( TC_ctrl() );
	if (mp_bssap_cfg.transport == BSSAP_TRANSPORT_SCCPlite_SERVER) {
		execute( TC_ctrl_location() );
	}

	/* RSL DCHAN Channel ACtivation / Deactivation */
	execute( TC_chan_act_noreply() );
	execute( TC_chan_act_counter() );
	execute( TC_chan_act_ack_noest() );
	execute( TC_chan_act_ack_est_ind_noreply() );
	execute( TC_chan_act_ack_est_ind_refused() );
	execute( TC_chan_act_nack() );
	execute( TC_chan_exhaustion() );
	execute( TC_chan_deact_silence() );
	execute( TC_chan_rel_rll_rel_ind() );
	execute( TC_chan_rel_conn_fail() );
	execute( TC_chan_rel_hard_clear() );
	execute( TC_chan_rel_hard_clear_csfb() );
	execute( TC_chan_rel_hard_rlsd() );
	execute( TC_chan_rel_hard_rlsd_ms_dead() );
	execute( TC_chan_rel_a_reset() );
	execute( TC_chan_rel_sccp_tiar_timeout() );

	execute( TC_outbound_connect() );

	/* Assignment related */
	execute( TC_assignment_cic_only() );
	execute( TC_assignment_csd() );
	execute( TC_assignment_ctm() );
	execute( TC_assignment_sign() );
	execute( TC_assignment_fr_a5_0() );
	execute( TC_assignment_fr_a5_1() );
	if (mp_bssap_cfg.transport == BSSAP_TRANSPORT_AoIP) {
		execute( TC_assignment_fr_a5_1_codec_missing() );
	}
	execute( TC_assignment_fr_a5_3() );
	execute( TC_assignment_fr_a5_4() );
	execute( TC_ciph_mode_a5_0() );
	execute( TC_ciph_mode_a5_1() );
	execute( TC_ciph_mode_a5_3() );

	execute( TC_assignment_codec_fr() );
	execute( TC_assignment_codec_hr() );
	execute( TC_assignment_codec_efr() );
	execute( TC_assignment_codec_amr_f() );
	execute( TC_assignment_codec_amr_h() );

	if (mp_bssap_cfg.transport == BSSAP_TRANSPORT_AoIP) {
		execute( TC_assignment_codec_amr_f_S1() );
		execute( TC_assignment_codec_amr_h_S1() );
		execute( TC_assignment_codec_amr_f_S124() );
		execute( TC_assignment_codec_amr_h_S124() );
		execute( TC_assignment_codec_amr_f_S0() );
		execute( TC_assignment_codec_amr_f_S02() );
		execute( TC_assignment_codec_amr_f_S024() );
		execute( TC_assignment_codec_amr_f_S0247() );
		execute( TC_assignment_codec_amr_h_S0() );
		execute( TC_assignment_codec_amr_h_S02() );
		execute( TC_assignment_codec_amr_h_S024() );
		execute( TC_assignment_codec_amr_h_S0247() );
		execute( TC_assignment_codec_amr_f_S01234567() );
		execute( TC_assignment_codec_amr_f_S0234567() );
		execute( TC_assignment_codec_amr_f_zero() );
		execute( TC_assignment_codec_amr_f_unsupp() );
		execute( TC_assignment_codec_amr_h_S7() );
	}

	execute( TC_assignment_codec_fr_exhausted_req_hr() );
	execute( TC_assignment_codec_fr_exhausted_req_fr() );
	execute( TC_assignment_codec_fr_exhausted_req_fr_hr() );
	execute( TC_assignment_codec_fr_exhausted_req_hr_fr() );
	execute( TC_assignment_codec_hr_exhausted_req_fr() );
	execute( TC_assignment_codec_hr_exhausted_req_hr() );
	execute( TC_assignment_codec_hr_exhausted_req_hr_fr() );
	execute( TC_assignment_codec_hr_exhausted_req_fr_hr() );
	execute( TC_assignment_codec_req_hr_fr() );
	execute( TC_assignment_codec_req_fr_hr() );

	if (mp_enable_osmux_test) {
		execute( TC_assignment_osmux() );
	}

	/* RLL Establish Indication on inactive DCHAN / SAPI */
	execute( TC_rll_est_ind_inact_lchan() );
	execute( TC_rll_est_ind_inval_sapi1() );
	execute( TC_rll_est_ind_inval_sapi3() );
	execute( TC_rll_est_ind_inval_sacch() );

	/* Paging related tests */
	execute( TC_paging_imsi_nochan() );
	execute( TC_paging_tmsi_nochan() );
	execute( TC_paging_tmsi_any() );
	execute( TC_paging_tmsi_sdcch() );
	execute( TC_paging_tmsi_tch_f() );
	execute( TC_paging_tmsi_tch_hf() );
	execute( TC_paging_imsi_nochan_cgi() );
	execute( TC_paging_imsi_nochan_lac_ci() );
	execute( TC_paging_imsi_nochan_ci() );
	execute( TC_paging_imsi_nochan_lai() );
	execute( TC_paging_imsi_nochan_lac() );
	execute( TC_paging_imsi_nochan_all() );
	execute( TC_paging_imsi_nochan_plmn_lac_rnc() );
	execute( TC_paging_imsi_nochan_rnc() );
	execute( TC_paging_imsi_nochan_lac_rnc() );
	execute( TC_paging_imsi_nochan_lacs() );
	execute( TC_paging_imsi_nochan_lacs_empty() );
	execute( TC_paging_imsi_nochan_cgi_unknown_cid() );
	execute( TC_paging_imsi_a_reset() );
	execute( TC_paging_imsi_load() );
	execute( TC_paging_counter() );
	execute( TC_paging_resp_unsol() );

	execute( TC_rsl_drop_counter() );
	execute( TC_rsl_unknown_unit_id() );

	execute( TC_oml_unknown_unit_id() );

	execute( TC_classmark() );
	execute( TC_unsol_ass_fail() );
	execute( TC_unsol_ass_compl() );
	execute( TC_unsol_ho_fail() );
	execute( TC_err_82_short_msg() );
	execute( TC_err_84_unknown_msg() );

	execute( TC_ho_int() );

	execute( TC_ho_out_of_this_bsc() );
	execute( TC_ho_out_fail_no_msc_response() );
	execute( TC_ho_out_fail_rr_ho_failure() );
	execute( TC_ho_out_fail_no_result_after_ho_cmd() );

	execute( TC_ho_into_this_bsc() );
	execute( TC_ho_in_fail_msc_clears() );
	execute( TC_ho_in_fail_msc_clears_after_ho_detect() );
	execute( TC_ho_in_fail_no_detect() );
	execute( TC_ho_in_fail_no_detect2() );

	execute( TC_ho_neighbor_config_1() );
	execute( TC_ho_neighbor_config_2() );
	execute( TC_ho_neighbor_config_3() );
	execute( TC_ho_neighbor_config_4() );
	execute( TC_ho_neighbor_config_5() );
	execute( TC_ho_neighbor_config_6() );
	execute( TC_ho_neighbor_config_7() );

	execute( TC_bssap_rlsd_does_not_cause_bssmap_reset() );
	execute( TC_bssmap_clear_does_not_cause_bssmap_reset() );
	execute( TC_ms_rel_ind_does_not_cause_bssmap_reset() );

	execute( TC_dyn_pdch_ipa_act_deact() );
	execute( TC_dyn_pdch_ipa_act_nack() );
	execute( TC_dyn_pdch_osmo_act_deact() );
	execute( TC_dyn_pdch_osmo_act_nack() );

	execute( TC_chopped_ipa_ping() );
	execute( TC_chopped_ipa_payload() );

	/* Power control related */
	execute( TC_assignment_verify_ms_power_params_ie() );
	/* at bottom as they might crash OsmoBSC before OS#3182 is fixed */
	execute( TC_early_conn_fail() );
	execute( TC_late_conn_fail() );

}

}
