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.
 *
 * 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 BSSAP_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 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() */

	var MGCP_Emulation_CT vc_MGCP;
	port TELNETasp_PT BSCVTY;

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

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

	/* 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";

	BSSAP_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
	};
}

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;
	}

	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)));
	T.start;
	alt {
	[] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap.sccp_addr_own, g_bssap.sccp_addr_peer, tr_BSSMAP_ResetAck)) {
		log("Received RESET-ACK in response to RESET, we're ready to go!");
		}
	[] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) -> 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));
		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)) -> value ud_ind {
		BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
			   ts_BSSMAP_ResetAck));
		repeat;
		}
}

altstep no_bssmap_reset() runs on test_CT {
	[] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) {
		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
	};

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

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");
}

/* 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) runs on test_CT {
	var integer i;

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

	T_guard.start;
	activate(as_Tguard());

	/* Call a function of our 'parent component' BSSAP_Adapter_CT to start the
	 * MSC-side BSSAP emulation */
	if (handler_mode) {
		f_bssap_init(g_bssap, mp_bssap_cfg, "VirtMSC", MSC_BssmapOps);
		f_bssap_start(g_bssap);
	} else {
		f_bssap_init(g_bssap, mp_bssap_cfg, "VirtMSC", omit);
		connect(self:BSSAP, g_bssap.vc_SCCP:SCCP_SP_PORT);
		f_bssap_start(g_bssap);
		f_legacy_bssap_reset();
	}

	f_ipa_ctrl_start(mp_bsc_ip, mp_bsc_ctrl_port);

	f_init_mgcp("VirtMSC");
	f_init_vty("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() return PDU_BSSAP {
	var PDU_BSSAP ass_cmd;
	if (mp_bssap_cfg.transport == BSSAP_TRANSPORT_AoIP) {
		var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
						valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
		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() return template PDU_BSSAP {
	var template PDU_BSSAP exp_compl;
	if (mp_bssap_cfg.transport == BSSAP_TRANSPORT_AoIP) {
		exp_compl := tr_BSSMAP_AssignmentComplete(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)));
	interleave {
	[] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap.sccp_addr_own, g_bssap.sccp_addr_peer, tr_BSSMAP_ResetAck)) { }
	[] 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);
}

/* 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", "3");

	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);
}

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)));
	alt {
	[] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap.sccp_addr_own, g_bssap.sccp_addr_peer, tr_BSSMAP_ResetAck)) { }
	[] 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, for instance because we
 * receive a Paging Response after T3113 expired (and subscriber information was
 * dropped). See OS#3680.
 */
testcase TC_paging_resp_unsol() runs on test_CT {

	f_init(1);

	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))));

	/* 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)));

	/* expect BSC to disable the channel */
	f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
	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 := "0/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 + BSSMAP_Emulation
 ***********************************************************************/

import from BSSMAP_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:BSSMAPEM, g_bssap.vc_BSSMAP: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);
	}
	connect(vc_conn:BSSAP, g_bssap.vc_BSSMAP:CLIENT);
	connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
}

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();
	var template PDU_BSSAP exp_compl := f_gen_exp_compl();

	/* 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];
	}
	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;
		}
	}
}

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;
}

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;
}

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);
}

/* 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);
}

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);

	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;
}

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_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));

	/* Expecting MGCP to DLCX the endpoint's two connections: towards BTS and towards MSC */
	var MgcpCommand mgcp;
	interleave {
	[] BSSAP.receive(tr_BSSMAP_ClearComplete);
	[] MGCP.receive(tr_DLCX()) -> value mgcp {
			log("Got first DLCX: ", mgcp);
		}
	[] MGCP.receive(tr_DLCX()) -> value mgcp {
			log("Got second DLCX: ", mgcp);
		}
	}
	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_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_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 HO, receives BSSMAP Handover Command, but MS reports
 * RR Handover Failure. */
private function f_tc_ho_out_fail_no_ho_detect(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_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);
		}
	}

	/* The MS never shows up on the remote BSS. Eventually the BSC times
	 * out and we run into 3GPP TS 48.008 3.1.5.3.3 "Abnormal Conditions":
	 * RR should be released and Clear Request should go to the MSC. */

	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));
		}
	[] BSSAP.receive(tr_BSSMAP_ClearRequest) {
			log("Got BSSMAP Clear Request");
		}
	[] MGCP.receive(tr_DLCX()) -> value mgcp {
			log("Got first DLCX: ", mgcp);
		}
	[] MGCP.receive(tr_DLCX()) -> value mgcp {
			log("Got second DLCX: ", mgcp);
		}
	}

	setverdict(pass);
	f_sleep(1.0);
}
testcase TC_ho_out_fail_no_ho_detect() 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_ho_detect));
	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(BSSAP_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(BSSAP_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. 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));

	/* Expecting MGCP to DLCX the endpoint's two connections: towards BTS and towards MSC */
	var MgcpCommand mgcp;
	interleave {
	[] BSSAP.receive(tr_BSSMAP_ClearComplete);
	[] MGCP.receive(tr_DLCX()) -> value mgcp {
			log("Got first DLCX: ", mgcp);
		}
	[] MGCP.receive(tr_DLCX()) -> value mgcp {
			log("Got second DLCX: ", mgcp);
		}
	}
	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(BSSAP_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));

	/* Expecting MGCP to DLCX the endpoint's two connections: towards BTS and towards MSC */
	var MgcpCommand mgcp;
	interleave {
	[] BSSAP.receive(tr_BSSMAP_ClearComplete);
	[] MGCP.receive(tr_DLCX()) -> value mgcp {
			log("Got first DLCX: ", mgcp);
		}
	[] MGCP.receive(tr_DLCX()) -> value mgcp {
			log("Got second DLCX: ", mgcp);
		}
	}
	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(BSSAP_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));

	/* Expecting MGCP to DLCX the endpoint's two connections: towards BTS and towards MSC */
	var MgcpCommand mgcp;
	interleave {
	[] BSSAP.receive(tr_BSSMAP_ClearComplete);
	[] MGCP.receive(tr_DLCX()) -> value mgcp {
			log("Got first DLCX: ", mgcp);
		}
	[] MGCP.receive(tr_DLCX()) -> value mgcp {
			log("Got second DLCX: ", mgcp);
		}
	}
	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(BSSAP_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 */

	/* Expecting MGCP to DLCX the endpoint's two connections: towards BTS and towards MSC */
	var PDU_BSSAP rx_clear_request;
	var MgcpCommand mgcp;
	interleave {
	[] 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));
	};
	[] BSSAP.receive(tr_BSSMAP_ClearComplete);

	[] MGCP.receive(tr_DLCX()) -> value mgcp {
			log("Got first DLCX: ", mgcp);
		}
	[] MGCP.receive(tr_DLCX()) -> value mgcp {
			log("Got second DLCX: ", mgcp);
		}
	}
	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;
}

/* 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);
	}
}


/* 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() );

	/* 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_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() );

	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() );

	/* 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_ho_detect() );

	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_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() );

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

}

}
