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 RSL_Types all;
import from RSL_Emulation all;
import from MGCP_Emulation 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 L3_Templates all;
import from GSM_RR_Types all;

import from BSSMAP_Templates 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_shutdown_helper() runs on test_CT {
	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 templaten 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 */
	IPA_RSL[0].clear;
	alt {
	[] IPA_RSL[0].receive(tr_ASP_RSL_UD(sid, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) -> value rx_rsl_ud { }
	[] IPA_RSL[0].receive(tr_ASP_RSL_UD(sid, tr_RSL_REL_REQ(chan_nr, ?))) -> value rx_rsl_ud {
		f_ipa_tx(0, ts_RSL_REL_CONF(chan_nr, main_dcch));
		repeat;
		}
	}

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

/* 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));
	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 flush := true,
			   boolean handle_rll_rel := true) runs on test_CT {

	var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
	if (flush) {
		/* Clear the queue, it might still contain stuff like IMMEDIATE ASSIGN */
		IPA_RSL[bts_nr].clear;
	}
	alt {
	/* ignore DEACTIVATE SACCH (if any) */
	[] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(IPAC_PROTO_RSL_TRX0,
					tr_RSL_DEACT_SACCH(rsl_chan_nr))) {
		repeat;
	}
	/* acknowledge RLL release (if any)*/
	[handle_rll_rel] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(IPAC_PROTO_RSL_TRX0,
					tr_RSL_REL_REQ(rsl_chan_nr, ?))) {
		/* FIXME: Why are we getting this for LinkID SACCH? */
		f_ipa_tx(0, ts_RSL_REL_CONF(rsl_chan_nr, main_dcch));
		repeat;
	}
	[not handle_rll_rel] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(IPAC_PROTO_RSL_TRX0,
					tr_RSL_REL_REQ(rsl_chan_nr, ?))) {
		/* Do not reply, just continue */
		repeat;
	}
	/* Expect RF channel release from BSC on Abis */
	[] 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;
		}
	}
}

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

	/* 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 := valueof(t_def_TestHdlrPars);
	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 := valueof(t_def_TestHdlrPars);
	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 := valueof(t_def_TestHdlrPars);
	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 := valueof(t_def_TestHdlrPars);
	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 := valueof(t_def_TestHdlrPars);
	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 := valueof(t_def_TestHdlrPars);
	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 := valueof(t_def_TestHdlrPars);
	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);
	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 := valueof(t_def_TestHdlrPars);
	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 := valueof(t_def_TestHdlrPars);
	var template PDU_BSSAP exp_compl := tr_BSSMAP_AssignmentComplete(omit, omit);
	var PDU_BSSAP ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, omit));

	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 := valueof(t_def_TestHdlrPars);
	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 := valueof(t_def_TestHdlrPars);
	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 := valueof(t_def_TestHdlrPars);
	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 := valueof(t_def_TestHdlrPars);
	var MSC_ConnHdlr vc_conn;
	var RSL_IE_Body mr_conf := {
		other := {
			len := 2,
			payload := '2804'O
		}
	};

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

	pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
	pars.expect_mr_conf_ie := mr_conf;
	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 := valueof(t_def_TestHdlrPars);
	var MSC_ConnHdlr vc_conn;
	var RSL_IE_Body mr_conf := {
		other := {
			len := 2,
			payload := '2804'O
		}
	};

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

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

/* test if L3 RR CLASSMARK CHANGE is translated to BSSMAP CLASSMARK UPDATE */
private function f_tc_classmark(charstring id) runs on MSC_ConnHdlr {
	g_pars := valueof(t_def_TestHdlrPars);
	f_create_chan_and_exp();
	/* we should now have a COMPL_L3 at the MSC */
	BSSAP.receive(tr_BSSMAP_ComplL3);

	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 := valueof(t_def_TestHdlrPars);
	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 := valueof(t_def_TestHdlrPars);
	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;
}

/* 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 := valueof(t_def_TestHdlrPars);
	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()
}

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

/* 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);
	resp := f_vty_transceive_ret(BSCVTY, cmd);
	return regexp(resp, "*\((*)\)*", 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));

	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 */
	f_dyn_ipa_pdch_act(0, 0, chan_nr.tn);
	f_sleep(1.0);
	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);
	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));

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

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

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

}

}
