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

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

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

	T_guard.start;
	activate(as_Tguard());
}

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

	/* expect 5xTCH/F 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('23'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; }
	}
}

/***********************************************************************
 * 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
			   ) runs on test_CT {

	var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
	var octetstring l3_rr_chan_rel := '060D00'O;
	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;
	}
	[] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(IPAC_PROTO_RSL_TRX0, tr_RSL_DATA_REQ(rsl_chan_nr, ?, l3_rr_chan_rel))) {
		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 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();
}

/* 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 := '00000110'B;
	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 := '00000110'B;
	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;
}

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

	/* 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;
	var octetstring l3_rr_chan_rel := '060D00'O;
	interleave {
	[] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
			log("Got Deact SACCH");
		}
	[] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, l3_rr_chan_rel)) {
			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;
}


/* 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_rel_rll_rel_ind() );
	execute( TC_chan_rel_conn_fail() );
	execute( TC_chan_rel_hard_clear() );
	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() );

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

}

}
