module BTS_Tests {

/* Integration Tests for OsmoBTS
 * (C) 2018-2019 by Harald Welte <laforge@gnumonks.org>
 * contributions by Vadim Yanitskiy and sysmocom - s.f.m.c. GmbH
 * All rights reserved.
 *
 * Released under the terms of GNU General Public License, Version 2 or
 * (at your option) any later version.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 *
 * This test suite tests OsmoBTS by attaching to the external interfaces
 * such as Abis RSL, PCU, VTY as well as by attaching to a MS L1 implementation
 * using the L1CTL protocol/interface.
 *
 * You can run the tests with
 *  a) osmo-bts-trx + trxcon + fake_trx (without any hardware)
 *  b) any osmo-bts-* + OsmocomBB layer1 + osmocon (with real BTS hardware)
 *  c) osmo-bts-virtual + virt_phy (without any hardware)
 *
 * Some of the tests will only run on a subset of those three configurations
 * due to limitations in the respective L1.
 */

import from Misc_Helpers all;
import from General_Types all;
import from GSM_Types all;
import from GSM_RR_Types all;
import from Osmocom_Types all;
import from GSM_Types all;
import from GSM_RestOctets all;
import from GSM_SystemInformation all;
import from L1CTL_PortType all;
import from L1CTL_Types all;
import from LAPDm_Types all;
import from LAPDm_RAW_PT all;
import from Native_Functions all;
import from Osmocom_CTRL_Adapter all;
import from Osmocom_CTRL_Functions all;

import from RSL_Types all;
import from RTP_Types all;
import from IPA_Types all;
import from IPA_Emulation all;
import from IPA_Testing all;
import from RSL_Emulation all;
import from RTP_Emulation all;

import from AMR_Types all;

import from OSMUX_Types all;
import from OSMUX_CodecPort all;
import from OSMUX_CodecPort_CtrlFunct all;
import from OSMUX_Emulation all;

import from IPL4asp_Types all;
import from TRXC_Types all;
import from TRXC_CodecPort all;
import from TRXC_CodecPort_CtrlFunct all;

import from PCUIF_Types all;
import from PCUIF_CodecPort all;
import from UD_Types all;

import from MobileL3_CommonIE_Types all;
import from MobileL3_RRM_Types all;
import from MobileL3_Types all;
import from L3_Templates all;
import from L3_Common all;
import from MobileL3_GMM_SM_Types all;

import from Osmocom_VTY_Functions all;
import from TELNETasp_PortType all;
import from BTS_Tests_LAPDm all;

friend module BTS_Tests_SMSCB;
friend module BTS_Tests_VAMOS;
friend module BTS_Tests_virtphy;
friend module BTS_Tests_LAPDm;
friend module BTS_Tests_perf;
friend module BTS_Tests_OML;

/* The tests assume a BTS with the following timeslot configuration:
 * TS0 : Combined CCCH + SDCCH/4
 * TS1 : TCH/F
 * TS2 : TCH/F
 * TS3 : TCH/F_PDCH (IPA Style)
 * TS4 : TCH/F_TCH/H_PDCH (Osmocom Style)
 * TS5 : TCH/H
 * TS6 : SDCCH/8
 * TS7 : PDCH
 */

modulepar {
	charstring mp_rsl_ip := "127.0.0.2";
	integer mp_rsl_port := 3003;
	charstring mp_bts_trxc_ip := "127.0.0.1";
	integer mp_bts_trxc_port := 5701;
	charstring mp_pcu_socket := PCU_SOCK_DEFAULT;
	charstring mp_ctrl_ip := "127.0.0.1";
	integer mp_ctrl_port := 4238;
	charstring mp_bsc_ctrl_ip := "127.0.0.1";
	integer mp_bsc_ctrl_port := 4249;
	charstring mp_rtpem_bind_ip := "127.0.0.1";
	integer mp_rtpem_bind_port := 6766;
	charstring mp_osmuxem_bind_ip := "127.0.0.1";
	integer mp_osmuxem_bind_port := 1984;
	integer mp_tolerance_rxqual := 1;
	integer mp_tolerance_rxlev := 3;
	integer mp_tolerance_timing_offset_256syms := 0;
	integer mp_rxlev_exp := 57;
	integer mp_ul_rxlev_exp := 10;
	integer mp_ms_power_level_exp := 7;
	integer mp_bts_tx_nom_pwr_exp := 50; /* Expected Tx Nominal Output Power of the BTS, in dBm */
	integer mp_bts_tx_pwr_att_exp := 20; /* Expected Tx Power attenuation wrt to Tx Nominal Output Power, in dB */
	integer mp_ms_actual_ta_exp := 0;
	integer mp_timing_offset_256syms_exp := 512;
	integer mp_uplink_power_target := -75;
	integer mp_uplink_power_hysteresis := 8; /* -83 .. -67 */
	/* Time to wait for RSL conn from BTS during startup of test */
	float mp_ipa_up_timeout := 15.0;
	float mp_ipa_up_delay := 0.0;
	/* false for now, as only virtphy supports it, not calypso-l1 nor trxcon */
	boolean mp_l1_supports_gprs := false;
	/* how many transceivers do we expect to connect */
	integer mp_transceiver_num := 1;
	/* frequency hopping status */
	boolean mp_freq_hop_enabled := false;
	/* frequency hopping parameters */
	FreqHopConfig mp_fh_config;
	/* configuration for each individual transceiver */
	TrxPars mp_trx_pars; /* see BTS_Tests.default */
	/* default Training Sequence Code */
	GsmTsc mp_tsc_def := 7;
	/* Default interference boundaries in osmo-bsc (in dBm):
	 *   0(-85) X1(-91) X2(-97) X3(-103) X4(-109) X5(-115)
	 * Default interference level reported by fake_trx.py:
	 *    0: -109 >= -85 dBm (no)
	 *   X1: -109 >= -91 dBm (no)
	 *   X2: -109 >= -97 dBm (no)
	 *   X3: -109 >= -103 dBm (no)
	 *   X4: -109 >= -109 dBm (yes)
	 *   X5: -109 >= -115 dBm (no)
	 * So all channels should be in band 4. */
	uint3_t mp_interf_band := 4;
	/* T3105 timer (see 3GPP TS 44.018, section 11.1.2) */
	integer mp_ho_t3105_ms := 100;
	/* Ny1 counter (see 3GPP TS 44.018, section 11.1.3) */
	integer mp_ho_ny1 := 10;
}

type record of RslChannelNr ChannelNrs;

type component test_CT extends CTRL_Adapter_CT {
	/* IPA Emulation component underneath RSL */
	var IPA_Emulation_CT vc_IPA;
	/* RSL Emulation component (for ConnHdlr tests) */
	var RSL_Emulation_CT vc_RSL;
	/* Direct RSL_CCHAN_PT */
	port RSL_CCHAN_PT RSL_CCHAN;

	/* L1CTL port (for classic tests) */
	port L1CTL_PT L1CTL;

	/* Optional TRXC connection to FakeTRX (BTS side) */
	port TRXC_CODEC_PT BTS_TRXC;
	var integer g_bts_trxc_conn_id;

	/* VTY connections to both BTS and BSC */
	port TELNETasp_PT BTSVTY;
	port TELNETasp_PT BSCVTY;

	/* PCU Interface of BTS */
	port PCUIF_CODEC_PT PCU;
	var integer g_pcu_conn_id;
	/* Last PCU INFO IND we received */
	var PCUIF_Message g_pcu_last_info;

	/* SI configuration */
	var SystemInformationConfig si_cfg := {
		bcch_extended := false,
		si1_present := false,
		si2bis_present := false,
		si2ter_present := false,
		si2quater_present := false,
		si7_present := false,
		si8_present := false,
		si9_present := false,
		si13_present := false,
		si13alt_present := false,
		si15_present := false,
		si16_present := false,
		si17_present := false,
		si2n_present := false,
		si21_present := false,
		si22_present := false
	};

	/* all logical channels available on the BTS */
	var ChannelNrs g_AllChannels;
	var ChannelNrs g_AllChanTypes;
}

/* an individual call / channel */
type component ConnHdlr extends RSL_DchanHdlr, lapdm_test_CT {
	port L1CTL_PT L1CTL;

	/* Optional TRXC connection to FakeTRX (BTS side) */
	port TRXC_CODEC_PT BTS_TRXC;
	var integer g_bts_trxc_conn_id;

	/* port to be initialized optionally to access BSC VTY */
	port TELNETasp_PT BSCVTY;

	timer g_Tguard;
	timer g_Tmeas_exp := 2.0; /* >= 103 SACCH multiframe ~ 500ms */

	var ConnHdlrPars g_pars;
	var uint8_t g_next_meas_res_nr := 0;
	var boolean g_first_meas_res := true;

	/* PCU Interface of BTS */
	port PCUIF_CODEC_PT PCU;

	var RTP_Emulation_CT vc_RTPEM;
	port RTPEM_CTRL_PT RTPEM_CTRL;
	port RTPEM_DATA_PT RTPEM_DATA;
	var OSMUX_Emulation_CT vc_OsmuxEM;
	port OsmuxEM_CTRL_PT OsmuxEM_CTRL;
	port OsmuxEM_DATA_PT OsmuxEM_DATA;
}

private function f_init_rsl(charstring id) runs on test_CT {
	var bitstring trx_mask := '00000000'B;
	var bitstring rfind_mask := '00000000'B;
	var integer trx_count := 0;
	var integer rfind_count := 0;
	var RSLEm_Event ev;
	var ASP_RSL_Unitdata rx_ud;
	timer T;

	vc_IPA := IPA_Emulation_CT.create(id & "-RSL-IPA");
	vc_RSL := RSL_Emulation_CT.create(id & "-RSL");

	map(vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
	connect(vc_IPA:IPA_RSL_PORT, vc_RSL:IPA_PT);
	connect(self:RSL_CCHAN, vc_RSL:CCHAN_PT);

	vc_IPA.start(IPA_Emulation.main_server(mp_rsl_ip, mp_rsl_port));
	vc_RSL.start(RSL_Emulation.main(false));

	/* We expect (N = mp_transceiver_num) IPA/RSL transceiver connections here.
	 * See https://gerrit.osmocom.org/q/Ib5ad31388ae25399ad09739aac3fdcb0b3a1f78b. */
	T.start(mp_ipa_up_timeout);
	alt {
	/* These events are sent by the RSL_Emulation_CT */
	[] RSL_CCHAN.receive(tr_RSLEm_EV(RSLEM_EV_TRX_UP, ?)) -> value ev {
		/* Make sure that all transceivers use unique stream ID */
		if (trx_mask[enum2int(ev.sid)] == '1'B) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
				log2str("Duplicate RSL stream ID (", ev.sid, ")"));
		}

		trx_mask[enum2int(ev.sid)] := '1'B;
		trx_count := trx_count + 1;

		log(trx_count, "/", mp_transceiver_num, " transceiver(s) connected");
		repeat;
		}
	/* This message (RF RESource INDication) is sent by the IUT itself */
	[] RSL_CCHAN.receive(tr_ASP_RSL_UD(tr_RSL_RF_RES_IND, ?)) -> value rx_ud {
		if (trx_mask[enum2int(rx_ud.streamId)] == '0'B) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
				log2str("Got RF Resource Indication before RSLEM_EV_TRX_UP (", rx_ud.streamId, ")"));
		}
		if (rfind_mask[enum2int(rx_ud.streamId)] == '1'B) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
				log2str("Duplicate RF Resource Indication ID (", rx_ud.streamId, ")"));
		}

		rfind_mask[enum2int(rx_ud.streamId)] := '1'B;
		rfind_count := rfind_count + 1;
		log(rfind_count, "/", mp_transceiver_num, " RF Resource Indication(s) received");
		if (rfind_count < mp_transceiver_num) { repeat; }
	}
	/* osmo-bts may send us CCCH LOAD INDication or whatever else */
	[] RSL_CCHAN.receive(ASP_RSL_Unitdata:?) { repeat; }
	[] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
			"Timeout waiting for RSL bring up");
		}
	}
}

friend type record length(1 .. 256) of TrxParsItem TrxPars;
friend type record TrxParsItem {
	GsmArfcn arfcn,
	TrxTsPars ts
};

friend type record length(8) of TrxTsParsItem TrxTsPars;
friend type record TrxTsParsItem {
	PchanConfig config
};

friend type record FreqHopPars {
	/* Whether frequency hopping is in use */
	boolean enabled,
	/* Mobile Allocation Index Offset / Hopping Sequence Number */
	MaioHsn maio_hsn,
	/* MA bitmap to be indicated in RR Immediate Assignment */
	MobileAllocationLV ma_map,
	/* The actual Mobile Allocation (ARFCN list) to be used */
	L1ctlMA ma
};

type record ConnHdlrPars {
	uint8_t trx_nr,
	RslChannelNr chan_nr,
	RSL_IE_ChannelMode chan_mode,
	RSL_IE_MultirateCfg mr_conf optional,
	float t_guard,
	ConnL1Pars l1_pars,
	TestSpecUnion spec optional,
	RSL_IE_EncryptionInfo encr optional,
	BtsBand bts0_band optional,

	/* Training Sequence Code */
	GsmTsc tsc,
	/* Frequency hopping parameters */
	FreqHopPars fhp,
	OsmuxCID loc_osmux_cid,
	OsmuxCID rem_osmux_cid optional
};

/* Test-specific parameters */
friend type union TestSpecUnion {
	RllTestCase rll,
	TopTestCase top
}

private template (value) RachControlParameters ts_RachCtrl_default := {
	max_retrans := RACH_MAX_RETRANS_7,
	tx_integer := '1001'B, /* 12 slots */
	cell_barr_access := false,
	re_not_allowed := true,
	acc := '0000010000000000'B
};

private template (value) CellSelectionParameters ts_CellSelPar_default := {
	cell_resel_hyst_2dB := 2,
	ms_txpwr_max_cch := mp_ms_power_level_exp,
	acs := '0'B,
	neci := true,
	rxlev_access_min := 0
}

private template (value) LocationAreaIdentification ts_LAI_default := {
	mcc_mnc := '262F42'H,
	lac := 42
}

private template (value) GPRSIndicator ts_GPRSIndicator_def := {
	ra_colour := 0,
	si13_pos := '0'B
}

private template (value) SI3RestOctets ts_SI3RestOctets_def
modifies ts_SI3RestOctets := {
	gprs_ind := {
		presence := CSN1_H,
		ind := ts_GPRSIndicator_def
	}
}

private template (value) SI4RestOctets ts_SI4RestOctets_def
modifies ts_SI4RestOctets := {
	gprs_ind := {
		presence := CSN1_H,
		ind := ts_GPRSIndicator_def
	}
}

/* Default SYSTEM INFORMATION 3 */
private template (value) SystemInformation ts_SI3_default := {
	header := ts_RrHeader(SYSTEM_INFORMATION_TYPE_3, 18),
	payload := {
		si3 := {
			cell_id := 23,
			lai := ts_LAI_default,
			ctrl_chan_desc := {
				msc_r99 := true,
				att := true,
				bs_ag_blks_res := 1,
				ccch_conf := CCHAN_DESC_1CCCH_COMBINED,
				si22ind := false,
				cbq3 := CBQ3_IU_MODE_NOT_SUPPORTED,
				spare := '00'B,
				bs_pa_mfrms := 0, /* 2 multiframes */
				t3212 := 1 /* 6 minutes */
			},
			cell_options := {
				dn_ind := false,
				pwrc := false,
				dtx := MS_MAY_USE_UL_DTX,
				radio_link_tout_div4 := (32/4)-1
			},
			cell_sel_par := ts_CellSelPar_default,
			rach_control := ts_RachCtrl_default,
			rest_octets := valueof(ts_SI3RestOctets_def)
		}
	}
}

private template (value) SystemInformation ts_SI2_default := {
	header := ts_RrHeader(SYSTEM_INFORMATION_TYPE_2, 22),
	payload := {
		si2 := {
			bcch_freq_list := '00000000000000000000000000000000'O,
			ncc_permitted := '11111111'B,
			rach_control := ts_RachCtrl_default
		}
	}
}

private template (value) SystemInformation ts_SI4_default := {
	header := ts_RrHeader(SYSTEM_INFORMATION_TYPE_4, 12), /* no CBCH / restoct */
	payload := {
		si4 := {
			lai := ts_LAI_default,
			cell_sel_par := ts_CellSelPar_default,
			rach_control := ts_RachCtrl_default,
			cbch_chan_desc := omit,
			cbch_mobile_alloc := omit,
			rest_octets := valueof(ts_SI4RestOctets_def)
		}
	}
}

private function f_rsl_bcch_fill_raw(RSL_IE_SysinfoType rsl_si_type, octetstring si_enc)
runs on test_CT {
	log("Setting ", rsl_si_type, ": ", si_enc);
	RSL_CCHAN.send(ts_ASP_RSL_UD(ts_RSL_BCCH_INFO(rsl_si_type, si_enc)));
}

private function f_rsl_bcch_fill(RSL_IE_SysinfoType rsl_si_type, template (value) SystemInformation si_dec)
runs on test_CT {
	var octetstring si_enc := enc_SystemInformation(valueof(si_dec));
	log("Setting ", rsl_si_type, ": ", si_dec);
	f_rsl_bcch_fill_raw(rsl_si_type, si_enc);
}

friend function f_init_vty(charstring id) runs on test_CT {
	map(self:BTSVTY, system:BTSVTY);
	f_vty_set_prompts(BTSVTY);
	f_vty_transceive(BTSVTY, "enable");
}

friend function f_init_vty_bsc() runs on test_CT {
	map(self:BSCVTY, system:BSCVTY);
	f_vty_set_prompts(BSCVTY, "OsmoBSC");
	f_vty_transceive(BSCVTY, "enable");
}

friend function f_connhdlr_init_vty_bsc() runs on ConnHdlr {
	map(self:BSCVTY, system:BSCVTY);
	f_vty_set_prompts(BSCVTY, "OsmoBSC");
	f_vty_transceive(BSCVTY, "enable");
}

/* PCU socket may at any time receive a new INFO.ind */
friend altstep as_pcu_info_ind(PCUIF_CODEC_PT pt, integer pcu_conn_id,
				out PCUIF_Message pcu_last_info) {
	var PCUIF_send_data sd;
	[] pt.receive(t_SD_PCUIF(pcu_conn_id, tr_PCUIF_INFO_IND(0, ?))) -> value sd {
		pcu_last_info := sd.data;
		}
	[] pt.receive(t_SD_PCUIF(pcu_conn_id, tr_PCUIF_INFO_IND(?, ?, ?))) -> value sd {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Invalid PCU Version/BTS Number received");
		}
}

private function f_init_pcu(PCUIF_CODEC_PT pt, charstring id,
			    out integer pcu_conn_id, out PCUIF_Message pcu_last_info) {
	timer T := 2.0;
	var PCUIF_send_data sd;
	if (mp_pcu_socket == "") {
		pcu_conn_id := -1;
		return;
	}
	pcu_conn_id := f_pcuif_connect(pt, mp_pcu_socket);

	T.start;
	alt {
	[] as_pcu_info_ind(pt, pcu_conn_id, pcu_last_info);
	[] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for PCU INFO_IND");
		}
	}
}

private function f_init_trxc(TRXC_CODEC_PT pt, charstring id,
			     out integer trxc_conn_id) {
	var Result res;

	res := TRXC_CodecPort_CtrlFunct.f_IPL4_connect(pt, mp_bts_trxc_ip, mp_bts_trxc_port,
						       "", -1, -1, { udp := {} }, {});
	if (not ispresent(res.connId)) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
					"Could not connect to the control (TRXC) interface " &
					"of FakeTRX, check your configuration");
	}
	trxc_conn_id := res.connId;
}

/* global init function (without PCUIF connection) */
friend function f_init(uint8_t trx_nr := 0)
runs on test_CT
{
	var TrxParsItem trx_pars := mp_trx_pars[trx_nr];
	var charstring id := testcasename();

	/* FIXME: FACCH/H is unreliable with calypso firmware, see OS#3653.
	 * TODO: also generate this list dynamically from module parameters. */
	if (mp_bts_trxc_port != -1) {
		g_AllChanTypes := {
			/* TS 1..4: TCH/F */
			valueof(ts_RslChanNr_Bm(1)),
			/* TS 5: TCH/H */
			valueof(ts_RslChanNr_Lm(5,1)),
			/* TS 0: SDCCH/4 */
			valueof(ts_RslChanNr_SDCCH4(0,2)),
			/* TS 6: SDCCH/8 */
			valueof(ts_RslChanNr_SDCCH8(6,4))
		};
	} else {
		g_AllChanTypes := {
			/* TS 1..4: TCH/F */
			valueof(ts_RslChanNr_Bm(1)),
			/* TS 0: SDCCH/4 */
			valueof(ts_RslChanNr_SDCCH4(0,2)),
			/* TS 6: SDCCH/8 */
			valueof(ts_RslChanNr_SDCCH8(6,4))
		};
	}

	g_AllChannels := { };

	/* Generate list of all logical channels from module parameters */
	for (var integer tn := 0; tn < lengthof(trx_pars.ts); tn := tn + 1) {
		select (trx_pars.ts[tn].config) {
		case (GSM_PCHAN_CCCH_SDCCH4) {
			g_AllChannels := g_AllChannels &
				{ valueof(ts_RslChanNr_SDCCH4(tn, 0)),
				  valueof(ts_RslChanNr_SDCCH4(tn, 1)),
				  valueof(ts_RslChanNr_SDCCH4(tn, 2)),
				  valueof(ts_RslChanNr_SDCCH4(tn, 3)) };
			}
		case (GSM_PCHAN_SDCCH8) {
			g_AllChannels := g_AllChannels &
				{ valueof(ts_RslChanNr_SDCCH8(tn, 0)),
				  valueof(ts_RslChanNr_SDCCH8(tn, 1)),
				  valueof(ts_RslChanNr_SDCCH8(tn, 2)),
				  valueof(ts_RslChanNr_SDCCH8(tn, 3)),
				  valueof(ts_RslChanNr_SDCCH8(tn, 4)),
				  valueof(ts_RslChanNr_SDCCH8(tn, 5)),
				  valueof(ts_RslChanNr_SDCCH8(tn, 6)),
				  valueof(ts_RslChanNr_SDCCH8(tn, 7)) };
			}
		case (GSM_PCHAN_TCHH_TCHF_PDCH) {
			g_AllChannels := g_AllChannels &
				{ valueof(ts_RslChanNr_Lm(tn, 0)),
				  valueof(ts_RslChanNr_Lm(tn, 1)),
				  valueof(ts_RslChanNr_Bm(tn)) };
			}
		case (GSM_PCHAN_TCHH) {
			g_AllChannels := g_AllChannels &
				{ valueof(ts_RslChanNr_Lm(tn, 0)),
				  valueof(ts_RslChanNr_Lm(tn, 1)) };
			}
		case (GSM_PCHAN_TCHF, GSM_PCHAN_TCHF_PDCH) {
			g_AllChannels := g_AllChannels &
				{ valueof(ts_RslChanNr_Bm(tn)) };
			}
		}
	}

	f_init_rsl(id);
	f_sleep(0.5);	/* workaround for OS#3000 */
	f_init_vty(id);
	f_ipa_ctrl_start_client(mp_ctrl_ip, mp_ctrl_port);

	/* Send SI3 to the BTS, it is needed for various computations */
	f_rsl_bcch_fill(RSL_SYSTEM_INFO_3, ts_SI3_default);
	/* SI2 + SI4 are required for SI testing as they are mandatory defaults */
	f_rsl_bcch_fill(RSL_SYSTEM_INFO_2, ts_SI2_default);
	f_rsl_bcch_fill(RSL_SYSTEM_INFO_4, ts_SI4_default);

	if (mp_bts_trxc_port != -1) {
		var TrxcMessage ret;

		/* Init TRXC interface to FakeTRX */
		map(self:BTS_TRXC, system:BTS_TRXC);
		f_init_trxc(BTS_TRXC, id, g_bts_trxc_conn_id);

		/* Start with a default moderate timing offset equalling TA=2, and RSSI=-60 */
		ret := f_TRXC_transceive(BTS_TRXC, g_bts_trxc_conn_id, ts_TRXC_FAKE_TIMING(2*256));
		ret := f_TRXC_transceive(BTS_TRXC, g_bts_trxc_conn_id, ts_TRXC_FAKE_RSSI(-60));
		/* OsmoBTS may have different AB / NB threshold (see MIN_QUAL_NORM, MIN_QUAL_RACH) */
		ret := f_TRXC_transceive(BTS_TRXC, g_bts_trxc_conn_id, ts_TRXC_FAKE_CI(60));
	}

	/* Wait some extra time to make sure the BTS emits a stable carrier.
	 * (this is only relevant when running the tests with a physical BTS.) */
	f_sleep(mp_ipa_up_delay);
}

/* Attach L1CTL to master test_CT (classic tests, non-handler mode) */
friend function f_init_l1ctl() runs on test_CT {
	map(self:L1CTL, system:L1CTL);
	f_connect_reset(L1CTL);
}

friend type function void_fn(charstring id) runs on ConnHdlr;

private type record length(8) of FreqHopGroups FreqHopConfig;

private type record of FreqHopGroup FreqHopGroups;
private type record FreqHopGroup {
	uint6_t			hsn,
	FreqHopGroupItems	trx_maio
};

private type record of FreqHopGroupItem FreqHopGroupItems;
private type record FreqHopGroupItem {
	uint8_t			trx_nr,
	uint6_t			maio
};

friend function f_resolve_fh_params(inout FreqHopPars fhp, uint8_t tn,
				    uint8_t trx_nr := 0)
{
	var FreqHopGroups groups := mp_fh_config[tn];
	var integer i, j;

	fhp.enabled := false;

	for (i := 0; i < lengthof(groups); i := i + 1) {
		var FreqHopGroup g := groups[i];
		for (j := 0; j < lengthof(g.trx_maio); j := j + 1) {
			var FreqHopGroupItem gi := g.trx_maio[j];
			if (gi.trx_nr == trx_nr) {
				fhp.maio_hsn.maio := gi.maio;
				fhp.maio_hsn.hsn := g.hsn;
				fhp.enabled := true;
				break;
			}
		}

		if (fhp.enabled) {
			/* Prepare the Mobile Allocation bitmask (length & padding) */
			fhp.ma_map.len := (mp_transceiver_num + 8 - 1) / 8; /* in bytes */
			fhp.ma_map.ma := f_pad_bit('0'B, fhp.ma_map.len * 8, '0'B);
			fhp.ma := { }; /* to be composed below */

			/* Compose the actual Mobile Allocation and the bitmask */
			for (j := 0; j < lengthof(g.trx_maio); j := j + 1) {
				var FreqHopGroupItem gi := g.trx_maio[j];
				var GsmArfcn arfcn := mp_trx_pars[gi.trx_nr].arfcn;
				fhp.ma := fhp.ma & { valueof(ts_GsmBandArfcn(arfcn)) };
				fhp.ma_map.ma[gi.trx_nr] := '1'B;
			}

			log("Freq. hopping parameters: ", fhp);
			break; /* We're done */
		}
	}
}

/* create a new test component */
friend function f_start_handler(void_fn fn, ConnHdlrPars pars,
				boolean pcu_comp := false,
				boolean trxc_comp := false,
				boolean l1ctl := true)
runs on test_CT return ConnHdlr {
	var charstring id := testcasename();
	var ConnHdlr vc_conn;

	vc_conn := ConnHdlr.create(id);
	/* connect to RSL Emulation main component */
	connect(vc_conn:RSL, vc_RSL:CLIENT_PT);
	connect(vc_conn:RSL_PROC, vc_RSL:RSL_PROC);

	/* The ConnHdlr component may want to talk to some ports directly,
	 * so we disconnect it from the test_CT and connect it to the component.
	 * This obviously only works for one component, i.e. no concurrency. */
	if (pcu_comp) {
		unmap(self:PCU, system:PCU);
		map(vc_conn:PCU, system:PCU);
	}
	if (trxc_comp) {
		unmap(self:BTS_TRXC, system:BTS_TRXC);
		map(vc_conn:BTS_TRXC, system:BTS_TRXC);
	}
	if (l1ctl) {
		map(vc_conn:L1CTL, system:L1CTL);
	}

	/* Obtain frequency hopping parameters for a given timeslot */
	if (mp_freq_hop_enabled and mp_transceiver_num > 1) {
		f_resolve_fh_params(pars.fhp, pars.chan_nr.tn);
	}

	vc_conn.start(f_handler_init(fn, id, pars));
	return vc_conn;
}

private altstep as_Tguard() runs on ConnHdlr {
	[] g_Tguard.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Tguard timeout");
	}
}

friend function f_l1_tune(L1CTL_PT L1CTL, L1ctlCcchMode ccch_mode := CCCH_MODE_COMBINED) {
	var GsmBandArfcn arfcn := valueof(ts_GsmBandArfcn(mp_trx_pars[0].arfcn));
	f_L1CTL_FBSB(L1CTL, arfcn, ccch_mode, mp_rxlev_exp);
}

private function f_trxc_fake_rssi(TRXC_RSSI rssi) runs on ConnHdlr {
	var TrxcMessage ret;
	ret := f_TRXC_transceive(BTS_TRXC, g_bts_trxc_conn_id, ts_TRXC_FAKE_RSSI(rssi));
}

private function f_trxc_fake_toffs256(int16_t toffs256) runs on ConnHdlr {
	var TrxcMessage ret;
	ret := f_TRXC_transceive(BTS_TRXC, g_bts_trxc_conn_id, ts_TRXC_FAKE_TIMING(toffs256));
}

/* first function started in ConnHdlr component */
private function f_handler_init(void_fn fn, charstring id, ConnHdlrPars pars)
runs on ConnHdlr {
	g_pars := pars;
	g_chan_nr := pars.chan_nr;

	if (L1CTL.checkstate("Mapped")) {
		f_connect_reset(L1CTL);
	}

	if (mp_bts_trxc_port != -1 and BTS_TRXC.checkstate("Mapped")) {
		f_init_trxc(BTS_TRXC, id, g_bts_trxc_conn_id);
	}

	g_Tguard.start(pars.t_guard);
	activate(as_Tguard());

	f_rslem_register(pars.trx_nr, pars.chan_nr);

	/* call the user-supplied test case function */
	fn.apply(id);
}

private function f_rsl_transceive_ret(template RSL_Message tx, template RSL_Message exp_rx,
				      charstring id, boolean ignore_other := false)
runs on ConnHdlr return RSL_Message {
	var RSL_Message rx;
	timer T := 3.0;
	RSL.send(tx);
	T.start;
	alt {
	[] RSL.receive(exp_rx) -> value rx {
		T.stop;
		setverdict(pass);
		}
	[] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout expecting " & id);
		}
	[not ignore_other] as_l1_sacch();
	[not ignore_other] as_meas_res();
	[not ignore_other] as_l1_dcch_loop();
	[not ignore_other] as_l1_tch_loop();
	[not ignore_other] RSL.receive(RSL_Message:?) -> value rx {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Rx unexpected RSL port message: ", rx));
		}
	[not ignore_other] RSL.receive {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Rx unexpected RSL port message");
		}
	[ignore_other] RSL.receive { repeat; }
	}
	return rx;
}

friend function f_rsl_transceive(template RSL_Message tx, template RSL_Message exp_rx,
				 charstring id, boolean ignore_other := false)
runs on ConnHdlr {
	var RSL_Message rx := f_rsl_transceive_ret(tx, exp_rx, id, ignore_other);
}

/* Send the given measurement results to the IUT over the Um interface */
friend function f_send_meas_rep(template (value) MeasurementResults meas_res)
runs on ConnHdlr {
	var template (value) SacchL1Header l1h;

	l1h := ts_SacchL1Header(g_pars.l1_pars.ms_power_level, g_pars.l1_pars.ms_actual_ta);
	f_send_meas_rep_l1h(meas_res, l1h);
}

/* Send the given measurement results and L1H to the IUT over the Um interface */
friend function f_send_meas_rep_l1h(template (value) MeasurementResults meas_res,
				    template (value) SacchL1Header l1h)
runs on ConnHdlr {
	var octetstring l2;

	/* RR Measurement Report to be sent */
	var GsmRrL3Message meas_rep := {
		header := valueof(t_RrL3Header(MEASUREMENT_REPORT)),
		payload := { meas_rep := { meas_res := valueof(meas_res) } }
	};

	/* TITAN has weird (and often unusable) padding model, so we pad here manaully */
	l2 := f_pad_oct(enc_LapdmFrameAB(valueof(ts_LAPDm_AB(0, meas_rep))), 21, '00'O);

	log(%definitionId, "(): Tx SACCH L1 header: ", l1h);

	/* Send RR Measurement Report over the Um interface */
	L1CTL.send(ts_L1CTL_DATA_REQ_SACCH(g_chan_nr, ts_RslLinkID_SACCH(0), l1h, l2));
}

/* Send the given measurement results to the IUT over the Um interface,
 * wait for the IUT to receive then and forward over the A-bis/RSL interface. */
friend function f_transceive_meas_rep(template (value) MeasurementResults meas_res)
runs on ConnHdlr {
	var octetstring l3;
	timer T;

	/* RR Measurement Report to be sent */
	var GsmRrL3Message meas_rep := {
		header := valueof(t_RrL3Header(MEASUREMENT_REPORT)),
		payload := { meas_rep := { meas_res := valueof(meas_res) } }
	};

	/* TITAN has weird (and often unusable) padding model, so we pad here manaully */
	l3 := f_pad_oct(enc_GsmRrL3Message(meas_rep), 18, '00'O);

	f_send_meas_rep(meas_res);

	/* Expect MEASurement RESult on the A-bis/RSL interface */
	T.start(2.0);
	alt {
	[] RSL.receive(tr_RSL_MEAS_RES_OSMO(g_chan_nr, l3_info := l3)) {
		setverdict(pass);
		}
	[] RSL.receive { repeat; }
	[] T.timeout {
		setverdict(fail, "Timeout waiting for RSL MEASurement RESult");
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
		}
	}
}

friend function f_rsl_chan_act(RSL_IE_ChannelMode mode,
			       boolean encr_enable := false,
			       RSL_IE_List more_ies := {},
			       RSL_IE_ActivationType act_type := t_RSL_IE_ActType_IA)
runs on ConnHdlr {
	var RSL_Message ch_act := valueof(ts_RSL_CHAN_ACT(g_chan_nr, mode, act_type));
	if (encr_enable) {
		/* append encryption related IEs, if requested */
		var RSL_IE_EncryptionInfo encr_info;
		encr_info := valueof(ts_RSL_IE_EncrInfo(g_pars.encr.alg_id, g_pars.encr.key));
		ch_act.ies := ch_act.ies & { valueof(t_RSL_IE(RSL_IE_ENCR_INFO, RSL_IE_Body:{encr_info :=
encr_info})) };
	}
	if (ischosen(mode.u.speech) and mode.u.speech == RSL_CMOD_SP_GSM3) {
		ch_act.ies := ch_act.ies & { valueof(t_RSL_IE(RSL_IE_MR_CONFIG,
							      RSL_IE_Body:{multirate_cfg := g_pars.mr_conf})) };
	}
	ch_act.ies := ch_act.ies & more_ies;
	f_rsl_transceive(ch_act, tr_RSL_CHAN_ACT_ACK(g_chan_nr), "RSL CHAN ACT");
}

friend function f_rsl_chan_deact() runs on ConnHdlr {
	f_rsl_transceive(ts_RSL_RF_CHAN_REL(g_chan_nr), tr_RSL_RF_CHAN_REL_ACK(g_chan_nr),
			"RF CHAN REL", true);
}

friend template ConnHdlrPars t_Pars(template RslChannelNr chan_nr,
				    template RSL_IE_ChannelMode chan_mode,
				    template (omit) TestSpecUnion spec := omit,
				    uint8_t trx_nr := 0, float t_guard := 20.0) := {
	trx_nr := trx_nr,
	chan_nr := valueof(chan_nr),
	chan_mode := valueof(chan_mode),
	mr_conf := omit,
	t_guard := t_guard,
	l1_pars := {
		dtx_enabled := false,
		toa256_enabled := false,
		meas_valid := true,
		meas_ul := {
			full := {
				rxlev := mp_ul_rxlev_exp,
				rxqual := 0
			},
			sub := {
				rxlev := mp_ul_rxlev_exp,
				rxqual := 0
			}
		},
		timing_offset_256syms := mp_timing_offset_256syms_exp,
		bs_power_level := 0,
		ms_power_level := mp_ms_power_level_exp,
		ms_actual_ta := mp_ms_actual_ta_exp,
		facch_enabled := false
	},
	spec := spec,
	encr := omit,
	bts0_band := omit,
	tsc := mp_tsc_def,
	fhp := {
		enabled := false,
		maio_hsn := ts_HsnMaio(0, 0),
		ma_map := c_MA_null,
		ma := { }
	},
	loc_osmux_cid := trx_nr,
	rem_osmux_cid := omit
}

/* This altstep triggers on receipt of a L1CTL DATA.ind matching the given
 * RSL chan_nr/link_id and data templates.  Used as a base for other altsteps. */
private altstep as_l1ctl_dl_msg(out L1ctlMessage msg,
				template (present) octetstring tr_data := ?,
				template (present) RslChannelNr chan_nr := ?,
				template (present) RslLinkId link_id := ?)
runs on ConnHdlr {
	[] L1CTL.receive(tr_L1CTL_DATA_IND(chan_nr, link_id, tr_data)) -> value msg;
}

/* This altstep is built on top of as_l1ctl_dl_msg(), and triggers on receipt
 * of dummy LAPDm func=UI frames with empty payload.  Repeats by default. */
private altstep as_dl_lapdm_dummy(template (present) RslChannelNr chan_nr := ?,
				  template (present) RslLinkId link_id := ?,
				  template (present) LapdmSapi sapi := ?,
				  boolean do_repeat := true)
runs on ConnHdlr {
	template (present) LapdmFrame tr_frame := tr_LAPDm_UI(sapi, true, ''O);
	var L1ctlMessage dl_msg;

	[] as_l1ctl_dl_msg(dl_msg, decmatch tr_frame, chan_nr, link_id) {
		if (do_repeat) {
			repeat;
		}
	}
}

/* This altstep triggers on receipt of a Downlink DCCH containing a L2 payload
 * that matches the given LAPDm frame.  The L2 is treated as LapdmFrameAB. */
private altstep as_dl_dcch_lapdm_ab(out LapdmFrameAB frame,
				    template (present) LapdmFrameAB tr_frame := ?,
				    template (present) RslLinkId link_id := ?)
runs on ConnHdlr {
	var L1ctlMessage dl_msg;

	[] as_l1ctl_dl_msg(dl_msg, decmatch tr_frame, g_chan_nr, link_id) {
		frame := dec_LapdmFrameAB(dl_msg.payload.data_ind.payload);
	}
}

/* This altstep triggers on receipt of a Downlink SACCH containing a L2 payload
 * that matches the given LAPDm frame, as well as the given SACCH L1 header. */
private altstep as_dl_sacch_lapdm_ab(out SacchL1Header l1h, out LapdmFrameAB frame,
				     template (present) LapdmFrameAB tr_frame := ?,
				     template (present) SacchL1Header tr_l1h := ?,
			             template (present) GsmSapi sapi := ?)
runs on ConnHdlr {
	var L1ctlMessage dl_msg;
	template (present) RslLinkId link_id := tr_RslLinkID_SACCH(sapi);
	template (present) L1ctlDataReq tr_data := {
		l1header := tr_l1h,
		l2_payload := decmatch tr_frame
	};

	[] as_l1ctl_dl_msg(dl_msg, decmatch tr_data, g_chan_nr, link_id) {
		var octetstring data := dl_msg.payload.data_ind.payload;
		l1h := dec_SacchL1Header(substr(data, 0, 2));
		frame := dec_LapdmFrameAB(substr(data, 2, lengthof(data) - 2));
	}
}

/* This altstep is built on top of as_dl_dcch_lapdm_ab(), and triggers on receipt
 * of a LAPDm AB frame with a L3 payload matching the given template.  The L3
 * payload is treated as PDU_ML3_NW_MS. */
private altstep as_dl_dcch_pdu(out PDU_ML3_NW_MS pdu,
			       template (present) PDU_ML3_NW_MS tr_pdu := ?,
			       template (present) GsmSapi sapi := 0)
runs on ConnHdlr {
	template (present) LapdmFrame tr_frame := tr_LAPDm_UI(sapi, true, decmatch tr_pdu);
	template (present) RslLinkId link_id := tr_RslLinkID_DCCH(sapi);
	var LapdmFrameAB lapdm_frame;

	[] as_dl_dcch_lapdm_ab(lapdm_frame, tr_frame.ab, link_id) {
		pdu := dec_PDU_ML3_NW_MS(lapdm_frame.payload);
	}
}

/***********************************************************************
 * Channel Activation / Deactivation
 ***********************************************************************/

/* Stress test: Do 500 channel activations/deactivations in rapid succession */
private function f_TC_chan_act_stress(charstring id) runs on ConnHdlr {
	for (var integer i := 0; i < 500; i := i+1) {
		f_rsl_chan_act(g_pars.chan_mode);
		f_rsl_chan_deact();
	}
	setverdict(pass);
}
testcase TC_chan_act_stress() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN));
	f_init();
	vc_conn := f_start_handler(refers(f_TC_chan_act_stress), pars);
	vc_conn.done;
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/* Test if re-activation of an already active channel fails as expected */
private function f_TC_chan_act_react(charstring id) runs on ConnHdlr {
	f_rsl_chan_act(g_pars.chan_mode);
	/* attempt to activate the same lchan again -> expect reject */
	RSL.send(ts_RSL_CHAN_ACT(g_chan_nr, g_pars.chan_mode));
	alt {
	[] RSL.receive(tr_RSL_CHAN_ACT_ACK(g_chan_nr)) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Unexpected CHAN ACT ACK on double activation");
		}
	[] RSL.receive(tr_RSL_CHAN_ACT_NACK(g_chan_nr)) {
		setverdict(pass);
		}
	}
	f_rsl_chan_deact();
}
testcase TC_chan_act_react() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN));
	f_init();
	vc_conn := f_start_handler(refers(f_TC_chan_act_react), pars);
	vc_conn.done;
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/* Attempt to de-activate a channel that's not active */
private function f_TC_chan_deact_not_active(charstring id) runs on ConnHdlr {
	timer T := 3.0;
	RSL.send(ts_RSL_RF_CHAN_REL(g_chan_nr));
	T.start;
	alt {
	[] RSL.receive(tr_RSL_RF_CHAN_REL_ACK(g_chan_nr)) {
		setverdict(pass);
		}
	[] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout expecting RF_CHAN_REL_ACK");
		}
	}
}
testcase TC_chan_deact_not_active() runs on test_CT {
	var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN));
	f_init();
	var ConnHdlr vc_conn := f_start_handler(refers(f_TC_chan_deact_not_active), pars);
	vc_conn.done;
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/* attempt to activate channel with wrong RSL Channel Nr IE; expect NACK */
private function f_TC_chan_act_wrong_nr(charstring id) runs on ConnHdlr {
	RSL.send(ts_RSL_CHAN_ACT(g_chan_nr, g_pars.chan_mode));
	alt {
	[] RSL.receive(tr_RSL_CHAN_ACT_ACK(g_chan_nr)) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Unexpected CHAN ACT ACK");
		}
	[] RSL.receive(tr_RSL_CHAN_ACT_NACK(g_chan_nr)) {
		setverdict(pass);
		}
	}
}
private type record WrongChanNrCase {
	RslChannelNr	chan_nr,
	charstring	description
}
private type record of WrongChanNrCase WrongChanNrCases;
private template WrongChanNrCase t_WCN(template RslChannelNr chan_nr, charstring desc) := {
	chan_nr := chan_nr,
	description := desc
}

testcase TC_chan_act_wrong_nr() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;

	f_init();

	var WrongChanNrCases wrong := {
		valueof(t_WCN(t_RslChanNr_RACH(0), "RACH is not a dedicated channel")),
		valueof(t_WCN(t_RslChanNr_RACH(1), "RACH doesn't exist on timeslot")),
		valueof(t_WCN(t_RslChanNr_BCCH(0), "BCCH is not a dedicated channel")),
		valueof(t_WCN(t_RslChanNr_PCH_AGCH(0), "PCH/AGCH is not a dedicated channel")),
		valueof(t_WCN(t_RslChanNr_Bm(0), "TS0 cannot be TCH/F")),
		valueof(t_WCN(t_RslChanNr_Lm(0, 0), "TS0 cannot be TCH/H")),
		valueof(t_WCN(t_RslChanNr_Lm(0, 1), "TS0 cannot be TCH/H")),
		valueof(t_WCN(t_RslChanNr_PDCH(0), "TS0 cannot be PDCH")),
		valueof(t_WCN(t_RslChanNr_SDCCH8(0, 0), "TS0 cannot be SDCCH/8")),
		valueof(t_WCN(t_RslChanNr_SDCCH8(0, 7), "TS0 cannot be SDCCH/8")),
		valueof(t_WCN(t_RslChanNr_SDCCH4(7, 0), "TS7 cannot be SDCCH/4")),
		valueof(t_WCN(t_RslChanNr_SDCCH4(7, 3), "TS7 cannot be SDCCH/4")),
		valueof(t_WCN(t_RslChanNr_Lm(1, 0), "TS1 cannot be TCH/H"))
	};

	for (var integer i := 0; i < sizeof(wrong); i := i+1) {
		pars := valueof(t_Pars(wrong[i].chan_nr, ts_RSL_ChanMode_SIGN));
		vc_conn := f_start_handler(refers(f_TC_chan_act_wrong_nr), pars);
		vc_conn.done;
	}
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/* execute the same callback function on a variety of logical channels */
friend function f_testmatrix_each_chan(ConnHdlrPars pars, void_fn fn) runs on test_CT {
	var ConnHdlr vc_conn;
	f_init();

	/* test on each of the channels we have */
	for (var integer i := 0; i < sizeof(g_AllChanTypes); i := i+1) {
		pars.chan_nr := valueof(g_AllChanTypes[i]);

		log(testcasename(), ": XXX Starting on ", g_AllChanTypes[i]);
		vc_conn := f_start_handler(fn, pars);
		vc_conn.done;
	}

	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/***********************************************************************
 * SACCH handling
 ***********************************************************************/

private function f_exp_sacch(boolean exp) runs on ConnHdlr {
	timer T_sacch := 3.0;
	T_sacch.start;
	alt {
	[not exp] L1CTL.receive(tr_L1CTL_DATA_IND(g_chan_nr, tr_RslLinkID_SACCH(0))) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received SACCH when not expecting it");
		}
	[not exp] T_sacch.timeout {
		setverdict(pass);
		}
	[exp] L1CTL.receive(tr_L1CTL_DATA_IND(g_chan_nr, tr_RslLinkID_SACCH(0))) {
		setverdict(pass);
		}
	[exp] T_sacch.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Timeout waiting for SACCH on ", g_chan_nr));
		}
	[] L1CTL.receive { repeat; }
	[] RSL.receive { repeat; }
	}
}

/* Test if DEACTIVATE SACCH actualy deactivates its transmission (TS 48.058 4.6) */
private function f_TC_deact_sacch(charstring id) runs on ConnHdlr {
	f_l1_tune(L1CTL);
	RSL.clear;

	/* activate the logical channel */
	f_est_dchan();
	L1CTL.clear;

	/* check that SACCH actually are received as expected */
	f_exp_sacch(true);

	/* deactivate SACCH on the logical channel */
	RSL.send(ts_RSL_DEACT_SACCH(g_chan_nr));
	f_sleep(1.0);
	L1CTL.clear;

	/* check that no SACCH are received anymore */
	f_exp_sacch(false);

	/* release the channel */
	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
}
testcase TC_deact_sacch() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;
	f_init();
	for (var integer i := 0; i < sizeof(g_AllChannels); i := i+1) {
	//for (var integer i := 0; i < 1; i := i+1) {
		pars := valueof(t_Pars(g_AllChannels[i], ts_RSL_ChanMode_SIGN));
		log(testcasename(), ": Starting for ", g_AllChannels[i]);
		vc_conn := f_start_handler(refers(f_TC_deact_sacch), pars);
		vc_conn.done;
	}
	/* TODO: do the above in parallel, rather than sequentially? */
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/* verify that given SACCH payload is present */
private function f_sacch_present(template octetstring l3_exp,
				 boolean do_fail := true)
runs on ConnHdlr {
	var L1ctlMessage dl;
	timer T_sacch := 3.0;
	L1CTL.clear;
	T_sacch.start;
	alt {
	[] L1CTL.receive(tr_L1CTL_DATA_IND(g_chan_nr, tr_RslLinkID_SACCH(0))) -> value dl {
		var octetstring l3 := substr(dl.payload.data_ind.payload, 4, 19);
		if (match(l3, l3_exp)) {
			setverdict(pass);
		} else {
			repeat;
		}
		}
	[] L1CTL.receive { repeat; }
	[not do_fail] T_sacch.timeout {
		log("Timeout waiting for SACCH ", l3_exp);
		}
	[do_fail] T_sacch.timeout {
		setverdict(fail, "Timeout waiting for SACCH ", l3_exp);
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
		}
	}
}

/* verify that given SACCH payload is not present */
private function f_sacch_missing(template octetstring l3_exp) runs on ConnHdlr {
	var L1ctlMessage dl;
	timer T_sacch := 3.0;
	L1CTL.clear;
	T_sacch.start;
	alt {
	[] L1CTL.receive(tr_L1CTL_DATA_IND(g_chan_nr, tr_RslLinkID_SACCH(0))) -> value dl {
		var octetstring l3 := substr(dl.payload.data_ind.payload, 4, 19);
		if (match(l3, l3_exp)) {
			setverdict(fail, "Received unexpected SACCH ", dl);
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
		} else {
			repeat;
		}
		}
	[] L1CTL.receive { repeat; }
	[] T_sacch.timeout {
		setverdict(pass);
		}
	}
}

/* Test for default SACCH FILL transmitted in DL SACCH (all channel types) */
private function f_TC_sacch_filling(charstring id) runs on ConnHdlr {
	/* Set a known default SACCH filling for SI5 */
	var octetstring si5 := f_rnd_octstring(19);
	RSL.send(ts_RSL_SACCH_FILL(RSL_SYSTEM_INFO_5, si5));

	f_l1_tune(L1CTL);
	RSL.clear;

	/* activate the logical channel */
	f_est_dchan();

	/* check that the specified SI5 value is actually sent */
	f_sacch_present(si5);

	/* release the channel */
	RSL.clear;
	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
}
testcase TC_sacch_filling() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;
	f_init();
	for (var integer i := 0; i < sizeof(g_AllChannels); i := i+1) {
		pars := valueof(t_Pars(g_AllChannels[i], ts_RSL_ChanMode_SIGN));
		log(testcasename(), ": Starting for ", g_AllChannels[i]);
		vc_conn := f_start_handler(refers(f_TC_sacch_filling), pars);
		vc_conn.done;
	}
	/* TODO: do the above in parallel, rather than sequentially? */
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/* Test for lchan-specific SACCH INFO MODIFY (TS 48.058 4.12) */
private function f_TC_sacch_info_mod(charstring id) runs on ConnHdlr {
	/* Set a known default SACCH filling for SI5 */
	var octetstring si5 := f_rnd_octstring(19);
	var octetstring si5_diff := f_rnd_octstring(19);
	RSL.send(ts_RSL_SACCH_FILL(RSL_SYSTEM_INFO_5, si5));

	f_l1_tune(L1CTL);
	RSL.clear;

	log("Activating channel, expecting standard SI5");
	/* activate the logical channel */
	f_est_dchan();
	/* check that the specified SI5 value is actually sent */
	f_sacch_present(si5);

	/* set channel-specific different SI5 */
	log("Setting channel specific SACCH INFO, expecting it");
	RSL.send(ts_RSL_SACCH_INF_MOD(g_chan_nr, RSL_SYSTEM_INFO_5, si5_diff))
	/* check that the specified lchan-specific value is now used */
	f_sacch_present(si5_diff);

	/* deactivate the channel and re-activate it, this should result in default SI5  */
	log("De-activating and re-activating channel, expecting standard SI5");
	f_rsl_chan_deact();
	f_rsl_chan_act(valueof(ts_RSL_ChanMode_SIGN));
	/* Verify that the TRX-wide default SACCH filling is present again */
	f_sacch_present(si5);

	/* release the channel */
	RSL.clear;
	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
}
testcase TC_sacch_info_mod() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;
	f_init();
	for (var integer i := 0; i < sizeof(g_AllChannels); i := i+1) {
		pars := valueof(t_Pars(g_AllChannels[i], ts_RSL_ChanMode_SIGN));
		log(testcasename(), ": Starting for ", g_AllChannels[i]);
		vc_conn := f_start_handler(refers(f_TC_sacch_info_mod), pars);
		vc_conn.done;
	}
	/* TODO: do the above in parallel, rather than sequentially? */
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/* Test SACCH scheduling of multiple different SI message types */
private function f_TC_sacch_multi(charstring id) runs on ConnHdlr {
	var octetstring si5 := f_rnd_octstring(19);
	var octetstring si5bis := f_rnd_octstring(19);
	var octetstring si5ter := f_rnd_octstring(19);
	var octetstring si6 := f_rnd_octstring(19);

	RSL.send(ts_RSL_SACCH_FILL(RSL_SYSTEM_INFO_5, si5));
	RSL.send(ts_RSL_SACCH_FILL(RSL_SYSTEM_INFO_5bis, si5bis));
	RSL.send(ts_RSL_SACCH_FILL(RSL_SYSTEM_INFO_5ter, si5ter));
	RSL.send(ts_RSL_SACCH_FILL(RSL_SYSTEM_INFO_6, si6));

	f_l1_tune(L1CTL);
	RSL.clear;

	/* activate the logical channel */
	f_est_dchan();
	L1CTL.clear;

	/* check that SACCH actually are received as expected */
	f_sacch_present(si5);
	f_sacch_present(si5bis);
	f_sacch_present(si5ter);
	f_sacch_present(si6);

	/* release the channel */
	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
}
testcase TC_sacch_multi() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;
	f_init();
	for (var integer i := 0; i < sizeof(g_AllChannels); i := i+1) {
		pars := valueof(t_Pars(g_AllChannels[i], ts_RSL_ChanMode_SIGN));
		log(testcasename(), ": Starting for ", g_AllChannels[i]);
		vc_conn := f_start_handler(refers(f_TC_sacch_multi), pars);
		vc_conn.done;
	}
	/* TODO: do the above in parallel, rather than sequentially? */
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/* Test if SACH information is modified as expected */
private function f_TC_sacch_multi_chg(charstring id) runs on ConnHdlr {
	var octetstring si5 := f_rnd_octstring(19);
	var octetstring si6 := f_rnd_octstring(19);

	/* First, configure both SI5 and SI6 to be transmitted */
	RSL.send(ts_RSL_SACCH_FILL(RSL_SYSTEM_INFO_5, si5));
	RSL.send(ts_RSL_SACCH_FILL(RSL_SYSTEM_INFO_6, si6));

	f_l1_tune(L1CTL);
	RSL.clear;

	/* activate the logical channel */
	f_est_dchan();
	L1CTL.clear;

	/* check that SACCH actually are received as expected */
	f_sacch_present(si5);
	f_sacch_present(si6);

	/* disable SI6 */
	RSL.send(ts_RSL_SACCH_FILL(RSL_SYSTEM_INFO_6, ''O));

	/* check that SI5 is still transmitted */
	f_sacch_present(si5);
	/* check if SI6 is now gone */
	f_sacch_missing(si6);

	/* release the channel */
	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
}
testcase TC_sacch_multi_chg() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;
	f_init();
	for (var integer i := 0; i < sizeof(g_AllChannels); i := i+1) {
		pars := valueof(t_Pars(g_AllChannels[i], ts_RSL_ChanMode_SIGN));
		log(testcasename(), ": Starting for ", g_AllChannels[i]);
		vc_conn := f_start_handler(refers(f_TC_sacch_multi_chg), pars);
		vc_conn.done;
	}
	/* TODO: do the above in parallel, rather than sequentially? */
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/* Test for SACCH information present in RSL CHAN ACT (overrides FILLING) */
private function f_TC_sacch_chan_act(charstring id) runs on ConnHdlr {
	var octetstring si5 := f_rnd_octstring(19);
	var octetstring si6 := f_rnd_octstring(19);
	var octetstring si5_specific := f_rnd_octstring(19);
	var octetstring si6_specific := f_rnd_octstring(19);

	/* First, configure both SI5 and SI6 to be transmitted */
	RSL.send(ts_RSL_SACCH_FILL(RSL_SYSTEM_INFO_5, si5));
	RSL.send(ts_RSL_SACCH_FILL(RSL_SYSTEM_INFO_6, si6));

	f_l1_tune(L1CTL);
	RSL.clear;

	/* activate channel with different SACCH filling */
	var RSL_SacchInfo sacch_info := valueof(ts_RSL_SacchInfo({
				ts_RSL_SacchInfoElem(RSL_SYSTEM_INFO_5, si5_specific),
				ts_RSL_SacchInfoElem(RSL_SYSTEM_INFO_6, si6_specific)
				}));
	var RSL_IE_List addl_ies := { valueof(t_RSL_IE(RSL_IE_SACCH_INFO,
							RSL_IE_Body:{sacch_info := sacch_info})) };
	f_est_dchan(more_ies := addl_ies);

	/* check that SACCH actually are received as expected */
	f_sacch_present(si5_specific);
	f_sacch_present(si6_specific);

	/* release the channel */
	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
}
testcase TC_sacch_chan_act() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;
	f_init();

	for (var integer i := 0; i < sizeof(g_AllChannels); i := i+1) {
		pars := valueof(t_Pars(g_AllChannels[i], ts_RSL_ChanMode_SIGN));
		log(testcasename(), ": Starting for ", g_AllChannels[i]);
		vc_conn := f_start_handler(refers(f_TC_sacch_chan_act), pars);
		vc_conn.done;
	}
	/* TODO: do the above in parallel, rather than sequentially? */
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/* verify that SACCH DL transmission is started only if MS power IE present
 * see section 4.1.3 of 3GPP TS 48.058 */
private function f_TC_sacch_chan_act_ho_async(charstring id) runs on ConnHdlr {
	var octetstring si5 := f_rnd_octstring(19);
	RSL.send(ts_RSL_SACCH_FILL(RSL_SYSTEM_INFO_5, si5));

	f_l1_tune(L1CTL);
	RSL.clear;

	/* Step 1: Activate ASYNC HO channel without MS power IE */

	var integer ho_ref := oct2int(f_rnd_octstring(1));
	var RSL_IE ho_ref_ie := valueof(t_RSL_IE(RSL_IE_HANDO_REF,
					RSL_IE_Body:{ handover_ref := ho_ref }));
	var RSL_IE_List addl_ies := {
		ho_ref_ie
		};

	/* Activate channel on BTS side */
	f_rsl_chan_act(g_pars.chan_mode, more_ies := addl_ies, act_type := t_RSL_IE_ActType_HO_ASYNC);
	/* don't perform immediate assignment here, as we're testing non-IA case */
	/* enable dedicated mode */
	f_l1ctl_est_dchan(L1CTL, g_pars);

	/* Verify that no DL SACCH is being received */
	f_sacch_missing(?);

	/* Send handover Access Burst and expect SACCH to start */
	f_L1CTL_RACH(L1CTL, ho_ref, chan_nr := g_pars.chan_nr);

	f_sacch_present(si5);

	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
	f_L1CTL_RESET(L1CTL);

	/* Tune back to CCCH/BCCH */
	f_l1_tune(L1CTL);


	/* Step 2: Activate ASYNC HO channel with MS power IE */

	/* Activate channel on BTS side */
	addl_ies := {
		ho_ref_ie,
		valueof(t_RSL_IE(RSL_IE_MS_POWER, RSL_IE_Body:{ms_power := ts_RSL_IE_MS_Power(0)}))
		};
	f_rsl_chan_act(g_pars.chan_mode, more_ies := addl_ies, act_type := t_RSL_IE_ActType_HO_ASYNC);
	/* don't perform immediate assignment here, as we're testing non-IA case */
	/* enable dedicated mode */
	f_l1ctl_est_dchan(L1CTL, g_pars);

	/* 4.1.3 "If the MS Power IE is present the BTS *may* start transmission
	 * also on the SACCH".  "May" does not mean "shall", so osmo-bts does not. */
	f_sacch_present(si5, do_fail := false);

	/* Send handover Access Burst and expect SACCH to remain present */
	f_L1CTL_RACH(L1CTL, ho_ref, chan_nr := g_pars.chan_nr);

	f_sacch_present(si5);

	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
}
testcase TC_sacch_chan_act_ho_async() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;
	f_init();

	for (var integer i := 0; i < sizeof(g_AllChanTypes); i := i+1) {
		pars := valueof(t_Pars(g_AllChanTypes[i], ts_RSL_ChanMode_SIGN));
		log(testcasename(), ": Starting for ", g_AllChanTypes[i]);
		vc_conn := f_start_handler(refers(f_TC_sacch_chan_act_ho_async), pars);
		vc_conn.done;
	}
	/* TODO: do the above in parallel, rather than sequentially? */
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/* verify that SACCH DL transmission is started only if TA + MS power IEs present,
 * see section 4.1.4 of 3GPP TS 48.058 */
private function f_TC_sacch_chan_act_ho_sync(charstring id) runs on ConnHdlr {
	var octetstring si5 := f_rnd_octstring(19);
	RSL.send(ts_RSL_SACCH_FILL(RSL_SYSTEM_INFO_5, si5));

	var RSL_IE_List addl_ies;

	f_l1_tune(L1CTL);
	RSL.clear;

	/* Step 1: Activate SYNC HO channel without MS power IE */

	var integer ho_ref := oct2int(f_rnd_octstring(1));
	var RSL_IE ho_ref_ie := valueof(t_RSL_IE(RSL_IE_HANDO_REF,
					RSL_IE_Body:{ handover_ref := ho_ref }));
	addl_ies := {
		ho_ref_ie
		};

	/* Activate channel on BTS side */
	f_rsl_chan_act(g_pars.chan_mode, more_ies := addl_ies, act_type := t_RSL_IE_ActType_HO_SYNC);
	/* don't perform immediate assignment here, as we're testing non-IA case */
	/* enable dedicated mode */
	f_l1ctl_est_dchan(L1CTL, g_pars);

	/* Verify that no DL SACCH is being received */
	f_sacch_missing(?);

	/* Send handover Access Burst and expect SACCH to start */
	f_L1CTL_RACH(L1CTL, ho_ref, chan_nr := g_pars.chan_nr);

	f_sacch_present(si5);

	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
	f_L1CTL_RESET(L1CTL);

	/* Tune back to CCCH/BCCH */
	f_l1_tune(L1CTL);


	/* Step 2a: Activate SYNC HO channel with only MS power IE */

	/* Activate channel on BTS side */
	addl_ies := {
		ho_ref_ie,
		valueof(t_RSL_IE(RSL_IE_MS_POWER, RSL_IE_Body:{ms_power := ts_RSL_IE_MS_Power(0)}))
		};
	f_rsl_chan_act(g_pars.chan_mode, more_ies := addl_ies, act_type := t_RSL_IE_ActType_HO_SYNC);
	/* don't perform immediate assignment here, as we're testing non-IA case */
	/* enable dedicated mode */
	f_l1ctl_est_dchan(L1CTL, g_pars);

	/* 4.1.4 "If only the MS Power IE is present the BTS *may* start transmission
	 * also on the SACCH".  "May" does not mean "shall", so osmo-bts does not. */
	f_sacch_present(si5, do_fail := false);

	/* Send handover Access Burst and expect SACCH to remain present */
	f_L1CTL_RACH(L1CTL, ho_ref, chan_nr := g_pars.chan_nr);

	f_sacch_present(si5);

	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
	f_L1CTL_RESET(L1CTL);

	/* Tune back to CCCH/BCCH */
	f_l1_tune(L1CTL);


	/* Step 2b: Activate SYNC HO channel with TA IE */

	/* Activate channel on BTS side */
	addl_ies := {
		ho_ref_ie,
		valueof(t_RSL_IE(RSL_IE_TIMING_ADVANCE, RSL_IE_Body:{timing_adv := 0}))
		};
	f_rsl_chan_act(g_pars.chan_mode, more_ies := addl_ies, act_type := t_RSL_IE_ActType_HO_SYNC);
	/* don't perform immediate assignment here, as we're testing non-IA case */
	/* enable dedicated mode */
	f_l1ctl_est_dchan(L1CTL, g_pars);

	/* Verify that no DL SACCH is being received */
	f_sacch_missing(?);

	/* Send handover Access Burst and expect SACCH to start */
	f_L1CTL_RACH(L1CTL, ho_ref, chan_nr := g_pars.chan_nr);

	f_sacch_present(si5);

	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
	f_L1CTL_RESET(L1CTL);

	/* Tune back to CCCH/BCCH */
	f_l1_tune(L1CTL);


	/* Step 3: Activate SYNC HO channel with MS power IE and TA IE */

	/* Activate channel on BTS side */
	addl_ies := {
		ho_ref_ie,
		valueof(t_RSL_IE(RSL_IE_TIMING_ADVANCE, RSL_IE_Body:{timing_adv := 0})),
		valueof(t_RSL_IE(RSL_IE_MS_POWER, RSL_IE_Body:{ms_power := ts_RSL_IE_MS_Power(0)}))
		};
	f_rsl_chan_act(g_pars.chan_mode, more_ies := addl_ies, act_type := t_RSL_IE_ActType_HO_SYNC);
	/* don't perform immediate assignment here, as we're testing non-IA case */
	/* enable dedicated mode */
	f_l1ctl_est_dchan(L1CTL, g_pars);

	/* Verify that DL SACCH is being received */
	f_sacch_present(si5);

	/* Send handover Access Burst and expect SACCH to remain present */
	f_L1CTL_RACH(L1CTL, ho_ref, chan_nr := g_pars.chan_nr);

	f_sacch_present(si5);

	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
}
testcase TC_sacch_chan_act_ho_sync() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;
	f_init();

	for (var integer i := 0; i < sizeof(g_AllChanTypes); i := i+1) {
		pars := valueof(t_Pars(g_AllChanTypes[i], ts_RSL_ChanMode_SIGN));
		log(testcasename(), ": Starting for ", g_AllChanTypes[i]);
		vc_conn := f_start_handler(refers(f_TC_sacch_chan_act_ho_sync), pars);
		vc_conn.done;
	}
	/* TODO: do the above in parallel, rather than sequentially? */
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}


/***********************************************************************
 * RACH Handling
 ***********************************************************************/

/* Send 1000 RACH requests and check their RA+FN on the RSL side */
private function f_TC_rach_content(boolean emerg) runs on test_CT {
	f_init();
	f_init_l1ctl();
	f_l1_tune(L1CTL);

	var GsmFrameNumber fn_last := 0;
	var boolean test_failed := false;
	for (var integer i := 0; i < 1000; i := i+1) {
		var OCT1 ra;
		if (emerg == true) {
			ra := f_rnd_ra_emerg();
		} else {
			ra := f_rnd_ra_cs();
		}
		var GsmFrameNumber fn := f_L1CTL_RACH(L1CTL, oct2int(ra));
		if (fn == fn_last) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Two RACH in same FN?!?");
		}
		fn_last := fn;

		timer T := 5.0;
		T.start;
		alt {
		[] RSL_CCHAN.receive(tr_ASP_RSL_UD(tr_RSL_CHAN_RQD(ra, fn, t_RslChanNr_RACH(0)))) {
			T.stop;
			}
		[] RSL_CCHAN.receive(tr_ASP_RSL_UD(tr_RSL_CHAN_RQD(?, ?, ?, ?))) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Unexpected CHAN RQD");
			}
		[] RSL_CCHAN.receive { repeat; }
		[] T.timeout {
			test_failed := true;
			log("[", i, "] Timeout waiting for CHAN RQD FN=", fn, " RA=", ra);
			}
		}
	}
	if (test_failed) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Some out of 1000 RACH requests timed out"));
	}
	setverdict(pass);
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/* Normal variant */
testcase TC_rach_content() runs on test_CT {
	 f_TC_rach_content(emerg := false);
}

/* Emergency call variant */
testcase TC_rach_content_emerg() runs on test_CT {
	 f_TC_rach_content(emerg := true);
}

/* Send 1000 RACH Requests (flood ~ 89/s) and count if count(Abis) == count(Um) */
testcase TC_rach_count() runs on test_CT {
	f_init();
	f_init_l1ctl();
	f_sleep(1.0);
	f_l1_tune(L1CTL);

	var GsmFrameNumber fn_last := 0;
	for (var integer i := 0; i < 1000; i := i+1) {
		var OCT1 ra := f_rnd_ra_cs();
		var GsmFrameNumber fn := f_L1CTL_RACH(L1CTL, oct2int(ra));
		if (fn == fn_last) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Two RACH in same FN?!?");
		}
		fn_last := fn;
	}
	var integer rsl_chrqd := 0;
	timer T := 3.0;
	T.start;
	alt {
	[] RSL_CCHAN.receive(tr_ASP_RSL_UD(tr_RSL_CHAN_RQD(?,?))) {
		rsl_chrqd := rsl_chrqd + 1;
		f_timer_safe_restart(T);
		repeat;
		}
	[] RSL_CCHAN.receive { repeat; }
	[] T.timeout { }
	}
	if (rsl_chrqd == 1000) {
		setverdict(pass);
	} else {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Received only ", rsl_chrqd, " out of 1000 RACH"));
	}
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

private function f_vty_load_ind_thresh(integer period := 10, integer bts_nr := 0) runs on test_CT {
	var charstring bts_str := "bts " & int2str(bts_nr);
	f_vty_config2(BSCVTY, {"network", bts_str}, "ccch load-indication-threshold " & int2str(period));
}

/* empirical value: Number of RACH slots per reporting interval (1s) on combined CCCH */
private template integer tr_rach_slots_per_interval := (90 .. 130);

/* Expect 0 RACH load on an idle BTS that has just started up */
testcase TC_rach_load_idle_thresh0() runs on test_CT {
	var ASP_RSL_Unitdata rx_ud;

	f_init_vty_bsc();
	/* send load indications even at 0% load */
	f_vty_load_ind_thresh(0);
	f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
	f_sleep(2.0);

	f_init();

	/* Skip the first RACH LOAD IND, as it may not have the full slot count (BTS started less than 1s  before) */
	alt {
	[] RSL_CCHAN.receive(tr_ASP_RSL_UD(tr_RSL_RACH_LOAD_IND(?, ?, ?))) { }
	[] RSL_CCHAN.receive { repeat }
	}

	timer T := 5.0;
	T.start;
	alt {
	[] RSL_CCHAN.receive(tr_ASP_RSL_UD(tr_RSL_RACH_LOAD_IND(tr_rach_slots_per_interval, 0, 0))) {
		setverdict(pass);
		repeat;
		}
	[] RSL_CCHAN.receive(tr_ASP_RSL_UD(tr_RSL_RACH_LOAD_IND(?, ?, ?))) -> value rx_ud {
		setverdict(fail, "Unexpected RACH LOAD IND: ", rx_ud);
		repeat;
		}
	[] RSL_CCHAN.receive {
		repeat;
		}
	[] T.timeout { }
	}

	f_vty_load_ind_thresh(10);
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/* Expect no RACH load indications on an idle BTS that has just started up (default threshold 10%) */
testcase TC_rach_load_idle_below_thresh() runs on test_CT {
	var ASP_RSL_Unitdata rx_ud;

	f_init_vty_bsc();
	f_init();

	timer T := 5.0;
	T.start;
	alt {
	[] RSL_CCHAN.receive(tr_ASP_RSL_UD(tr_RSL_RACH_LOAD_IND(?, ?, ?))) -> value rx_ud {
		setverdict(fail, "Unexpected RACH LOAD IND: ", rx_ud);
		repeat;
		}
	[] RSL_CCHAN.receive {
		repeat;
		}
	[] T.timeout {
		setverdict(pass);
		}
	}

	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/* Expect 0 RACH load on an idle BTS that has just started up */
testcase TC_rach_load_count() runs on test_CT {
	var ASP_RSL_Unitdata rx_ud;
	var integer load_access_count := 0;

	f_init_vty_bsc();
	/* send load indications even at 0% load */
	f_vty_load_ind_thresh(0);
	f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
	f_sleep(2.0);
	f_init();

	f_init_l1ctl();
	f_sleep(1.0);
	f_l1_tune(L1CTL);

	/* Skip the first RACH LOAD IND, as it may not have the full slot count (BTS started less than 1s  before) */
	alt {
	[] RSL_CCHAN.receive(tr_ASP_RSL_UD(tr_RSL_RACH_LOAD_IND(?, ?, ?))) { }
	[] RSL_CCHAN.receive { repeat }
	}

	var GsmFrameNumber fn_last := 0;
	for (var integer i := 0; i < 1000; i := i+1) {
		var OCT1 ra := f_rnd_ra_cs();
		var GsmFrameNumber fn := f_L1CTL_RACH(L1CTL, oct2int(ra));
		if (fn == fn_last) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Two RACH in same FN?!?");
		}
		fn_last := fn;
	}

	timer T := 5.0;
	T.start;
	alt {
	[] RSL_CCHAN.receive(tr_ASP_RSL_UD(tr_RSL_RACH_LOAD_IND(tr_rach_slots_per_interval, ?, ?)))
										-> value rx_ud {
		var RSL_IE_Body ie;
		f_rsl_find_ie(rx_ud.rsl, RSL_IE_RACH_LOAD, ie);
		load_access_count := load_access_count + ie.rach_load.access_count;
		if (ie.rach_load.busy_count < ie.rach_load.access_count) {
			setverdict(fail, "Access count cannot be < Busy count");
		}
		repeat;
		}
	[] RSL_CCHAN.receive(tr_ASP_RSL_UD(tr_RSL_RACH_LOAD_IND(?, ?, ?))) -> value rx_ud {
		setverdict(fail, "Unexpected RACH LOAD IND: ", rx_ud);
		repeat;
		}
	[] RSL_CCHAN.receive {
		repeat;
		}
	[] T.timeout { }
	}
	if (load_access_count == 1000) {
		setverdict(pass);
	} else {
		setverdict(fail, "Load reports state ", load_access_count, " RACH, but we sent 1000");
	}

	f_vty_load_ind_thresh(10);
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

private function f_rach_toffs(int16_t toffs256, boolean expect_pass) runs on test_CT {
	var TrxcMessage ret;
	/* tell fake_trx to use a given timing offset for all bursts */
	ret := f_TRXC_transceive(BTS_TRXC, g_bts_trxc_conn_id, ts_TRXC_FAKE_TIMING(toffs256));
	f_sleep(0.5);

	/* Transmit RACH request + wait for confirmation */
	var OCT1 ra := f_rnd_ra_cs();
	var GsmFrameNumber fn := f_L1CTL_RACH(L1CTL, oct2int(ra));

	/* Check for expected result */
	timer T := 1.5;
	T.start;
	alt {
	[expect_pass] RSL_CCHAN.receive(tr_ASP_RSL_UD(tr_RSL_CHAN_RQD(ra, fn))) {
		setverdict(pass);
		}
	[not expect_pass] RSL_CCHAN.receive(tr_ASP_RSL_UD(tr_RSL_CHAN_RQD(ra, fn))) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("RACH passed but was expected to be dropped: ", toffs256));
		}
	[] RSL_CCHAN.receive { repeat; }
	[not expect_pass] T.timeout {
		setverdict(pass);
		}
	[expect_pass] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Timeout waiting for CHAN RQD: FN=", fn, " RA=", ra));
		}
	}
}

/* Test if dropping of RACH Based on NM_ATT_MAX_TA works */
testcase TC_rach_max_ta() runs on test_CT {
	f_init();
	f_init_l1ctl();
	f_l1_tune(L1CTL);
	f_sleep(1.0);

	/* default max-ta is 63 (full range of GSM timing advance */

	/* We allow early arrival up to 2 symbols */
	f_rach_toffs(-1*256, true);
	f_rach_toffs(-2*256, true);
	f_rach_toffs(-10*256, false);

	/* 0 / 32 / 63 bits is legal / permitted */
	f_rach_toffs(0, true);
	f_rach_toffs(32*256, true);
	f_rach_toffs(63*256, true);

	/* more than 63 bits is not legal / permitted */
	f_rach_toffs(64*256, false);
	f_rach_toffs(127*256, false);
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

private function f_TC_ho_rach(charstring id) runs on ConnHdlr {
	var GsmFrameNumber fn;
	var RSL_Message rm;

	f_l1_tune(L1CTL);
	RSL.clear;

	/* Generate a random Handover Reference */
	var integer ho_ref := oct2int(f_rnd_octstring(1));

	/* Handover Reference IE (see 3GPP TS 48.058, 9.3.9) */
	var RSL_IE ho_ref_ie := valueof(t_RSL_IE(RSL_IE_HANDO_REF,
					RSL_IE_Body:{ handover_ref := ho_ref }));

	/* Activate a channel on the BTS side (no encryption) */
	f_rsl_chan_act(g_pars.chan_mode, more_ies := { ho_ref_ie },
		       act_type := t_RSL_IE_ActType_HO_SYNC);

	/* Switch the MS side (e.g. trxcon) to a dedicated channel without
	 * waiting for Immediate Assignment and sending Access Burst */
	f_l1ctl_est_dchan(L1CTL, g_pars);

	/* Send handover Access Burst */
	fn := f_L1CTL_RACH(L1CTL, ho_ref, chan_nr := g_pars.chan_nr);

	/* TODO: test mismatching Handover Reference, and missing IE */

	/* Wait for handover detection */
	timer T := 3.0;
	T.start;
	alt {
	[] RSL.receive(tr_RSL_HANDO_DET(g_pars.chan_nr)) -> value rm {
		log("Handover RACH has been detected: ", rm);
		setverdict(pass);
		}
	[] RSL.receive(tr_RSL_CHAN_RQD(?, ?, ?, ?)) -> value rm {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
			log2str("RSL_CHAN_RQD was not expected: ", rm));
		}
	[] RSL.receive { repeat; }
	[] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
			log2str("Timeout waiting for handover RACH: FN=", fn, " RA=", ho_ref));
		}
	}

	/* Release the channel */
	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
}

/* Test handover RACH detection */
testcase TC_ho_rach() runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;

	f_init();

	for (var integer i := 0; i < sizeof(g_AllChannels); i := i + 1) {
		pars := valueof(t_Pars(g_AllChannels[i], ts_RSL_ChanMode_SIGN));
		log(testcasename(), ": Starting for ", g_AllChannels[i]);
		vc_conn := f_start_handler(refers(f_TC_ho_rach), pars);
		vc_conn.done;
	}

	/* TODO: do the above in parallel, rather than sequentially? */
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/* Test sending of the RR Physical Information message on DCCH */
private function f_TC_ho_physical_info(charstring id) runs on ConnHdlr {
	var PDU_ML3_NW_MS dcch_pdu;
	var integer count := 0;
	var L1ctlMessage dl;
	timer T;

	f_l1_tune(L1CTL);
	RSL.clear;

	/* Generate a random Handover Reference */
	var integer ho_ref := oct2int(f_rnd_octstring(1));

	/* Handover Reference IE (see 3GPP TS 48.058, 9.3.9) */
	var RSL_IE ho_ref_ie := valueof(t_RSL_IE(RSL_IE_HANDO_REF,
					RSL_IE_Body:{ handover_ref := ho_ref }));

	/* Activate a channel on the BTS side (no encryption) */
	f_rsl_chan_act(g_pars.chan_mode, more_ies := { ho_ref_ie },
		       act_type := t_RSL_IE_ActType_HO_SYNC);

	/* Switch the MS side (e.g. trxcon) to a dedicated channel without
	 * waiting for Immediate Assignment and sending of an Access Burst. */
	f_l1ctl_est_dchan(L1CTL, g_pars); /* FIXME: disable Uplink Tx */

	/* Expect nothing to be transmitted on Downlink DCCH.  Nothing in this
	 * context means any L2 frames, not only the RR Physical Information. */
	T.start(2.0);
	L1CTL.clear;
	alt {
	[] L1CTL.receive(tr_L1CTL_DATA_IND(g_chan_nr, tr_RslLinkID_DCCH(?))) -> value dl {
		setverdict(fail, "Rx unexpected Downlink DCCH (before handover RACH): ", dl);
		T.stop;
		}
	[] L1CTL.receive { repeat; }
	[] T.timeout { setverdict(pass); }
	}

	/* Send handover Access Burst */
	log("Sending handover Access Burst");
	f_L1CTL_RACH(L1CTL, ho_ref, chan_nr := g_pars.chan_nr);

	/* Expect RR Physical Information being sent on Downlink DCCH Ny1 times */
	T.start(int2float(mp_ho_t3105_ms * mp_ho_ny1) / 1000.0 + 1.0);
	L1CTL.clear;
	alt {
	[] as_dl_lapdm_dummy(); /* Ignore empty LAPDm func=UI frames */
	[] as_dl_dcch_pdu(dcch_pdu, tr_RRM_PhysicalInfo) {
		log("Rx RR Physical Information: ", dcch_pdu);
		/* Wait until the count reaches Ny1 */
		count := count + 1;
		if (count < mp_ho_ny1)
			{ repeat; }
		setverdict(pass);
		}
	[] as_dl_dcch_pdu(dcch_pdu, ?) {
		setverdict(fail, "Rx unexpected DCCH PDU: ", dcch_pdu);
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
		}
	[] L1CTL.receive { repeat; }
	[] T.timeout {
		setverdict(fail, "Timeout waiting for RR Physical Information");
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
		}
	}

	/* Release the channel */
	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
}
testcase TC_ho_physical_info() runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;

	f_init();

	for (var integer i := 0; i < sizeof(g_AllChanTypes); i := i + 1) {
		pars := valueof(t_Pars(g_AllChanTypes[i], ts_RSL_ChanMode_SIGN));
		log(testcasename(), ": Starting for ", g_AllChanTypes[i]);
		vc_conn := f_start_handler(refers(f_TC_ho_physical_info), pars);
		vc_conn.done;
	}

	/* TODO: do the above in parallel, rather than sequentially? */
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/***********************************************************************
 * Measurement Processing / Reporting
 ***********************************************************************/

private template (value) LapdmAddressField
ts_LapdmAddr(template (value) LapdmSapi sapi,
	     template (value) boolean c_r) := {
	spare := '0'B,
	lpd := 0,
	sapi := sapi,
	c_r := c_r,
	ea := true
}

private template (value) LapdmFrameAB
ts_LAPDm_AB(template (value) LapdmSapi sapi,
	    template (value) GsmRrL3Message l3,
	    template (value) boolean c_r := false,
	    template (value) boolean p := false) := {
	addr := ts_LapdmAddr(sapi, c_r),
	ctrl := ts_LapdmCtrlUI(valueof(p)),
	len := 0, /* overwritten */
	m := false,
	el := 1,
	payload := enc_GsmRrL3Message(valueof(l3)),
	padding := ''O
}

/* handle incoming downlink SACCH and respond with uplink SACCH (meas res) */
private altstep as_l1_sacch() runs on ConnHdlr {
	var template (value) LapdmFrameAB lb;
	var L1ctlMessage l1_dl;

	[] L1CTL.receive(tr_L1CTL_DATA_IND(g_chan_nr, tr_RslLinkID_SACCH(?))) -> value l1_dl {
		log("SACCH received: ", l1_dl.payload.data_ind.payload);

		lb := ts_LAPDm_AB(0, ts_MEAS_REP(g_pars.l1_pars.meas_valid,
						 g_pars.l1_pars.meas_ul.full.rxlev,
						 g_pars.l1_pars.meas_ul.sub.rxlev,
						 g_pars.l1_pars.meas_ul.full.rxqual,
						 g_pars.l1_pars.meas_ul.sub.rxqual));
		log("LAPDm: ", lb);

		var template (value) SacchL1Header l1h := ts_SacchL1Header(
			g_pars.l1_pars.ms_power_level, g_pars.l1_pars.ms_actual_ta);

		/* According to 3GPP TS 44.018, section 10.5.2.20, we should pad with zeroes */
		var octetstring l2 := f_pad_oct(enc_LapdmFrameAB(valueof(lb)), 21, '00'O);

		log("Sending Measurement Report: ", l1h, l2);
		L1CTL.send(ts_L1CTL_DATA_REQ_SACCH(g_chan_nr, ts_RslLinkID_SACCH(0), l1h, l2));
		repeat;
		}
}

/* handle incoming downlink SACCH, decode the L1 header into the given record */
private altstep as_l1_sacch_l1h(inout SacchL1Header l1h,
				boolean do_apply := true)
runs on ConnHdlr
{
	var L1ctlMessage l1_dl;

	[] L1CTL.receive(tr_L1CTL_DATA_IND(g_chan_nr, tr_RslLinkID_SACCH(?))) -> value l1_dl {
		/* Parse the L1 SACCH header (MS Power Level & Timing Advance) */
		l1h := dec_SacchL1Header(substr(l1_dl.payload.data_ind.payload, 0, 2));
		log(%definitionId, "(): Rx SACCH L1 header: ", l1h);

		if (do_apply) {
			/* Update TA and MS power to follow what BTS requests */
			f_L1CTL_PARAM(L1CTL, l1h.actual_ta, l1h.ms_power_lvl);
		}
	}
}

private altstep as_l1_dcch_loop() runs on ConnHdlr {
	var L1ctlMessage l1_dl;
	[] L1CTL.receive(tr_L1CTL_DATA_IND(g_chan_nr, tr_RslLinkID_DCCH(?))) -> value l1_dl {
		log("DCCH received: ", l1_dl.payload.data_ind.payload);
		var octetstring pl := '010301'O;
		L1CTL.send(ts_L1CTL_DATA_REQ(g_chan_nr, ts_RslLinkID_DCCH(0),
			f_pad_oct(pl, 23, '2B'O)));
		repeat;
		}
}

private altstep as_l1_tch_loop() runs on ConnHdlr {
	var L1ctlMessage l1_dl;
	[] L1CTL.receive(tr_L1CTL_TRAFFIC_IND(g_chan_nr)) -> value l1_dl {
		log("TCH received: ", l1_dl.payload.traffic_ind.data);

		/* occasionaly inject FACCH frames into the uplink */
		if (g_pars.l1_pars.facch_enabled == true and l1_dl.dl_info.frame_nr mod 5 == 0) {
			var octetstring pl := '010301'O;
			L1CTL.send(ts_L1CTL_DATA_REQ(g_chan_nr, ts_RslLinkID_DCCH(0),
				   f_pad_oct(pl, 23, '2B'O)));
		} else {
			L1CTL.send(ts_L1CTL_TRAFFIC_REQ(g_chan_nr, l1_dl.dl_info.link_id,
				   l1_dl.payload.traffic_ind.data));
		}

		repeat;
		}
}

private type record MeasElem {
	uint6_t rxlev,
	uint3_t rxqual
}

private type record MeasElemFS {
	MeasElem full,
	MeasElem sub
}

private type record ConnL1Pars {
	boolean dtx_enabled,
	boolean toa256_enabled,
	boolean meas_valid,
	MeasElemFS meas_ul,
	int16_t timing_offset_256syms,
	uint4_t bs_power_level,
	uint5_t ms_power_level,
	uint8_t ms_actual_ta,
	boolean facch_enabled
}

/* Convert tiing offset from 1/256th symbol to RSL Timing Offset */
private function toffs256s_to_rsl(int16_t toffs256s) return uint8_t {
	return 63 + (toffs256s/256);
}

private function f_max(integer a, integer b) return integer {
	if (a > b) {
		return a;
	} else {
		return b;
	}
}

private function f_min(integer a, integer b) return integer {
	if (a < b) {
		return a;
	} else {
		return b;
	}
}

/* compute negative tolerance val-tolerance, ensure >= min */
private function f_tolerance_neg(integer val, integer min, integer tolerance) return integer {
	val := val - tolerance;
	return f_max(val, min);
}

/* compute positive tolerance val+tolerance, ensure <= max */
private function f_tolerance_pos(integer val, integer max, integer tolerance) return integer {
	val := val + tolerance;
	return f_min(val, max);
}

/* return a template of (val-tolerance .. val+tolerance) ensuring it is within (min .. max) */
private function f_tolerance(integer val, integer min, integer max, integer tolerance)
return template integer {
	var template integer ret;
	ret := (f_tolerance_neg(val, min, tolerance) .. f_tolerance_pos(val, max, tolerance));
	return ret;
}


/* build a template for matching measurement results against */
private function f_build_meas_res_tmpl() runs on ConnHdlr return template RSL_Message {
	var ConnL1Pars l1p := g_pars.l1_pars;
	var template RSL_IE_UplinkMeas ul_meas := {
		len := 3,
		rfu := '0'B,
		dtx_d := l1p.dtx_enabled,
		rxlev_f_u := f_tolerance(l1p.meas_ul.full.rxlev, 0, 63, mp_tolerance_rxlev),
		reserved1 := '00'B,
		rxlev_s_u := f_tolerance(l1p.meas_ul.sub.rxlev, 0, 63, mp_tolerance_rxlev),
		reserved2 := '00'B,
		rxq_f_u := f_tolerance(l1p.meas_ul.full.rxqual, 0, 7, mp_tolerance_rxqual),
		rxq_s_u := f_tolerance(l1p.meas_ul.sub.rxqual, 0, 7, mp_tolerance_rxqual),
		supp_meas_info := omit
	};
	if (l1p.toa256_enabled) {
		ul_meas.len := (3+8);
		ul_meas.supp_meas_info := {
			toa256_mean := f_tolerance(l1p.timing_offset_256syms, -63*256, 192*256, mp_tolerance_timing_offset_256syms),
			toa256_min := ?,
			toa256_max := ?,
			toa256_std_dev := ?
		}
	}
	var template RSL_IE_BS_Power bs_power := {
		reserved := 0,
		epc := false,
		fpc := false,
		power_level := l1p.bs_power_level
	};
	var template RSL_IE_L1Info l1_info := {
		ms_power_lvl := l1p.ms_power_level,
		fpc := false,
		reserved := 0,
		actual_ta := f_tolerance(l1p.ms_actual_ta, 0, 63, mp_tolerance_timing_offset_256syms/256)
	};
	var uint8_t offs := toffs256s_to_rsl(l1p.timing_offset_256syms);
	var template uint8_t t_toffs := f_tolerance(offs, 0, 255, mp_tolerance_timing_offset_256syms/256);
	return tr_RSL_MEAS_RES_OSMO(g_chan_nr, g_next_meas_res_nr, ul_meas, bs_power, l1_info,
				    ?, t_toffs);
}

/* build a template for matching measurement results that do not contain any
 * MS related measurement (l1_info, l3_info and ms timing offset). */
private function f_build_meas_res_tmpl_empty() runs on ConnHdlr return template RSL_Message {
	var ConnL1Pars l1p := g_pars.l1_pars;
	var template RSL_IE_UplinkMeas ul_meas := {
		len := 3,
		rfu := '0'B,
		dtx_d := l1p.dtx_enabled,
		rxlev_f_u := ?,
		reserved1 := '00'B,
		rxlev_s_u := ?,
		reserved2 := '00'B,
		rxq_f_u := ?,
		rxq_s_u := ?,
		supp_meas_info := omit
	};
	if (l1p.toa256_enabled) {
		ul_meas.len := (3+8);
		ul_meas.supp_meas_info := {
			toa256_mean := f_tolerance(l1p.timing_offset_256syms, -63*256, 192*256, mp_tolerance_timing_offset_256syms),
			toa256_min := ?,
			toa256_max := ?,
			toa256_std_dev := ?
		}
	}
	var template RSL_IE_BS_Power bs_power := {
		reserved := 0,
		epc := false,
		fpc := false,
		power_level := l1p.bs_power_level
	};

	return tr_RSL_MEAS_RES_EMPTY(g_chan_nr, g_next_meas_res_nr, ul_meas, bs_power);
}

/* verify we regularly receive measurement reports with incrementing numbers */
private altstep as_meas_res(boolean verify_meas := true) runs on ConnHdlr {
	var RSL_Message rsl;
	var boolean chan_est := false;

	[not verify_meas] RSL.receive(tr_RSL_MEAS_RES(?)) { repeat; }

	/* Receive osmocom specific measurement reports. This is the normal
	 * case. Here we verify that the measurement reports we sent are
	 * comming back as we expect them. */
	[] RSL.receive(f_build_meas_res_tmpl()) -> value rsl {
		/* increment counter of next to-be-expected meas rep */
		g_next_meas_res_nr := (g_next_meas_res_nr + 1) mod 256;
		/* Re-start the timer expecting the next MEAS RES */
		f_timer_safe_restart(g_Tmeas_exp);

		/* The following two cases may only happen in the beginning
		 * of the channel establishment phase. Once we have received
		 * the "our" measurement report the first time, the channel
		 * is established and empty or hardcoded TRXCON reports must
		 * not occur anymore. */
		chan_est := true;

		repeat;
		}

	/* When the BTS has established the channel, the MS might need slightly
	 * more time to establish the channel and actually start sending. The
	 * result is then a measurement report that just lacks the measurement
	 * information of the MS. This is normal and we tolerate this behavior. */
	[chan_est == false] RSL.receive(f_build_meas_res_tmpl_empty()) -> value rsl {
		/* increment counter of next to-be-expected meas rep */
		g_next_meas_res_nr := (g_next_meas_res_nr + 1) mod 256;
		/* Re-start the timer expecting the next MEAS RES */
		f_timer_safe_restart(g_Tmeas_exp);
		repeat;
		}

	/* Due to the TDMA nature of GSM, TRXCON implements a way to emit dummy
	 * measurements if the TTCN3 side does not supply measurement input in
	 * time. In those cases TRXCON will either use a cached measurement
	 * report or a hardcoded one. If TRXCON picks the hardcoded measurement
	 * report the templates above will not match. We tolerate this
	 * behavior, but only once. */
	[chan_est == false] RSL.receive(tr_RSL_MEAS_RES(g_chan_nr, g_next_meas_res_nr)) -> value rsl {
		/* increment counter of next to-be-expected meas rep */
		g_next_meas_res_nr := (g_next_meas_res_nr + 1) mod 256;
		if (g_first_meas_res) {
			g_first_meas_res := false;
			repeat;
		} else {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Received unspecific MEAS RES ", rsl));
		}
		}
	[] RSL.receive(tr_RSL_MEAS_RES(?)) -> value rsl {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Received unexpected MEAS RES ", rsl));
		}
	[g_Tmeas_exp.running] g_Tmeas_exp.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Didn't receive expected measurement result")
		}
}

private function f_alg_id_to_l1ctl(RSL_AlgId rsl_alg_id) return uint8_t {
	select (rsl_alg_id) {
	case (RSL_ALG_ID_A5_0) { return 0; }
	case (RSL_ALG_ID_A5_1) { return 1; }
	case (RSL_ALG_ID_A5_2) { return 2; }
	case (RSL_ALG_ID_A5_3) { return 3; }
	case (RSL_ALG_ID_A5_4) { return 4; }
	case (RSL_ALG_ID_A5_5) { return 5; }
	case (RSL_ALG_ID_A5_6) { return 6; }
	case (RSL_ALG_ID_A5_7) { return 7; }
	case else {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Unknwon Algorithm ID");
		/* Make compiler happy by calling mtc.stop here. It is already
		 * called in f_shutdown */
		mtc.stop;
		}
	}
}

private function f_alg_id_to_l3(RSL_AlgId rsl_alg_id) return BIT3 {
	select (rsl_alg_id) {
	case (RSL_ALG_ID_A5_1) { return '000'B; }
	case (RSL_ALG_ID_A5_2) { return '001'B; }
	case (RSL_ALG_ID_A5_3) { return '010'B; }
	case (RSL_ALG_ID_A5_4) { return '011'B; }
	case (RSL_ALG_ID_A5_5) { return '100'B; }
	case (RSL_ALG_ID_A5_6) { return '101'B; }
	case (RSL_ALG_ID_A5_7) { return '110'B; }
	case else {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Unknwon Algorithm ID");
		/* Make compiler happy by calling mtc.stop here. It is already
		 * called in f_shutdown */
		mtc.stop;
		}
	}
}

/* Send RACH request through l1CTL and wait for ChanReq on RSL BST->BSC */
private function f_rach_req_wait_chan_rqd(integer ra) runs on ConnHdlr return GsmFrameNumber {
	var GsmFrameNumber fn;
	timer T := 8.0;

	/* advertise to RSL Emulation that we expect to receive confirmation from RACH */
	RSL.send(ts_RSLDC_ChanRqd_anyFN(int2oct(ra,1)));

	f_L1CTL_PARAM(L1CTL, g_pars.l1_pars.ms_actual_ta, g_pars.l1_pars.ms_power_level);
	/* Send the actual RACH */
	fn := f_L1CTL_RACH(L1CTL, ra);

	T.start;
	alt {
	[] RSL.receive(tr_RSL_CHAN_RQD(int2oct(ra,1), fn)) { setverdict(pass, "Received CHAN-RQD from RACH REQ") }
	[] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Timeout waiting for CHAN-RQD from RACH REQ <", ra, ", ", fn, ">"));
		}
	}
	T.stop
	return fn;
}

/* Tune to a dedicated channel: L1CTL only */
private function f_l1ctl_est_dchan(L1CTL_PT pt, ConnHdlrPars pars) {
	if (not pars.fhp.enabled) {
		var TrxParsItem trx_pars := mp_trx_pars[pars.trx_nr];
		pt.send(ts_L1CTL_DM_EST_REQ_H0(pars.chan_nr, pars.tsc,
						trx_pars.arfcn));
	} else {
		pt.send(ts_L1CTL_DM_EST_REQ_H1(pars.chan_nr, pars.tsc,
						pars.fhp.maio_hsn.hsn,
						pars.fhp.maio_hsn.maio,
						pars.fhp.ma));
	}
}

/* Establish dedicated channel: L1CTL + RSL side */
private function f_est_dchan(boolean encr_enable := false, RSL_IE_List more_ies := {}) runs on ConnHdlr {
	var ChannelDescription ch_desc;

	/* Activate channel on BTS side */
	f_rsl_chan_act(g_pars.chan_mode, encr_enable, more_ies);

	/* Craft channel description (with or without frequency hopping parameters) */
	if (g_pars.fhp.enabled) {
		ch_desc := valueof(ts_ChanDescH1(g_pars.chan_nr, g_pars.fhp.maio_hsn, g_pars.tsc));
	} else {
		var TrxParsItem trx_pars := mp_trx_pars[g_pars.trx_nr];
		ch_desc := valueof(ts_ChanDescH0(g_pars.chan_nr, trx_pars.arfcn, g_pars.tsc));
	}

	/* enable dedicated mode */
	f_l1ctl_est_dchan(L1CTL, g_pars);

	/* enable encryption, if requested */
	if (encr_enable) {
		var uint8_t alg_id := f_alg_id_to_l1ctl(g_pars.encr.alg_id);
		f_L1CTL_CRYPTO_REQ(L1CTL, g_pars.chan_nr, alg_id, g_pars.encr.key);
	}

	/* Send TCH Mode Request to the L1 if needed */
	if (match(g_pars.chan_mode.spd_ind, (RSL_SPDI_SPEECH, RSL_SPDI_DATA))) {
		var L1ctlTchMode tch_mode;
		var uint8_t amr_start_codec := 0;
		var BIT8 amr_codecs_bitmask := '00000000'B;

		select (g_pars.chan_mode) {
		case (tr_RSL_ChanMode_SIGN)
			{ tch_mode := L1CTL_CHAN_MODE_SIGN; }
		/* Speech modes */
		case (tr_RSL_ChanMode((RSL_CHRT_TCH_F, RSL_CHRT_TCH_H), RSL_CMOD_SP_GSM1))
			{ tch_mode := L1CTL_CHAN_MODE_SPEECH_V1; }
		case (tr_RSL_ChanMode((RSL_CHRT_TCH_F, RSL_CHRT_TCH_H), RSL_CMOD_SP_GSM2))
			{ tch_mode := L1CTL_CHAN_MODE_SPEECH_V2; }
		case (tr_RSL_ChanMode((RSL_CHRT_TCH_F, RSL_CHRT_TCH_H), RSL_CMOD_SP_GSM3))
			{ tch_mode := L1CTL_CHAN_MODE_SPEECH_V3;
			  amr_codecs_bitmask := g_pars.mr_conf.codec_modes; }
		/* Data modes */
		case (tr_RSL_ChanMode_DATA(RSL_CHRT_TCH_F, /* TCH/F14.4 */
					   (RSL_CMOD_CSD_T_14k4, RSL_CMOD_CSD_NT_14k5)))
			{ tch_mode := L1CTL_CHAN_MODE_DATA_14k5; }
		case (tr_RSL_ChanMode_DATA(RSL_CHRT_TCH_F, /* TCH/F9.6 */
					   (RSL_CMOD_CSD_T_9k6, RSL_CMOD_CSD_NT_12k0)))
			{ tch_mode := L1CTL_CHAN_MODE_DATA_12k0; }
		case (tr_RSL_ChanMode_DATA((RSL_CHRT_TCH_F, RSL_CHRT_TCH_H), /* TCH/[FH]4.8 */
					   (RSL_CMOD_CSD_T_4k8, RSL_CMOD_CSD_NT_6k0)))
			{ tch_mode := L1CTL_CHAN_MODE_DATA_6k0; }
		case (tr_RSL_ChanMode_DATA((RSL_CHRT_TCH_F, RSL_CHRT_TCH_H), /* TCH/[FH]2.4 */
					   (RSL_CMOD_CSD_T_2k4, RSL_CMOD_CSD_T_1k2,
					    RSL_CMOD_CSD_T_600, RSL_CMOD_CSD_T_1200_75)))
			{ tch_mode := L1CTL_CHAN_MODE_DATA_3k6; }
		case else {
			log("RSL channel mode is not supported by the L1, falling back to signalling");
			tch_mode := L1CTL_CHAN_MODE_SIGN;
			}
		}

		f_L1CTL_TCH_MODE(L1CTL,
				 ts_L1CTL_TCH_MODE_REQ(tch_mode,
						       amr_start_codec := amr_start_codec,
						       amr_codecs_bitmask := amr_codecs_bitmask));
	}

	g_first_meas_res := true;
}

private function get_start_amr_ft() runs on ConnHdlr return integer {
	var integer start_nth;
	if (g_pars.mr_conf.icmi) {
		start_nth := 0; /* FIXME: implement 3GPP TS 45.009 3.4.3 */
	} else {
		start_nth := g_pars.mr_conf.start_mode;
	}

	var integer n := 0;
	for (var integer i:= 7; i >= 0; i := i - 1) {
		if (g_pars.mr_conf.codec_modes[i] == '1'B) {
			if (n == start_nth) {
				return 7 - i;
			}
			n := n + 1;
		}
	}
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
			        log2str("mr_conf is wrong! ", g_pars.mr_conf));
	return 0;
}

/* Initialize and start the RTP emulation component for a ConnHdlr */
friend function f_rtpem_activate(inout octetstring payload,
				 RtpemConfig cfg := c_RtpemDefaultCfg,
				 RtpemMode mode := RTPEM_MODE_BIDIR)
runs on ConnHdlr {
	/* Step 0: initialize, connect and start the emulation component */
	vc_RTPEM := RTP_Emulation_CT.create(testcasename() & "-RTPEM");
	map(vc_RTPEM:RTP, system:RTP);
	map(vc_RTPEM:RTCP, system:RTCP);
	connect(vc_RTPEM:CTRL, self:RTPEM_CTRL);
	connect(vc_RTPEM:DATA, self:RTPEM_DATA);
	vc_RTPEM.start(RTP_Emulation.f_main());

	/* Step 1: configure the RTP parameters */
	var integer payload_len := 0;
	var octetstring hdr := ''O;
	var OCT1 pad := '00'O;

	select (g_pars.chan_mode) {
	case (tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM1)) /* TCH/FS */
		{ payload_len := 33; hdr := 'D0'O; pad := 'FF'O; }
	case (tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM1)) /* TCH/HS */
		{ payload_len := 15; hdr := '00'O; }
	case (tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM2)) /* TCH/EFS */
		{ payload_len := 31; hdr := 'C0'O; }
	case (tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM3)) /* TCH/AFS */
		{
			var integer amr_ft := get_start_amr_ft();
			payload_len := f_amrft_payload_len(amr_ft) + 2;
			hdr := enc_RTP_AMR_Hdr(valueof(ts_RTP_AMR_Hdr(amr_ft, amr_ft, '1'B)));
		}
	case (tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM3)) /* TCH/AHS */
		{
			var integer amr_ft := get_start_amr_ft();
			payload_len := f_amrft_payload_len(amr_ft) + 2;
			hdr := enc_RTP_AMR_Hdr(valueof(ts_RTP_AMR_Hdr(amr_ft, amr_ft, '1'B)));
		}
	case else {
		setverdict(fail, "Unhandled RSL channel mode := ", g_pars.chan_mode);
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
		}
	}

	/* Pad the payload to conform the expected length */
	payload := f_pad_oct(hdr & payload, payload_len, pad);
	cfg.tx_payloads[0].fixed_payload := payload;
	f_rtpem_configure(RTPEM_CTRL, cfg);

	/* Step 2: bind the RTP emulation to the configured address */
	var PortNumber rtpem_bind_port := mp_rtpem_bind_port;
	f_rtpem_bind(RTPEM_CTRL, mp_rtpem_bind_ip, rtpem_bind_port);

	/* Step 3a: send CRCX to create an RTP connection at the IUT */
	var RSL_Message crcx_ack := f_rsl_transceive_ret(
		/* FIXME (OS#5242): do not include Remote IP/Port IEs because
		 * osmo-bts would respond with nonsense listen addr='0.0.0.0'. */
		ts_RSL_IPA_CRCX(g_chan_nr, omit, omit),
		tr_RSL_IPA_CRCX_ACK(g_chan_nr, ?, ?, ?, omit),
		"IPA CRCX ACK");
	var uint16_t conn_id := crcx_ack.ies[1].body.ipa_conn_id;

	/* Step 3b: send MDCX with the configured address/port to the IUT */
	var RSL_Message mdcx_ack := f_rsl_transceive_ret(
		ts_RSL_IPA_MDCX(g_chan_nr, conn_id,
				remote_ip := f_inet_addr(mp_rtpem_bind_ip),
				remote_port := rtpem_bind_port,
				rtp_pt2 := 0),
		tr_RSL_IPA_MDCX_ACK(g_chan_nr, conn_id, ?, ?, ?),
		"IPA MDCX ACK");

	/* Step 4: connect to the IUT's address/port parsed from MDCX ACK */
	var HostName bts_bind_ip := f_inet_ntoa(mdcx_ack.ies[2].body.ipa_local_ip);
	var PortNumber bts_bind_port := mdcx_ack.ies[3].body.ipa_local_port;
	f_rtpem_connect(RTPEM_CTRL, bts_bind_ip, bts_bind_port);

	/* Step 5: set the given RTP emulation mode */
	f_rtpem_mode(RTPEM_CTRL, mode);
}

/* Initialize and start the RTP emulation component for a ConnHdlr */
friend function f_osmuxem_activate(inout octetstring payload,
				 OsmuxemConfig cfg := c_OsmuxemDefaultCfg,
				 OsmuxemMode mode := OSMUXEM_MODE_BIDIR)
runs on ConnHdlr {
	var RSL_IE_Body ie;
	var OsmuxTxHandle tx_hdl;
	var OsmuxRxHandle rx_hdl;
	/* Step 0: initialize, connect and start the emulation component */
	vc_OsmuxEM := OSMUX_Emulation_CT.create(testcasename() & "-OsmuxEM");
	map(vc_OsmuxEM:OSMUX, system:OSMUX);
	connect(vc_OsmuxEM:CTRL, self:OsmuxEM_CTRL);
	connect(vc_OsmuxEM:DATA, self:OsmuxEM_DATA);
	vc_OsmuxEM.start(OSMUX_Emulation.f_main());

	/* Step 1: configure the RTP parameters */
	var integer payload_len := 31;
	var octetstring hdr := ''O;

	/* Pad the payload to conform the expected length */
	payload := f_pad_oct(hdr & payload, payload_len, '00'O);
	cfg.tx_fixed_payload := payload;
	f_osmuxem_configure(OsmuxEM_CTRL, cfg);

	/* Step 2: bind the RTP emulation to the configured address */
	var PortNumber osmuxem_bind_port := mp_osmuxem_bind_port;
	f_osmuxem_bind(OsmuxEM_CTRL, mp_osmuxem_bind_ip, osmuxem_bind_port);
	rx_hdl := c_OsmuxemDefaultRxHandle;
	rx_hdl.cid := g_pars.loc_osmux_cid;
	f_osmuxem_register_rxhandle(OsmuxEM_CTRL, rx_hdl);

	/* Step 3a: send CRCX to create an RTP connection at the IUT */
	var RSL_Message crcx_ack := f_rsl_transceive_ret(
		/* FIXME (OS#5242): do not include Remote IP/Port IEs because
		 * osmo-bts would respond with nonsense listen addr='0.0.0.0'. */
		ts_RSL_IPA_CRCX(g_chan_nr, omit, omit, g_pars.loc_osmux_cid),
		tr_RSL_IPA_CRCX_ACK(g_chan_nr, ?, ?, ?, ?),
		"IPA CRCX ACK");
	var uint16_t conn_id := crcx_ack.ies[1].body.ipa_conn_id;
	f_rsl_find_ie(crcx_ack, RSL_IE_OSMO_OSMUX_CID, ie);
	g_pars.rem_osmux_cid := ie.osmux_cid.cid;


	/* Step 3b: send MDCX with the configured address/port to the IUT */
	var RSL_Message mdcx_ack := f_rsl_transceive_ret(
		ts_RSL_IPA_MDCX(g_chan_nr, conn_id,
				remote_ip := f_inet_addr(mp_osmuxem_bind_ip),
				remote_port := osmuxem_bind_port,
				rtp_pt2 := 0,
				osmux_cid := g_pars.loc_osmux_cid),
		tr_RSL_IPA_MDCX_ACK(g_chan_nr, conn_id, ?, ?, ?, g_pars.rem_osmux_cid),
		"IPA MDCX ACK");

	tx_hdl := valueof(t_TxHandleAMR590(g_pars.rem_osmux_cid));
	f_osmuxem_register_txhandle(OsmuxEM_CTRL, tx_hdl);

	/* Step 4: connect to the IUT's address/port parsed from MDCX ACK */
	var HostName bts_bind_ip := f_inet_ntoa(mdcx_ack.ies[2].body.ipa_local_ip);
	var PortNumber bts_bind_port := mdcx_ack.ies[3].body.ipa_local_port;
	f_osmuxem_connect(OsmuxEM_CTRL, bts_bind_ip, bts_bind_port);

	/* Step 5: set the given RTP emulation mode */
	f_osmuxem_mode(OsmuxEM_CTRL, mode);
}

/* establish DChan, verify existance + contents of measurement reports */
private function f_TC_meas_res_periodic(charstring id) runs on ConnHdlr {
	f_l1_tune(L1CTL);
	RSL.clear;

	if (mp_bts_trxc_port != -1) {
		f_trxc_fake_rssi(rxlev2dbm(mp_ul_rxlev_exp));
		f_trxc_fake_toffs256(g_pars.l1_pars.timing_offset_256syms);
	}

	f_est_dchan();

	/* run for a number of seconds, send SACCH + FACCH from MS side and verify
	 * RSL measurement reports on Abis side */
	timer T := 8.0;
	T.start;
	alt {
	[] as_l1_sacch();
	[] as_meas_res();
	[] as_l1_dcch_loop();
	[] as_l1_tch_loop();
	[] L1CTL.receive { repeat; }
	[g_Tmeas_exp.running] T.timeout {
		/* as_meas_res() would have done Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail) in case
		 * of any earlier errors, so if we reach this timeout, we're good */
		setverdict(pass);
		}
	[] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "No MEAS RES received at all");
		}
	}
	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
}

/* Wait until the BTS has reached full tx power (nominal tx power minus configured attenuation) */
private function f_wait_ramp_up() runs on ConnHdlr return integer {
	var L1ctlMessage l1_dl;
	var integer max_rx_lvl := mp_bts_tx_nom_pwr_exp - mp_bts_tx_pwr_att_exp;
	timer Tup := 10.0;
	Tup.start;
	alt {
	[] L1CTL.receive(tr_L1CTL_DATA_IND(t_RslChanNr_BCCH(0), ?)) -> value l1_dl {
		var GsmRxLev rx_lvl := l1_dl.dl_info.rx_level;
		log("Received rx_level=", rx_lvl);

		if (rx_lvl != max_rx_lvl) {
			repeat;
		}
		Tup.stop;
		}
	[] L1CTL.receive { repeat; }
	[] Tup.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
					log2str("Didn't reach full power ", max_rx_lvl));
		}
	}
	return max_rx_lvl;
}

/* verify BTS ramps power up to full tx power (nominal tx power minus configured attenuation) */
private function f_verify_ramp_up() runs on ConnHdlr {
	var L1ctlMessage l1_dl;
	var integer initial_rx_lvl := -1;
	var integer last_rx_lvl := -1;
	var integer max_rx_lvl := mp_bts_tx_nom_pwr_exp - mp_bts_tx_pwr_att_exp;

	timer T := 2.0;
	alt {
	[] L1CTL.receive(tr_L1CTL_DATA_IND(t_RslChanNr_BCCH(0), ?)) -> value l1_dl {
		var GsmRxLev rx_lvl := l1_dl.dl_info.rx_level;
		log("Received rx_level=", rx_lvl);
		if (initial_rx_lvl == -1) {
			initial_rx_lvl := rx_lvl;
			last_rx_lvl := rx_lvl;

			/* Expect a somehow low value during first received messages */
			if (initial_rx_lvl >= max_rx_lvl / 2) {
				Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
							log2str("Detected high initial tx power during ramp up: ",
								initial_rx_lvl , ", full power is", max_rx_lvl));
			}
		}

		/* received Rx level bigger than maximum allowed power by CN */
		if (rx_lvl > max_rx_lvl) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
						log2str("Detected Tx power higher than full power: ",
							rx_lvl , " > ", max_rx_lvl));
		}

		/* Make sure it never decreases, since we are rumping up */
		if (last_rx_lvl > rx_lvl) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
						log2str("Detected Tx power decrease during ramp up: ",
							last_rx_lvl , " -> ", rx_lvl));
		}

		if (rx_lvl == max_rx_lvl and not T.running) {
			/* We reached the maximum power, start timer and receive
			/* a few more to make sure we don't surpass it */
			log("Reached full power, wating a bit more until success");
			T.start;
		}

		last_rx_lvl := rx_lvl;
		repeat;
		}
	[] L1CTL.receive { repeat; }
	[] T.timeout { }
	}

	/* We didn't increase tx power during ramp up */
	if (initial_rx_lvl < last_rx_lvl) {
		log("Tx power increased during ramp up: ", initial_rx_lvl , " -> ", last_rx_lvl);
	} else {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
					log2str("No Tx power increase during whole ramp up: ",
						initial_rx_lvl , " -> ", last_rx_lvl));
	}
}

/* verify BTS ramps power down to rx_level 0 */
private function f_verify_ramp_down(integer max_rx_lvl) runs on ConnHdlr {
	var L1ctlMessage l1_dl;
	var integer last_rx_lvl := max_rx_lvl;

	timer Tdown := 5.0;
	Tdown.start;
	alt {
	[] L1CTL.receive(tr_L1CTL_DATA_IND(t_RslChanNr_BCCH(0), ?)) -> value l1_dl {
		var GsmRxLev rx_lvl := l1_dl.dl_info.rx_level;
		log("Received rx_level=", rx_lvl);

		/* received Rx level bigger than maximum allowed power by CN */
		if (rx_lvl > max_rx_lvl) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
						log2str("Detected Tx power higher than full power: ",
							rx_lvl , " > ", max_rx_lvl));
		}

		/* Make sure it never increases, since we are rumping down */
		if (last_rx_lvl < rx_lvl) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
						log2str("Detected Tx power increase during ramp up: ",
							last_rx_lvl , " -> ", rx_lvl));
		}

		last_rx_lvl := rx_lvl;
		if (last_rx_lvl != 0) {
			repeat;
		}
		/* we reached power level 0, we are done */
		Tdown.stop;
		}
	[] L1CTL.receive { repeat; }
	[] Tdown.timeout { }
	}

	/* We didn't increase tx power during ramp down */
	if (max_rx_lvl > last_rx_lvl) {
		log("Tx power decreased during ramp down: ", max_rx_lvl , " -> ", last_rx_lvl);
	} else {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
					log2str("No Tx power decrease during whole ramp down: ",
						max_rx_lvl , " -> ", last_rx_lvl));
	}
}

/* verify BTS power down to rx_level 0 without ramping */
private function f_verify_power_down(integer max_rx_lvl) runs on ConnHdlr {
	var L1ctlMessage l1_dl;
	var boolean first_data_ind := true;

	timer Tdown := 5.0;
	Tdown.start;
	alt {
	[first_data_ind == true] L1CTL.receive(tr_L1CTL_DATA_IND(t_RslChanNr_BCCH(0), ?)) -> value l1_dl {
		first_data_ind := false;
		var GsmRxLev rx_lvl := l1_dl.dl_info.rx_level;
		log("Received rx_level=", rx_lvl);

		/* The first data indication could still have the original power level */
		if (rx_lvl != 0 and rx_lvl != max_rx_lvl) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
						log2str("Detected Tx power: ",
							rx_lvl , " should be 0 or ", max_rx_lvl));
		}
		repeat;
	}
	[first_data_ind == false] L1CTL.receive(tr_L1CTL_DATA_IND(t_RslChanNr_BCCH(0), ?)) -> value l1_dl {
		var GsmRxLev rx_lvl := l1_dl.dl_info.rx_level;
		log("Received rx_level=", rx_lvl);

		/* Expect immediate power off so either rx_level == 0 or no report at all
		   because TRX was shut down already */
		if (rx_lvl != 0) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
						log2str("Detected Tx power: ",
							rx_lvl , " should be 0"));
		}

		repeat;
		}
	[] L1CTL.receive { repeat; }
	[] Tdown.timeout { }
	}
}

/* Verify Tx power reduction and ramping up during BTS bring up */
private function f_TC_tx_power_start_ramp_up_bcch(charstring id) runs on ConnHdlr {
	f_l1_tune(L1CTL);
	RSL.clear;

	f_verify_ramp_up();

	setverdict(pass);
}
testcase TC_tx_power_start_ramp_up_bcch() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;
	f_init();
	pars := valueof(t_Pars(t_RslChanNr_Bm(0), ts_RSL_ChanMode_SIGN));
	vc_conn := f_start_handler(refers(f_TC_tx_power_start_ramp_up_bcch), pars,
				   pcu_comp := false, trxc_comp := true);
	vc_conn.done;
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/* Verify Tx power reduction without ramping down during BTS shutdown due to Abis link failure */
private function f_TC_tx_power_down_bcch(charstring id) runs on ConnHdlr {
	f_connhdlr_init_vty_bsc();

	f_l1_tune(L1CTL);
	RSL.clear;

	/* Wait until BTS is started and at full power */
	var integer max_rx_lvl := f_wait_ramp_up();
	log("Reached nominal level ", max_rx_lvl, ", shutting down OML link");

	f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
	f_verify_power_down(max_rx_lvl);

	setverdict(pass);
}
testcase TC_tx_power_down_bcch() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;
	f_init();
	pars := valueof(t_Pars(t_RslChanNr_Bm(0), ts_RSL_ChanMode_SIGN));
	vc_conn := f_start_handler(refers(f_TC_tx_power_down_bcch), pars,
				   pcu_comp := false, trxc_comp := true);
	vc_conn.done;
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/* Verify Tx power:
 * + ramping down during ADM state UNLOCKED->LOCKED
 * + ramping up during ADM state LOCKED->UNLOCKED
 */
private function f_TC_tx_power_ramp_adm_state_change(charstring id) runs on ConnHdlr {
	var L1ctlMessage l1_dl;
	var integer last_rx_lvl;

	f_connhdlr_init_vty_bsc();

	f_l1_tune(L1CTL);
	RSL.clear;

	/* Wait until BTS is started and at full power */
	var integer max_rx_lvl := f_wait_ramp_up();
	log("Reached nominal level ", max_rx_lvl, ", changing ADM state to LOCKED");

	log("ADM STATE UNLOCKED->LOCKED");
	f_vty_enter_cfg_trx(BSCVTY);
	f_vty_transceive(BSCVTY, "rf_locked 1");
	last_rx_lvl := max_rx_lvl;
	f_verify_ramp_down(max_rx_lvl);

	/* Let some time after we received 0dBm, then check we don't receive BCCH
	 * anymore because scheduler has stopped after ramping down */
	f_sleep(2.0);
	L1CTL.clear;
	timer Tlocked := 2.0;
	Tlocked.start;
	alt {
	[] L1CTL.receive(tr_L1CTL_DATA_IND(t_RslChanNr_BCCH(0), ?)) -> value l1_dl {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
					log2str("Received data_ind during rf_locked: ", l1_dl));
		}
	[] L1CTL.receive { repeat; }
	[] Tlocked.timeout { setverdict(pass, "Didn't receive data_ind while in rf_locked state."); }
	}

	log("ADM STATE LOCKED->UNLOCKED");
	f_vty_transceive(BSCVTY, "rf_locked 0");
	f_verify_ramp_up();
	setverdict(pass);
}
testcase TC_tx_power_ramp_adm_state_change() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;
	f_init();
	pars := valueof(t_Pars(t_RslChanNr_Bm(0), ts_RSL_ChanMode_SIGN));
	vc_conn := f_start_handler(refers(f_TC_tx_power_ramp_adm_state_change), pars,
				   pcu_comp := false, trxc_comp := true);
	vc_conn.done;
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

private function f_check_meas_bs_power_level(integer level) runs on ConnHdlr {
	timer T := 8.0;
	T.start;
	var RSL_Message rsl;
	alt {
	[] as_l1_sacch();
	[] L1CTL.receive { repeat; }
	[] RSL.receive(tr_RSL_MEAS_RES(g_chan_nr, ?, ?, ?)) -> value rsl {
		if (rsl.ies[3].body.bs_power.power_level == level) {
			setverdict(pass)
		} else {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Received wrong BS power level in MEAS RES ", rsl));
		}
		}
	[] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "No MEAS RES received at all");
		}
	}
}

/* See if the RSL MEASurement RESult contains expeced BS power level
 * set  _during_ the CHANnel ACTIVation procedure. */
private function f_TC_rsl_bs_pwr_static_ass(charstring id) runs on ConnHdlr {
	f_l1_tune(L1CTL);
	RSL.clear;

	if (mp_bts_trxc_port != -1) {
		f_trxc_fake_rssi(rxlev2dbm(mp_ul_rxlev_exp));
		f_trxc_fake_toffs256(g_pars.l1_pars.timing_offset_256syms);
	}

	var uint4_t pwr_var := 1;
	var template (value) RSL_IE_BS_Power bs_power := ts_RSL_IE_BS_Power(pwr_var);
	var template (value) RSL_IE pwr := t_RSL_IE(RSL_IE_BS_POWER, RSL_IE_Body:{bs_power := bs_power});

	f_est_dchan(more_ies :={valueof(pwr)});

	f_check_meas_bs_power_level(pwr_var);

	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
}

/* See if the RSL MEASurement RESult contains expeced BS power level
 * set  _after_ the CHANnel ACTIVation procedure. */
private function f_TC_rsl_bs_pwr_static_power_control(charstring id) runs on ConnHdlr {
	f_l1_tune(L1CTL);
	RSL.clear;

	if (mp_bts_trxc_port != -1) {
		f_trxc_fake_rssi(rxlev2dbm(mp_ul_rxlev_exp));
		f_trxc_fake_toffs256(g_pars.l1_pars.timing_offset_256syms);
	}

	var uint4_t pwr_var := 1;
	var template (value) RSL_IE_BS_Power bs_power := ts_RSL_IE_BS_Power(pwr_var);

	f_est_dchan();

	RSL.send(ts_RSL_BS_PWR_CTRL(g_chan_nr, bs_power));

	f_check_meas_bs_power_level(pwr_var);

	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
}

testcase TC_rsl_bs_pwr_static_ass() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;

	f_init();

	pars := valueof(t_Pars(t_RslChanNr_Bm(0), ts_RSL_ChanMode_SIGN, trx_nr := 1));
	vc_conn := f_start_handler(refers(f_TC_rsl_bs_pwr_static_ass), pars,
				   pcu_comp := false, trxc_comp := true);
	vc_conn.done;

	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

testcase TC_rsl_bs_pwr_static_power_control() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;

	f_init();

	pars := valueof(t_Pars(t_RslChanNr_Bm(0), ts_RSL_ChanMode_SIGN, trx_nr := 1));
	vc_conn := f_start_handler(refers(f_TC_rsl_bs_pwr_static_power_control), pars,
				   pcu_comp := false, trxc_comp := true);
	vc_conn.done;

	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/* Target level -100, first rssi -90, ms power 7, expected increase to 7+6 within 6 seconds,
 * second rssi -110, ms power 7+6, expected decrease to 7 within 6 seconds.
 * These power levels are valid for all bands and require no special handling. */
private function f_TC_rsl_ms_pwr_dyn_ass_updown(charstring id) runs on ConnHdlr {
	var uint5_t pwr_var := 7;
	var SacchL1Header l1h;

	f_trxc_fake_rssi(rxlev2dbm(10));
	f_l1_tune(L1CTL);
	RSL.clear;

	var RSL_IE_List addl_ies;
	var template (value)  RSL_IE_MS_Power_Parameters pp := (ts_RSL_IE_MS_Power_Parameters(''O));

	addl_ies := {
		valueof(t_RSL_IE(RSL_IE_MS_POWER, RSL_IE_Body:{ms_power := ts_RSL_IE_MS_Power(pwr_var)})),
		valueof(t_RSL_IE(RSL_IE_MS_POWER_PARAM, RSL_IE_Body:{ms_power_params := pp}))
	};

	/* establish with power parameters */
	f_est_dchan(more_ies := addl_ies);

	/* set a high value to ensure L1 power control level increases */
	f_trxc_fake_rssi(rxlev2dbm(20));

	timer T2 := 6.0;
	T2.start;
	alt {
	[] as_l1_sacch_l1h(l1h) {
		f_send_meas_rep_l1h(ts_MeasurementResults, l1h);

		if (l1h.ms_power_lvl < (pwr_var + 6)) {
			repeat;
		}
		T2.stop;
		}
	[] L1CTL.receive { repeat; }
	[] T2.timeout {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
			"Power Level in L1 header has not increased sufficiently");
		}
	}

	/* set a low value to ensure L1 power control level decreases */
	f_trxc_fake_rssi(rxlev2dbm(0));

	timer T4 := 6.0;
	T4.start;
	alt {
	[] as_l1_sacch_l1h(l1h) {
		f_send_meas_rep_l1h(ts_MeasurementResults, l1h);

		if (l1h.ms_power_lvl > pwr_var) {
			repeat;
		}
		T4.stop;
		setverdict(pass, "Power level in L1 decreased/increased as expected");
		}
	[] L1CTL.receive { repeat; }
	[] T4.timeout {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
			"Power Level in L1 header has not decreased sufficiently");
		}
	}

	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);

}

/* check that we do not exceed the max power */
private function f_TC_rsl_ms_pwr_dyn_max(charstring id) runs on ConnHdlr {
	var uint5_t pwr_var := 7;
	var SacchL1Header l1h;

	/* set a low value to ensure power increases */
	f_trxc_fake_rssi(rxlev2dbm(10));
	f_l1_tune(L1CTL);
	RSL.clear;

	var RSL_IE_List addl_ies;
	var template (value)  RSL_IE_MS_Power_Parameters pp := (ts_RSL_IE_MS_Power_Parameters(''O));

	addl_ies := {
		valueof(t_RSL_IE(RSL_IE_MS_POWER, RSL_IE_Body:{ms_power := ts_RSL_IE_MS_Power(pwr_var)})),
		valueof(t_RSL_IE(RSL_IE_MS_POWER_PARAM, RSL_IE_Body:{ms_power_params := pp}))
	};

	/* establish with power parameters */
	f_est_dchan(more_ies := addl_ies);

	timer T1 := 10.0;
	T1.start;
	alt {
	[] as_l1_sacch_l1h(l1h) {
		f_send_meas_rep_l1h(ts_MeasurementResults, l1h);
		repeat;
		}
	[] L1CTL.receive { repeat; }
	[] T1.timeout {
		if (not isbound(l1h)) {
			setverdict(fail, "No SACCH blocks were received");
		} else if (l1h.ms_power_lvl != pwr_var) {
			setverdict(fail, "Power level in L1 header should not have changed");
		}
		}
	}

	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);

}

/* see if we reach the band max power */
private function f_TC_rsl_ms_pwr_dyn_up(charstring id) runs on ConnHdlr {
	var SacchL1Header l1h;
	var uint5_t pwr_var := 15;
	var uint5_t pwr_max_var := f_get_max_power_from_band();

	/* set a low value to ensure power increases */
	f_trxc_fake_rssi(rxlev2dbm(10));
	f_l1_tune(L1CTL);
	RSL.clear;

	var template (value) RSL_IE_MS_Power ms_power := ts_RSL_IE_MS_Power(pwr_var);
	var template (value) RSL_IE pwr := t_RSL_IE(RSL_IE_MS_POWER, RSL_IE_Body:{ms_power := ms_power});

	/* establish with fixed power level */
	f_est_dchan(more_ies :={valueof(pwr)});

	/* check our initial power level */
	f_wait_for_l1_power_level(pwr_var);

	/* update power param to enable power loop
	48.058 The maximum power to be used is indicated in the BS and MS Power elements respectively. */
	RSL.send(ts_RSL_MS_PWR_CTRL_with_pp(g_chan_nr, pwr_max_var));

	/* By default, the MS power loop gets triggered every 4th SACCH block (1.92s).
	 * We need 9 * 4 dB steps to get from 0 dBm to 33 dBm, so 9 * 1.92s total.
	 * Add an extra offset to avoid race conditions: +1.92s. */
	timer T1 := 9.0 * 1.92 + 1.92;
	T1.start;
	alt {
	[] as_l1_sacch_l1h(l1h) {
		f_send_meas_rep_l1h(ts_MeasurementResults, l1h);
		repeat;
		}
	[] L1CTL.receive { repeat; }
	[] T1.timeout {
		if (not isbound(l1h)) {
			setverdict(fail, "No SACCH blocks were received");
		} else if (f_power_level_is_highest_dbm(l1h.ms_power_lvl)) {
			setverdict(pass, "Power level in L1 header reduced as expected");
		} else {
			setverdict(fail, "Power level := ", l1h.ms_power_lvl, " did not ",
				   "reach the expected value := ", pwr_max_var);
		}
		}
	}

	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);

}

/* see if we reach the band min power */
private function f_TC_rsl_ms_pwr_dyn_down(charstring id) runs on ConnHdlr {
	var SacchL1Header l1h;

	/* set a high value to ensure power decreases */
	f_trxc_fake_rssi(rxlev2dbm(50));
	f_l1_tune(L1CTL);
	RSL.clear;

	var uint5_t pwr_var := 5;
	var uint5_t pwr_target_val := 15;

	var template (value) RSL_IE_MS_Power ms_power := ts_RSL_IE_MS_Power(pwr_var);
	var template (value) RSL_IE pwr := t_RSL_IE(RSL_IE_MS_POWER, RSL_IE_Body:{ms_power := ms_power});

	/* establish with fixed power level */
	f_est_dchan(more_ies :={valueof(pwr)});

	/* check our initial power level */
	f_wait_for_l1_power_level(pwr_var);

	/* update power param to enable power loop
	 as per spec the supplied ms power IE should set the max allowed power...*/
	RSL.send(ts_RSL_MS_PWR_CTRL_with_pp(g_chan_nr, pwr_target_val));

	/* wait, then check that our power level was increased */
	timer T1 := 10.0;
	T1.start;
	alt {
	[] as_l1_sacch_l1h(l1h) { repeat; }
	[] L1CTL.receive { repeat; }
	[] T1.timeout {
		if (not isbound(l1h)) {
			setverdict(fail, "No SACCH blocks were received");
		} else if (f_power_level_is_lowest_dbm(l1h.ms_power_lvl)) {
			setverdict(pass, "Power level increased to lowest power value");
		} else {
			setverdict(fail, "Power level NOT increased to lowest power value");
		}
		}
	}

	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);

}

/* See if the power level remains constant when MS Power Parameters IE
 * is _absent_ in the CHANnel ACTIVation message. */
private function f_TC_rsl_ms_pwr_dyn_active(charstring id) runs on ConnHdlr {
	var SacchL1Header l1h;

	/* set a high value to ensure power decreases */
	f_trxc_fake_rssi(rxlev2dbm(50));
	f_l1_tune(L1CTL);
	RSL.clear;

	var uint5_t pwr_var := 5;

	var template (value) RSL_IE_MS_Power ms_power := ts_RSL_IE_MS_Power(pwr_var);
	var template (value) RSL_IE pwr := t_RSL_IE(RSL_IE_MS_POWER, RSL_IE_Body:{ms_power := ms_power});

	/* establish with fixed power level */
	f_est_dchan(more_ies :={valueof(pwr)});

	/* check our initial power level */
	f_wait_for_l1_power_level(pwr_var);

	/* wait, then check that our power level did not change */
	timer T1 := 10.0;
	T1.start;
	alt {
	[] as_l1_sacch_l1h(l1h, do_apply := false) {
		if (l1h.ms_power_lvl != pwr_var) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
			"BS power control should not be active unless we receive a power parameters IE!");
		}
		repeat;
		}
	[] L1CTL.receive { repeat; }
	[] T1.timeout { setverdict(pass); }
	}

	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);

}

/* See if the power level remains constant when MS Power Parameters IE
 * is _absent_ in the CHANnel ACTIVation and MS Power Control messages. */
private function f_TC_rsl_ms_pwr_dyn_active2(charstring id) runs on ConnHdlr {
	var SacchL1Header l1h;

	/* set a high value to ensure power decreases */
	f_trxc_fake_rssi(rxlev2dbm(50));
	f_l1_tune(L1CTL);
	RSL.clear;

	var uint5_t pwr_var := 5;

	var template (value) RSL_IE_MS_Power ms_power := ts_RSL_IE_MS_Power(pwr_var);
	var template (value) RSL_IE pwr := t_RSL_IE(RSL_IE_MS_POWER, RSL_IE_Body:{ms_power := ms_power});

	/* establish with fixed power level */
	f_est_dchan(more_ies :={valueof(pwr)});

	/* check our initial power level */
	f_wait_for_l1_power_level(pwr_var);

	/* pwr control without power params IE, should NOT activate MS power control*/
	RSL.send(ts_RSL_MS_PWR_CTRL(g_chan_nr, ms_power));

	/* wait, then check that our power level did not change */
	timer T1 := 10.0;
	T1.start;
	alt {
	[] as_l1_sacch_l1h(l1h, do_apply := false) {
		if (l1h.ms_power_lvl != pwr_var) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
			"BS power control should not be active unless we receive a power parameters IE!");
		}
		repeat;
		}
	[] L1CTL.receive { repeat; }
	[] T1.timeout { setverdict(pass); }
	}

	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);

}

private function f_wait_for_l1_power_level(integer level) runs on ConnHdlr {
	var SacchL1Header l1h;
	timer T0 := 10.0;
	T0.start;
	alt {
	[] as_l1_sacch_l1h(l1h, do_apply := false) {
		if (l1h.ms_power_lvl != level) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
			"Power level in L1 header != signaled (RSL) power level.");
		}
		}
	[] L1CTL.receive { repeat; }
	[] T0.timeout {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
			"Timeout waiting for initial power level");
		}
	}
	T0.stop;
}

private function f_power_level_is_lowest_dbm(integer level) runs on ConnHdlr return boolean  {
	var IntegerRecord min_dbm_level;
	var IntegerRecord max_dbm_level;
	var IntegerRecord x := f_power_from_band(g_pars.bts0_band, min_dbm_level, max_dbm_level);

	for (var integer i := 0; i < sizeof(min_dbm_level); i := i+1) {
		if (min_dbm_level[i] == level) {
			return true;
		}
	}
	return false;
}

private function f_power_level_is_highest_dbm(integer level) runs on ConnHdlr return boolean {
	var IntegerRecord min_dbm_level;
	var IntegerRecord max_dbm_level;
	var IntegerRecord x := f_power_from_band(g_pars.bts0_band, min_dbm_level, max_dbm_level);

	for (var integer i := 0; i < sizeof(max_dbm_level); i := i+1) {
		if (max_dbm_level[i] == level) {
			return true;
		}
	}
	return false;
}

private function f_get_max_power_from_band() runs on ConnHdlr return integer {
	var IntegerRecord min_dbm_level;
	var IntegerRecord max_dbm_level;
	var IntegerRecord x := f_power_from_band(g_pars.bts0_band, min_dbm_level, max_dbm_level);
	return max_dbm_level[0];
}

type charstring BtsBand ("GSM450","GSM480","GSM750","GSM810","GSM850","GSM900","DCS1800","PCS1900");
private template charstring BtsBand_allGSM := pattern "GSM???";
private function f_power_from_band(in BtsBand band, out IntegerRecord min_dbm_level, out IntegerRecord max_dbm_level) return IntegerRecord {
	// 45.005 4.1.1
	var IntegerRecord gsm_power :={31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19,
	 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3,
	 2, 1, 0};
	var IntegerRecord dcs_power :={28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15,
	 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 31, 30, 29};
	var IntegerRecord pcs_power :={15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 31, 30};
	var IntegerRecord rv;

	select(band){
	case (BtsBand_allGSM){
		rv := gsm_power;
		min_dbm_level := {31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19} ;
		max_dbm_level := {2, 1, 0};
	}
	case("DCS1800"){
		rv := dcs_power;
		min_dbm_level := {28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15};
		max_dbm_level := {0, 29}; // let's cheat here, assume MS_TXPWR_MAX_CCH might be being broadcast, so maybe no 29,30,31
	}
	case("PCS1900"){
		rv := pcs_power;
		min_dbm_level := {15};
		max_dbm_level := {30};
	}
	case else {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Unsupported band: " & band);
	}
	}

	return rv;
}

private function f_vty_get_bts0_band() runs on test_CT return BtsBand {
	return f_vty_transceive_match_regex(BTSVTY, "show bts 0", "BTS 0 is of*type* in band (\w+),*", 0);
}

testcase TC_rsl_ms_pwr_dyn_ass_updown() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;
	f_init();
	f_vty_config(BTSVTY, "phy 0", "osmotrx ms-power-loop -100");
	for (var integer tn := 1; tn <= 1; tn := tn+1) {
		pars := valueof(t_Pars(t_RslChanNr_Bm(tn), ts_RSL_ChanMode_SIGN));
		pars.bts0_band := f_vty_get_bts0_band();
		vc_conn := f_start_handler(refers(f_TC_rsl_ms_pwr_dyn_ass_updown), pars, trxc_comp := true);
		vc_conn.done;
	}
	f_vty_config(BTSVTY, "phy 0", "no osmotrx ms-power-loop");
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

testcase TC_rsl_ms_pwr_dyn_up() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;
	f_init();
	f_vty_config(BTSVTY, "phy 0", "osmotrx ms-power-loop -10");
	for (var integer tn := 1; tn <= 1; tn := tn+1) {
		pars := valueof(t_Pars(t_RslChanNr_Bm(tn), ts_RSL_ChanMode_SIGN, t_guard := 30.0));
		pars.bts0_band := f_vty_get_bts0_band();
		vc_conn := f_start_handler(refers(f_TC_rsl_ms_pwr_dyn_up), pars, trxc_comp := true);
		vc_conn.done;
	}
	f_vty_config(BTSVTY, "phy 0", "no osmotrx ms-power-loop");
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

testcase TC_rsl_ms_pwr_dyn_max() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;
	f_init();
	f_vty_config(BTSVTY, "phy 0", "osmotrx ms-power-loop -10");
	for (var integer tn := 1; tn <= 1; tn := tn+1) {
		pars := valueof(t_Pars(t_RslChanNr_Bm(tn), ts_RSL_ChanMode_SIGN));
		pars.bts0_band := f_vty_get_bts0_band();
		vc_conn := f_start_handler(refers(f_TC_rsl_ms_pwr_dyn_max), pars, trxc_comp := true);
		vc_conn.done;
	}
	f_vty_config(BTSVTY, "phy 0", "no osmotrx ms-power-loop");
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

testcase TC_rsl_ms_pwr_dyn_down() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;
	f_init();
	f_vty_config(BTSVTY, "phy 0", "osmotrx ms-power-loop -100");
	for (var integer tn := 1; tn <= 1; tn := tn+1) {
		pars := valueof(t_Pars(t_RslChanNr_Bm(tn), ts_RSL_ChanMode_SIGN));
		pars.bts0_band := f_vty_get_bts0_band();
		vc_conn := f_start_handler(refers(f_TC_rsl_ms_pwr_dyn_down), pars, trxc_comp := true);
		vc_conn.done;
	}
	f_vty_config(BTSVTY, "phy 0", "no osmotrx ms-power-loop");
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

testcase TC_rsl_ms_pwr_dyn_active() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;
	f_init();
	f_vty_config(BTSVTY, "phy 0", "osmotrx ms-power-loop -100");
	for (var integer tn := 1; tn <= 1; tn := tn+1) {
		pars := valueof(t_Pars(t_RslChanNr_Bm(tn), ts_RSL_ChanMode_SIGN));
		pars.bts0_band := f_vty_get_bts0_band();
		vc_conn := f_start_handler(refers(f_TC_rsl_ms_pwr_dyn_active), pars, trxc_comp := true);
		vc_conn.done;
	}
	f_vty_config(BTSVTY, "phy 0", "no osmotrx ms-power-loop");
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

testcase TC_rsl_ms_pwr_dyn_active2() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;
	f_init();
	f_vty_config(BTSVTY, "phy 0", "osmotrx ms-power-loop -100");
	for (var integer tn := 1; tn <= 1; tn := tn+1) {
		pars := valueof(t_Pars(t_RslChanNr_Bm(tn), ts_RSL_ChanMode_SIGN));
		pars.bts0_band := f_vty_get_bts0_band();
		vc_conn := f_start_handler(refers(f_TC_rsl_ms_pwr_dyn_active2), pars, trxc_comp := true);
		vc_conn.done;
	}
	f_vty_config(BTSVTY, "phy 0", "no osmotrx ms-power-loop");
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

function f_TC_meas_res_speech_tchf(boolean facch_enabled) runs on test_CT {
	var template RSL_IE_ChannelMode ch_mode;
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;
	f_init();
	ch_mode := ts_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM1);
	for (var integer tn := 1; tn <= 1; tn := tn + 1) {
		pars := valueof(t_Pars(t_RslChanNr_Bm(tn), ch_mode));
		pars.l1_pars.facch_enabled := facch_enabled;
		vc_conn := f_start_handler(refers(f_TC_meas_res_periodic), pars,
					   pcu_comp := false, trxc_comp := true);
		vc_conn.done;
	}
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

testcase TC_meas_res_speech_tchf() runs on test_CT {
	 f_TC_meas_res_speech_tchf(false);
}

testcase TC_meas_res_speech_tchf_facch() runs on test_CT {
	 f_TC_meas_res_speech_tchf(true);
}

function f_TC_meas_res_speech_tchh(boolean facch_enabled) runs on test_CT {
	var template RSL_IE_ChannelMode ch_mode;
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;
	f_init();
	ch_mode := ts_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM1);
	for (var integer ss := 0; ss <= 1; ss := ss + 1) {
		pars := valueof(t_Pars(t_RslChanNr_Lm(5, ss), ch_mode));
		pars.l1_pars.facch_enabled := facch_enabled;
		vc_conn := f_start_handler(refers(f_TC_meas_res_periodic), pars,
					   pcu_comp := false, trxc_comp := true);
		vc_conn.done;
	}
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

testcase TC_meas_res_speech_tchh() runs on test_CT {
	 f_TC_meas_res_speech_tchh(false)
}

testcase TC_meas_res_speech_tchh_facch() runs on test_CT {
	 f_TC_meas_res_speech_tchh(true)
}

testcase TC_meas_res_speech_tchh_toa256() runs on test_CT {
	var template RSL_IE_ChannelMode ch_mode;
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;
	f_init();
	f_vty_config(BTSVTY, "bts 0", "supp-meas-info toa256");
	ch_mode := ts_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM1);
	for (var integer ss := 0; ss <= 1; ss := ss + 1) {
		pars := valueof(t_Pars(t_RslChanNr_Lm(5, ss), ch_mode));
		pars.l1_pars.toa256_enabled := true;
		vc_conn := f_start_handler(refers(f_TC_meas_res_periodic), pars,
					   pcu_comp := false, trxc_comp := true);
		vc_conn.done;
	}
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

testcase TC_meas_res_sign_tchf() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;
	f_init();
	f_vty_config(BTSVTY, "bts 0", "no supp-meas-info toa256");
	for (var integer tn := 1; tn <= 4; tn := tn+1) {
		pars := valueof(t_Pars(t_RslChanNr_Bm(tn), ts_RSL_ChanMode_SIGN(RSL_CHRT_TCH_F)));
		vc_conn := f_start_handler(refers(f_TC_meas_res_periodic), pars,
					   pcu_comp := false, trxc_comp := true);
		vc_conn.done;
	}
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}
testcase TC_meas_res_sign_tchh() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;
	f_init();
	f_vty_config(BTSVTY, "bts 0", "no supp-meas-info toa256");
	for (var integer ss := 0; ss <= 1; ss := ss+1) {
		pars := valueof(t_Pars(t_RslChanNr_Lm(5, ss), ts_RSL_ChanMode_SIGN(RSL_CHRT_TCH_H)));
		vc_conn := f_start_handler(refers(f_TC_meas_res_periodic), pars,
					   pcu_comp := false, trxc_comp := true);
		vc_conn.done;
	}
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}
testcase TC_meas_res_sign_sdcch4() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;
	f_init();
	f_vty_config(BTSVTY, "bts 0", "no supp-meas-info toa256");
	for (var integer ss := 0; ss <= 3; ss := ss+1) {
		pars := valueof(t_Pars(t_RslChanNr_SDCCH4(0, ss), ts_RSL_ChanMode_SIGN));
		vc_conn := f_start_handler(refers(f_TC_meas_res_periodic), pars,
					   pcu_comp := false, trxc_comp := true);
		vc_conn.done;
	}
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}
testcase TC_meas_res_sign_sdcch8() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;
	f_init();
	f_vty_config(BTSVTY, "bts 0", "no supp-meas-info toa256");
	for (var integer ss := 0; ss <= 7; ss := ss+1) {
		pars := valueof(t_Pars(t_RslChanNr_SDCCH8(6, ss), ts_RSL_ChanMode_SIGN));
		vc_conn := f_start_handler(refers(f_TC_meas_res_periodic), pars,
					   pcu_comp := false, trxc_comp := true);
		vc_conn.done;
	}
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}
testcase TC_meas_res_sign_tchh_toa256() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;
	f_init();
	f_vty_config(BTSVTY, "bts 0", "supp-meas-info toa256");
	for (var integer ss := 0; ss <= 1; ss := ss+1) {
		pars := valueof(t_Pars(t_RslChanNr_Lm(5, ss), ts_RSL_ChanMode_SIGN(RSL_CHRT_TCH_H)));
		pars.l1_pars.toa256_enabled := true;
		vc_conn := f_start_handler(refers(f_TC_meas_res_periodic), pars,
					   pcu_comp := false, trxc_comp := true);
		vc_conn.done;
	}
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/* Make sure that we always get RSL MEASurement RESult messages regardless
 * of what is sent on SACCH: (RR) Measurement Report or SAPI=3 data (SMS). */
private function f_TC_meas_res_sapi3(charstring id) runs on ConnHdlr {
	timer Texec := 8.0;
	timer Timpf := 2.0;
	timer Tmr;

	f_l1_tune(L1CTL);
	RSL.clear;

	f_est_dchan();
	L1CTL.clear;

	/* Establish the main SAPI=0 link on DCCH first */
	f_tx_lapdm(ts_LAPDm_SABM(0, cr_MO_CMD, true, ''O), ts_RslLinkID_DCCH(0));

	/* Give more time for the first RSL MEASurement RESult */
	Tmr.start(0.480 * 2.0);
	Texec.start; /* EXECution timer */
	Timpf.start; /* IMPFung timer  */

	alt {
	/* We expect RSL MEASurement RESult messages every ~480ms (plus some guard) */
	[] RSL.receive(tr_RSL_MEAS_RES(g_pars.chan_nr)) {
		/* Reschedule the MEAS RES timer */
		Tmr.start(0.480 + 0.120);
		repeat;
		}
	[] RSL.receive { repeat; }
	[] Tmr.timeout {
		setverdict(fail, "Timeout waiting for RSL MEAS RES");
		}
	/* Inject some SAPI=3 traffic on SACCH every 2 seconds */
	[] Timpf.timeout {
		f_tx_lapdm(ts_LAPDm_SABM(3, cr_MO_CMD, true, ''O), ts_RslLinkID_SACCH(3));
		log("Injected SAPI=3 traffic on SACCH");
		Timpf.start;
		repeat;
		}
	/* We're good if survived so far */
	[] Texec.timeout {
		setverdict(pass);
		}
	}

	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
	f_rslem_unregister(0, g_chan_nr);
}
testcase TC_meas_res_speech_tchf_sapi3() runs on test_CT {
	var template RSL_IE_ChannelMode ch_mode;
	var template ConnHdlrPars pars;
	var ConnHdlr vc_conn;

	f_init();

	ch_mode := ts_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM1);
	pars := t_Pars(t_RslChanNr_Bm(1), ch_mode);

	vc_conn := f_start_handler(refers(f_TC_meas_res_sapi3), valueof(pars));
	vc_conn.done;

	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}
testcase TC_meas_res_speech_tchh_sapi3() runs on test_CT {
	var template RSL_IE_ChannelMode ch_mode;
	var template ConnHdlrPars pars;
	var ConnHdlr vc_conn;

	f_init();

	ch_mode := ts_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM1);
	pars := t_Pars(t_RslChanNr_Lm(5, 0), ch_mode);

	vc_conn := f_start_handler(refers(f_TC_meas_res_sapi3), valueof(pars));
	vc_conn.done;

	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/* establish DChan, and send MS POWER CONTROL messages via RSL, verify that
 * the BTS is forwarding those values to the MS via the SACCH L1 header. */
private function f_tc_rsl_ms_pwr_ctrl(charstring id) runs on ConnHdlr {
	var SacchL1Header l1h;
	var RSL_IE_MS_Power ms_power;
	var RSL_Message rsl;
	var uint5_t power_level := 0;

	f_l1_tune(L1CTL);
	RSL.clear;

	f_est_dchan();

	ms_power.reserved := 0;
	ms_power.fpc_epc := false;

	/* Send the first power control command. This will disable any BTS/TRX
	 * internal power control and switch the MS (which is not in scope of
	 * this test) to a constant power level. We start with a power level
	 * of 0 */
	ms_power.power_level := power_level;
	rsl := valueof(ts_RSL_MS_PWR_CTRL(g_chan_nr, ms_power));
	RSL.send(rsl);

	alt {
	[] as_l1_sacch_l1h(l1h, do_apply := false) {
		if (l1h.ms_power_lvl != power_level) {
			setverdict(fail, "Power level := ", l1h.ms_power_lvl, "does not ",
				   "match the signaled (RSL) power level := ", power_level);
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
		}

		/* Signal a new power level via RSL for the next turn. */
		if (power_level < 31) {
			power_level := power_level + 1;
			ms_power.power_level := power_level;
			rsl := valueof(ts_RSL_MS_PWR_CTRL(g_chan_nr, ms_power));
			RSL.send(rsl);
			repeat;
		}

		}

	/* Ignore all other blocks */
	[] L1CTL.receive { repeat; }

	}

	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);

	setverdict(pass);
}

testcase TC_rsl_ms_pwr_ctrl() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;
	f_init();

	for (var integer tn := 1; tn <= 4; tn := tn+1) {
		pars := valueof(t_Pars(t_RslChanNr_Bm(tn), ts_RSL_ChanMode_SIGN));
		vc_conn := f_start_handler(refers(f_tc_rsl_ms_pwr_ctrl), pars);
		vc_conn.done;
	}
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/* establish DChan, verify that the BTS sets the TA in the first SACCH L1 header.
TA for the IMM ASS messages is still controlled by g_pars.l1_pars.ms_actual_ta! */
private function f_tc_rsl_chan_initial_ta(charstring id) runs on ConnHdlr {
	var uint5_t ta_to_test := 16;
	var SacchL1Header l1h;

	f_l1_tune(L1CTL);
	RSL.clear;

	/* tell fake_trx to use a given timing offset for all bursts */
	f_trxc_fake_toffs256(ta_to_test*256);

	f_est_dchan(more_ies :={valueof(t_RSL_IE(RSL_IE_TIMING_ADVANCE, RSL_IE_Body:{timing_adv := ta_to_test}))} );


	alt {
	[] as_l1_sacch_l1h(l1h, do_apply := false) {
		if (l1h.actual_ta != ta_to_test) {
			setverdict(fail, "TA in L1 header does not match the signaled (RSL) TA.");
		}

		}

	/* Ignore all other blocks */
	[] L1CTL.receive { repeat; }

	}

	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);

	setverdict(pass);
}

testcase TC_rsl_chan_initial_ta() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;
	f_init();
	pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN));
	vc_conn := f_start_handler(refers(f_tc_rsl_chan_initial_ta), pars,
				   pcu_comp := false, trxc_comp := true);
	vc_conn.done;
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/* establish DChan, verify that the BTS sets MS power in the first SACCH L1 header. */
private function f_tc_rsl_chan_initial_ms_pwr(charstring id) runs on ConnHdlr {
	var uint5_t ms_power_level := 7;
	var SacchL1Header l1h;

	var RSL_IE_MS_Power ms_power;
	ms_power.reserved := 0;
	ms_power.fpc_epc := false;
	ms_power.power_level := ms_power_level;

	f_l1_tune(L1CTL);
	RSL.clear;

	f_est_dchan(more_ies :={valueof(t_RSL_IE(RSL_IE_MS_POWER, RSL_IE_Body:{ms_power := ms_power}))} );

	timer T := 1.0;
	T.start;
	alt {
	/* Pick all SACCH blocks for checking */
	[] as_l1_sacch_l1h(l1h, do_apply := false) {
		if (l1h.ms_power_lvl != ms_power_level) {
			setverdict(fail, "Power level := ", l1h.ms_power_lvl, "does not ",
				   "match the signaled (RSL) power level := ", ms_power_level);
		}
		}
	/* Ignore all other blocks */
	[] L1CTL.receive { repeat; }
	[] T.timeout {
		setverdict(fail, "Power Level in L1 header does not match the signaled (RSL) MS Power Level.");
		}
	}

	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
	setverdict(pass);
}

testcase TC_rsl_chan_initial_ms_pwr() runs on test_CT {
	var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN));
	f_testmatrix_each_chan(pars, refers(f_tc_rsl_chan_initial_ms_pwr));
}

/* Test if a channel without valid uplink bursts generates RSL CONN FAIL IND (TS 48.058 4.10) */
private function f_TC_conn_fail_crit(charstring id) runs on ConnHdlr {
	f_l1_tune(L1CTL);
	RSL.clear;

	f_est_dchan();
	f_sleep(2.0);
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
	f_L1CTL_RESET(L1CTL);
	f_l1_tune(L1CTL); /* tune back to BCCH */

	timer T := 40.0;
	T.start;
	alt {
	[] RSL.receive(tr_RSL_CONN_FAIL_IND(g_chan_nr, ?)) {
		setverdict(pass)
		}
	[] RSL.receive { repeat };
	[] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "No CONN FAIL IND received");
		}
	}
	f_rsl_chan_deact();
}
testcase TC_conn_fail_crit() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;
	f_init();
	pars := valueof(t_Pars(t_RslChanNr_SDCCH8(6, 3), ts_RSL_ChanMode_SIGN));
	pars.t_guard := 60.0;
	vc_conn := f_start_handler(refers(f_TC_conn_fail_crit), pars);
	vc_conn.done;
}

/***********************************************************************
 * Paging
 ***********************************************************************/

private function tmsi_is_dummy(TMSIP_TMSI_V tmsi) return boolean {
	if (tmsi == 'FFFFFFFF'O) {
		return true;
	} else {
		return false;
	}
}

private type record allowedFn { integer frame_nr }
private template allowedFn bs_ag_blks_res_0  := { frame_nr := (6, 12, 16, 22, 26, 32, 36, 42, 46) }
private template allowedFn bs_ag_blks_res_1  := { frame_nr := (12, 16, 22, 26, 32, 36, 42, 46) }
private template allowedFn bs_ag_blks_res_2  := { frame_nr := (16, 22, 26, 32, 36, 42, 46) }
private template allowedFn bs_ag_blks_res_3  := { frame_nr := (22, 26, 32, 36, 42, 46) }
private template allowedFn bs_ag_blks_res_4  := { frame_nr := (26, 32, 36, 42, 46) }
private template allowedFn bs_ag_blks_res_5  := { frame_nr := (32, 36, 42, 46) }
private template allowedFn bs_ag_blks_res_6  := { frame_nr := (36, 42, 46) }
private template allowedFn bs_ag_blks_res_7  := { frame_nr := (42, 46) }
private function check_pch_fn(integer frame_nr, integer bs_ag_blks_res) runs on test_CT
{
	var integer frame_nr_51;
	frame_nr_51 := frame_nr mod 51

	var allowedFn fn_check;
	fn_check.frame_nr := frame_nr_51;

	if (bs_ag_blks_res < 0 or bs_ag_blks_res > 7) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "bs_ag_blks_res out of valid range (0..7)");
		return;
	}

	if (bs_ag_blks_res == 0 and match(fn_check, bs_ag_blks_res_0)) {
		return;
	}
	if (bs_ag_blks_res == 1 and match(fn_check, bs_ag_blks_res_1)) {
		return;
	}
	if (bs_ag_blks_res == 2 and match(fn_check, bs_ag_blks_res_2)) {
		return;
	}
	if (bs_ag_blks_res == 3 and match(fn_check, bs_ag_blks_res_3)) {
		return;
	}
	if (bs_ag_blks_res == 4 and match(fn_check, bs_ag_blks_res_4)) {
		return;
	}
	if (bs_ag_blks_res == 5 and match(fn_check, bs_ag_blks_res_5)) {
		return;
	}
	if (bs_ag_blks_res == 6 and match(fn_check, bs_ag_blks_res_6)) {
		return;
	}
	if (bs_ag_blks_res == 7 and match(fn_check, bs_ag_blks_res_7)) {
		return;
	}

	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "received paging on AGCH");
	return;
}

private altstep as_l1_count_paging(inout integer num_paging_rcv_msgs,
				   inout integer num_paging_rcv_ids,
				   PagingTestCfg cfg)
runs on test_CT {
	var L1ctlMessage dl;
	[] L1CTL.receive(tr_L1CTL_DATA_IND(t_RslChanNr_PCH_AGCH(0), ?, c_DummyUI)) {
		repeat;
	}
	[] L1CTL.receive(tr_L1CTL_DATA_IND(t_RslChanNr_PCH_AGCH(0))) -> value dl {
		var octetstring without_plen :=
			substr(dl.payload.data_ind.payload, 1, lengthof(dl.payload.data_ind.payload)-1);
		var PDU_ML3_NW_MS rr := dec_PDU_ML3_NW_MS(without_plen);

		check_pch_fn(dl.dl_info.frame_nr, cfg.bs_ag_blks_res);

		if (match(rr, tr_PAGING_REQ1(tr_MI_LV(t_MI_NoIdentity(?))))) {
			/* Ignore empty RR Paging Request (PCH filling) messages.
			 * TODO: does it make sense to count them? */
		} else if (match(rr, tr_PAGING_REQ1)) {
			num_paging_rcv_msgs := num_paging_rcv_msgs + 1;
			num_paging_rcv_ids := num_paging_rcv_ids + 1;
			if (ispresent(rr.msgs.rrm.pagingReq_Type1.mobileIdentity2)) {
				num_paging_rcv_ids := num_paging_rcv_ids + 1;
			}
		} else if (match(rr, tr_PAGING_REQ2)) {
			num_paging_rcv_msgs := num_paging_rcv_msgs + 1;
			if (not tmsi_is_dummy(rr.msgs.rrm.pagingReq_Type2.mobileIdentity1)) {
				num_paging_rcv_ids := num_paging_rcv_ids + 1;
			}
			if (not tmsi_is_dummy(rr.msgs.rrm.pagingReq_Type2.mobileIdentity2)) {
				num_paging_rcv_ids := num_paging_rcv_ids + 1;
			}
			if (ispresent(rr.msgs.rrm.pagingReq_Type2.mobileIdentity3)) {
				num_paging_rcv_ids := num_paging_rcv_ids + 1;
			}
		} else if (match(rr, tr_PAGING_REQ3)) {
			num_paging_rcv_msgs := num_paging_rcv_msgs + 1;
			if (not tmsi_is_dummy(rr.msgs.rrm.pagingReq_Type3.mobileIdentity1)) {
				num_paging_rcv_ids := num_paging_rcv_ids + 1;
			}
			if (not tmsi_is_dummy(rr.msgs.rrm.pagingReq_Type3.mobileIdentity2)) {
				num_paging_rcv_ids := num_paging_rcv_ids + 1;
			}
			if (not tmsi_is_dummy(rr.msgs.rrm.pagingReq_Type3.mobileIdentity3)) {
				num_paging_rcv_ids := num_paging_rcv_ids + 1;
			}
			if (not tmsi_is_dummy(rr.msgs.rrm.pagingReq_Type3.mobileIdentity4)) {
				num_paging_rcv_ids := num_paging_rcv_ids + 1;
			}
		}
		repeat;
	}
}

private type record PagingTestCfg {
	boolean combined_ccch,
	integer bs_ag_blks_res,
	float load_factor,
	/* Mix in a paging request through the PCU socket for every Nth (ps_load_modulus)
	 * paging command that is issued via RSL. */
	integer ps_load_modulus,
	/* Wait until the paging queue inside the BTS is congested before starting to add
	 * pagings via the PCU socket (0 = disabled) */
	boolean ps_wait_cong,
	/* Maximum time to wait until the paging queue is drained at the end of the test.
	 * This usually takes about 15s (size: 200, ~ 13 per s -> 15s), it is recommended
	 * to set this value to 18s, however the draining process may take significantly
	 * longer when the queue contains paging requests for PS as those are implemented
	 * as immediate assignments and require an entire MAC block alone. */
	float queue_drain_timeout,
	boolean exp_load_ind,
	boolean exp_overload,
	boolean use_tmsi
}

private type record PagingTestState {
	integer num_paging_sent,
	integer num_paging_rcv_msgs,
	integer num_paging_rcv_ids,
	integer num_overload,
	/* When free space inside the paging queue reaches more than 2 thirds
	 * of its capacity cong_detected is set to true. */
	boolean cong_detected
}

/* Helper function for paging related testing */
private function f_TC_paging(PagingTestCfg cfg) runs on test_CT return PagingTestState {
	/* Using the PCU socket affects the timing of the paging processing. We only
	 * activate the PCU socket if we do paging load tests that include additional
	 * paging load that is introduced through the PCU socket. */
	if (cfg.ps_load_modulus > 0) {
		f_init_with_pcuif();
	} else {
		f_init();
	}
	f_init_l1ctl();
	f_l1_tune(L1CTL);

	var octetstring imm_ass := f_rnd_octstring(23);
	var ASP_RSL_Unitdata load_ind;

	var PagingTestState st := {
		num_paging_sent := 0,
		num_paging_rcv_msgs := 0,
		num_paging_rcv_ids := 0,
		num_overload := 0,
		cong_detected := false
	};

	var float max_pch_blocks_per_sec := f_pch_block_rate_est(cfg.combined_ccch, cfg.bs_ag_blks_res);
	var float max_pch_imsi_per_sec;
	if (cfg.use_tmsi) {
		max_pch_imsi_per_sec := max_pch_blocks_per_sec * 4.0; /* Type 3 */
	} else {
		max_pch_imsi_per_sec := max_pch_blocks_per_sec * 2.0; /* Type 1 */
	}
	var float pch_blocks_per_sec := max_pch_imsi_per_sec * cfg.load_factor;
	var float interval := 1.0 / pch_blocks_per_sec;
	var float time_total := 20.0;
	var integer pkt_total := float2int(time_total * pch_blocks_per_sec);
	log("pch_blocks_total=", pkt_total," pch_blocks_per_sec=", pch_blocks_per_sec, " interval=", interval);

	timer T_total := 300.0; /* big value (far bigger than time_total), used to count elapsed time */
	T_total.start;

	timer T_itv := 0.0;
	T_itv.start;
	while (st.num_paging_sent < pkt_total) {
		alt {
		/* check for presence of CCCH LOAD IND (paging load) */
		[cfg.exp_overload] RSL_CCHAN.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_LOAD_IND(0))) {
			st.num_overload := st.num_overload + 1;
			repeat;
			}
		[not cfg.exp_overload]  RSL_CCHAN.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_LOAD_IND(0))) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Unexpected PCH Overload");
			}
		[cfg.exp_load_ind] RSL_CCHAN.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_LOAD_IND)) -> value load_ind {
			log("Rx LOAD_IND");

			/* Detect paging congestion: The logic inside the BTS will diagnose the
			 * paging queue as congested when the fill state is more than 66% (which
			 * is two thirds fill state, or approx. 66 of 200 paging slots. When a
			 * paging congestion is detected pagings that are issued through the PCU
			 * socket (PS) are dropped in order to prefer the CS related pagings. */
			if (load_ind.rsl.ies[1].body.paging_load < 66) {
				st.cong_detected := true;
			}

			/* FIXME: analyze/verify interval + contents */
			repeat;
			}
		/* ignore other RSL messages like RF RESource INDication */
		[] RSL_CCHAN.receive { repeat; }
		/* check if paging requests arrive on Um side */
		[] as_l1_count_paging(st.num_paging_rcv_msgs, st.num_paging_rcv_ids, cfg);
		[] L1CTL.receive { repeat; }
		/* Only relevant when testing including with PCU sock connected */
		[] PCU.receive { repeat; }
		[] T_itv.timeout {
			/* Send paging cmds based on elapsed time */
			var integer new_sent := f_min(pkt_total, float2int(T_total.read * pch_blocks_per_sec) + 1);
			while (st.num_paging_sent < new_sent) {
				var MobileIdentityV mi;

				/* build mobile Identity */
				if (cfg.use_tmsi) {
					mi := valueof(t_MI_TMSI(f_rnd_octstring(4)));
				} else {
					mi := valueof(ts_MI_IMSI(f_gen_imsi(st.num_paging_sent)));
				}

				/* Send RSL PAGING COMMAND */
				RSL_CCHAN.send(ts_ASP_RSL_UD(ts_RSL_PAGING_CMD(mi, st.num_paging_sent mod 4)));

				/* Add additional pagings through the PCU socket interface. */
				if (cfg.ps_load_modulus > 0 and st.num_paging_sent mod cfg.ps_load_modulus == 0) {
					if (st.cong_detected == true or cfg.ps_wait_cong == false) {
						f_PCUIF_tx_imm_ass_pch(PCU, g_pcu_conn_id, imm_ass, '123459987'H, wait_for_cnf := false);
					}
				}

				st.num_paging_sent := st.num_paging_sent + 1;
			}
			if (st.num_paging_sent < pkt_total) {
				/* Wait for interval to next PAGING COMMAND */
				var float time_now := T_total.read;
				var float next_sched := int2float(st.num_paging_sent)*interval;
				if (next_sched > time_now) {
					T_itv.start(next_sched - time_now);
				} else {
					T_itv.start(0.0);
				}
			} else {
				/* We are done, no need to keep counting */
				T_total.stop;
			}
			}
		[] T_total.timeout { }
		}
	}

	timer T_wait := cfg.queue_drain_timeout
	T_wait.start;
	alt {
	[] as_l1_count_paging(st.num_paging_rcv_msgs, st.num_paging_rcv_ids, cfg);
	[] L1CTL.receive { repeat; }
	/* 65535 == empty paging queue, we can terminate*/
	[] RSL_CCHAN.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_LOAD_IND(65535))) { }
	[] RSL_CCHAN.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_LOAD_IND)) -> value load_ind { repeat; }
	/* ignore other RSL messages like RF RESource INDication */
	[] RSL_CCHAN.receive { repeat; }
	/* Only relevant when testing including with PCU sock connected */
	[] PCU.receive { repeat; }
	[] T_wait.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Waiting for paging queue, last detected fill state: ", load_ind.rsl.ies[1].body.paging_load));
		}
	}

	log("num_paging_sent=", st.num_paging_sent, " rcvd_msgs=", st.num_paging_rcv_msgs,
	    " rcvd_ids=", st.num_paging_rcv_ids);
	return st;
}

/* Create ~ 80% paging load (IMSI only) sustained for about 20s, verifying that
 *  - the number of Mobile Identities on Um PCH match the number of pages on RSL
 *  - that CCCH LOAD IND (PCH) are being generated
 *  - that CCCH LOAD IND (PCH) [no load] is received after paging flood is over */
testcase TC_paging_imsi_80percent() runs on test_CT {
	var SystemInformation si3 := valueof(ts_SI3_default);
	var PagingTestCfg cfg := {
		combined_ccch := true,
		bs_ag_blks_res := si3.payload.si3.ctrl_chan_desc.bs_ag_blks_res,
		load_factor := 0.8,
		ps_load_modulus := 0,
		ps_wait_cong := false,
		queue_drain_timeout := 18.0,
		exp_load_ind := true,
		exp_overload := false,
		use_tmsi := false
	};
	var PagingTestState st := f_TC_paging(cfg);
	if (st.num_paging_sent != st.num_paging_rcv_ids) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Expected ", st.num_paging_sent, " pagings but have ",
			   st.num_paging_rcv_ids));
	} else {
		setverdict(pass);
	}
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/* Create ~ 80% paging load (TMSI only) sustained for about 20s, verifying that
 *  - the number of Mobile Identities on Um PCH match the number of pages on RSL
 *  - that CCCH LOAD IND (PCH) are being generated
 *  - that CCCH LOAD IND (PCH) [no load] is received after paging flood is over */
testcase TC_paging_tmsi_80percent() runs on test_CT {
	var SystemInformation si3 := valueof(ts_SI3_default);
	var PagingTestCfg cfg := {
		combined_ccch := true,
		bs_ag_blks_res := si3.payload.si3.ctrl_chan_desc.bs_ag_blks_res,
		load_factor := 0.8,
		ps_load_modulus := 0,
		ps_wait_cong := false,
		queue_drain_timeout := 18.0,
		exp_load_ind := true,
		exp_overload := false,
		use_tmsi := true
	};
	var PagingTestState st := f_TC_paging(cfg);
	if (st.num_paging_sent != st.num_paging_rcv_ids) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Expected ", st.num_paging_sent, " pagings but have ",
			   st.num_paging_rcv_ids));
	} else {
		setverdict(pass);
	}
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/* Create ~ 200% paging load (IMSI only) sustained for about 20s, verifying that
 *  - the number of Mobile Identities on Um PCH are ~ 82% of the number of pages on RSL
 *  - that CCCH LOAD IND (PCH) are being generated and reach 0 at some point
 *  - that CCCH LOAD IND (PCH) [no load] is received after paging flood is over */
testcase TC_paging_imsi_200percent() runs on test_CT {
	var SystemInformation si3 := valueof(ts_SI3_default);
	var PagingTestCfg cfg := {
		combined_ccch := true,
		bs_ag_blks_res := si3.payload.si3.ctrl_chan_desc.bs_ag_blks_res,
		load_factor := 2.0,
		ps_load_modulus := 0,
		ps_wait_cong := false,
		queue_drain_timeout := 18.0,
		exp_load_ind := true,
		exp_overload := true,
		use_tmsi := false
	};
	var PagingTestState st := f_TC_paging(cfg);
	/* We expect about 80-85% to pass, given that we can fill the paging buffer of 200
	 * slots and will fully drain that buffer before returning */
	var template integer tpl := (st.num_paging_sent*78/100 .. st.num_paging_sent *85/100);
	if (not match(st.num_paging_rcv_ids, tpl)) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Expected ", tpl, " pagings but have ", st.num_paging_rcv_ids));
	} else {
		setverdict(pass);
	}
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/* Create ~ 200% paging load (TMSI only) sustained for about 20s, verifying that
 *  - the number of Mobile Identities on Um PCH are ~ 82% of the number of pages on RSL
 *  - that CCCH LOAD IND (PCH) are being generated and reach 0 at some point
 *  - that CCCH LOAD IND (PCH) [no load] is received after paging flood is over */
testcase TC_paging_tmsi_200percent() runs on test_CT {
	var SystemInformation si3 := valueof(ts_SI3_default);
	var PagingTestCfg cfg := {
		combined_ccch := true,
		bs_ag_blks_res := si3.payload.si3.ctrl_chan_desc.bs_ag_blks_res,
		load_factor := 2.0,
		ps_load_modulus := 0,
		ps_wait_cong := false,
		queue_drain_timeout := 18.0,
		exp_load_ind := true,
		exp_overload := true,
		use_tmsi := true
	};
	var PagingTestState st := f_TC_paging(cfg);
	/* We expect about 70% to pass, given that we can fill the paging buffer of 200
	 * slots and will fully drain that buffer before returning */
	var template integer tpl := (st.num_paging_sent*64/100 .. st.num_paging_sent *72/100);
	if (not match(st.num_paging_rcv_ids, tpl)) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Expected ", tpl, " pagings but have ", st.num_paging_rcv_ids));
	} else {
		setverdict(pass);
	}
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/* Same as above, but with additional paging load created by PS pagings that
 * are issued through the PCU socket. The additional load is introduced when
 * the paging queue is already two thirds full. Since the BTS implements a
 * prioritization logic that drops the pagings from the PCU under in those
 * congestive sitautions the behaviour on the PS side is expected to be
 * unaffected and match the behavior of TC_paging_imsi_200percent() */
testcase TC_paging_imsi_200percent_with_ps() runs on test_CT {
	var SystemInformation si3 := valueof(ts_SI3_default);
	var PagingTestCfg cfg := {
		combined_ccch := true,
		bs_ag_blks_res := si3.payload.si3.ctrl_chan_desc.bs_ag_blks_res,
		load_factor := 2.0,
		ps_load_modulus := 16,
		ps_wait_cong := true,
		queue_drain_timeout := 18.0,
		exp_load_ind := true,
		exp_overload := true,
		use_tmsi := false
	};
	var PagingTestState st := f_TC_paging(cfg);
	/* We expect about 80-85% to pass, given that we can fill the paging buffer of 200
	 * slots and will fully drain that buffer before returning */
	var template integer tpl := (st.num_paging_sent*78/100 .. st.num_paging_sent *85/100);
	if (not match(st.num_paging_rcv_ids, tpl)) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Expected ", tpl, " pagings but have ", st.num_paging_rcv_ids));
	} else {
		setverdict(pass);
	}
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}



/***********************************************************************
 * Immediate Assignment / AGCH
 ***********************************************************************/
private const MobileAllocationLV c_MA_null := {
	len := 0,
	ma := ''B
}

private function f_fmt_ia_stats(integer num_tx, integer num_rx, integer num_del) return charstring {
	return int2str(num_tx) & " sent, "
		  & int2str(num_rx) & " received, "
		  & int2str(num_del) & " deleted";
}

private function f_TC_imm_ass(integer num_total, float sleep_s, float exp_pass) runs on test_CT {
	var L1ctlMessage l1_dl;
	timer T := 10.0;
	var integer num_tx := 0;
	var integer num_rx := 0;
	var integer num_del := 0;
	var charstring res_str;
	var float rx_ratio;

	f_init();
	f_init_l1ctl();
	f_l1_tune(L1CTL);

	for (var integer i := 0; i < num_total; i := i+1) {
		var ChannelDescription ch_desc := valueof(ts_ChanDescH0(ts_RslChanNr_SDCCH4(0, 0),
									mp_trx_pars[0].arfcn,
									mp_tsc_def));
		var GsmRrMessage ia := valueof(ts_IMM_ASS(42, i, 5, ch_desc, c_MA_null));
		var octetstring ia_enc := enc_GsmRrMessage(ia);
		RSL_CCHAN.send(ts_ASP_RSL_UD(ts_RSL_IMM_ASSIGN(ia_enc, 0)));
		num_tx := num_tx+1;
		f_sleep(sleep_s);
	}
	/* FIXME: check if imm.ass arrive on Um side */
	T.start;
	alt {
	[] RSL_CCHAN.receive(tr_ASP_RSL_UD(tr_RSL_DELETE_IND(?, 0))) {
		num_del := num_del+1;
		repeat;
		}
	[] RSL_CCHAN.receive {
		repeat;
		}
	[] L1CTL.receive(tr_L1CTL_DATA_IND(t_RslChanNr_PCH_AGCH(0), ?)) -> value l1_dl {
		var GsmRrMessage rr := dec_GsmRrMessage(l1_dl.payload.data_ind.payload);
		if (not match(rr, tr_IMM_ASS(42, ?, 5, ?, ?))) {
			/* FIXME: Why are we seeing paging requests on PCH/AGCH? */
			//Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Unexpected IMM-ASS values on AGCH: ", rr));
		} else {
			num_rx := num_rx+1;
		}
		repeat;
		}
	[] L1CTL.receive { repeat; }
	[] T.timeout { }
	}
	res_str := f_fmt_ia_stats(num_tx, num_rx, num_del);
	log("AGCH test: " & res_str);
	if (num_rx + num_del != num_tx) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "RX + DEL != TX ?!?: " & res_str);
	}
	rx_ratio := int2float(num_rx) / int2float(num_tx);
	if (rx_ratio < exp_pass*0.8 or rx_ratio > exp_pass*1.2) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "RX ratio ("&float2str(rx_ratio)&") far from expected ("&float2str(exp_pass)&") " & res_str);
	} else {
		setverdict(pass);
	}
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/* send a long burst of 1000 IMM.ASS with 20ms spacing (50 per s); expect 75% of them to be deleted */
testcase TC_imm_ass_1000_20ms() runs on test_CT {
	f_TC_imm_ass(1000, 0.02, 0.25);
}

/* send a short burst of 200 IMM.ASS without any spacing; expect 95% of them to be deleted */
testcase TC_imm_ass_200_0ms() runs on test_CT {
	f_TC_imm_ass(200, 0.0, 0.05);
}

/* send 150 IMM.ASS at rate of 13/s; expect none of them to be deleted */
testcase TC_imm_ass_200_76ms() runs on test_CT {
	f_TC_imm_ass(150, 0.076, 1.00);
}



/***********************************************************************
 * BCCH
 ***********************************************************************/

/* tuple of Frame Number + decoded SI */
private type record SystemInformationFn {
	GsmFrameNumber frame_number,
	SystemInformation si
}

/* an arbitrary-length vector of decoded SI + gsmtap header */
private type record of SystemInformationFn SystemInformationVector;

/* an array of SI-vectors indexed by TC value */
private type SystemInformationVector SystemInformationVectorPerTc[8];

/* determine if a given SI vector contains given SI type at least once */
private function f_si_vecslot_contains(SystemInformationVector arr,
				       RrMessageType key,
				       boolean bcch_ext := false)
return boolean {
	for (var integer i:= 0; i< sizeof(arr); i := i + 1) {
		var integer fn_mod51 := arr[i].frame_number mod 51;
		if (not bcch_ext and fn_mod51 == 2 or
		        bcch_ext and fn_mod51 == 6) {
			if (arr[i].si.header.message_type == key) {
				return true;
			}
		}
	}
	return false;
}

/* ensure a given TC slot of the SI vector contains given SI type at least once at TC */
private function f_ensure_si_vec_contains(SystemInformationVectorPerTc arr,
					  integer tc, RrMessageType key,
					  boolean ext_bcch := false)
{
	if (not f_si_vecslot_contains(arr[tc], key, ext_bcch)) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("No ", key, " in TC=", tc, "!"));
	}
}

/* check if a given SI vector contains given SI type at least once on any TC */
private function f_si_vec_contains(SystemInformationVectorPerTc arr,
				   RrMessageType key)
return boolean {
	for (var integer tc:= 0; tc < sizeof(arr); tc := tc + 1) {
		if (f_si_vecslot_contains(arr[tc], key) or
		    f_si_vecslot_contains(arr[tc], key, true)) {
			return true;
		}
	}
	return false;
}

/* determine if a given SI vector contains given SI type at least N of M times */
private function f_si_vecslot_contains_n_of_m(SystemInformationVector arr,
					      RrMessageType key,
					      boolean bcch_ext := false,
					      integer n := 1, integer m := 4)
return boolean {
	var integer count := 0;
	if (sizeof(arr) < m) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Error: Insufficient SI in array: "
					& int2str(sizeof(arr)) & " < " & int2str(m));
	}
	for (var integer i:= 0; i < m; i := i + 1) {
		var integer fn_mod51 := arr[i].frame_number mod 51;
		if (not bcch_ext and fn_mod51 == 2 or
		        bcch_ext and fn_mod51 == 6) {
			if (arr[i].si.header.message_type == key) {
				count := count + 1;
			}
		}
	}
	if (count >= n) {
		return true;
	} else {
		return false;
	}
}

/* ensure a given TC slot of the SI vector contains given SI type at least N out of M times at TC */
private function f_ensure_si_vec_contains_n_of_m(SystemInformationVectorPerTc arr,
						 integer tc, RrMessageType key,
						 boolean ext_bcch := false,
						 integer n, integer m)
{
	if (not f_si_vecslot_contains_n_of_m(arr[tc], key, ext_bcch, n, m)) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Not ", n, "/", m, " of ", key, " in TC=", tc, "!"));
	}
}

/* determine if a given SI vector contains given SI type at least once */
private function f_si_vecslot_contains_only(SystemInformationVector arr,
					    RrMessageType key,
					    boolean bcch_ext := false)
return boolean {
	for (var integer i:= 0; i< sizeof(arr); i := i + 1) {
		var integer fn_mod51 := arr[i].frame_number mod 51;
		if (not bcch_ext and fn_mod51 == 2 or
		        bcch_ext and fn_mod51 == 6) {
			if (arr[i].si.header.message_type != key) {
				return false;
			}
		}
	}
	return true;
}

/* ensure a given TC slot of the SI vector contains only given SI type */
private function f_ensure_si_vec_contains_only(SystemInformationVectorPerTc arr,
					       integer tc, RrMessageType key,
					       boolean ext_bcch := false)
{
	if (not f_si_vecslot_contains_only(arr[tc], key, ext_bcch)) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Not all ", key, " in TC=", tc, "!"));
	}
}

/* SI configuration of cell, against which we validate actual SI messages */
private type set SystemInformationConfig {
	boolean bcch_extended,
	boolean si1_present,
	boolean si2bis_present,
	boolean si2ter_present,
	boolean si2quater_present,
	boolean si7_present,
	boolean si8_present,
	boolean si9_present,
	boolean si13_present,
	boolean si13alt_present,
	boolean si15_present,
	boolean si16_present,
	boolean si17_present,
	boolean si2n_present,
	boolean si21_present,
	boolean si22_present
}

/* validate the SI scheduling according to TS 45.002 version 14.1.0 Release 14, Section 6.3.1.3 */
private function f_validate_si_scheduling(SystemInformationConfig cfg,
					  SystemInformationVectorPerTc si_per_tc)
{
	var integer i;
	for (i := 0; i < sizeof(si_per_tc); i := i + 1) {
		if (sizeof(si_per_tc[i]) == 0) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("No SI messages for TC=", i));
		}
	}
	if (cfg.si1_present) {
		/* ii) System Information Type 1 needs to be sent if frequency hopping is in use or
		 * when the NCH is present in a cell. If the MS finds another message on BCCH Norm
		 * when TC = 0, it can assume that System Information Type 1 is not in use. */
		f_ensure_si_vec_contains(si_per_tc, 0, SYSTEM_INFORMATION_TYPE_1);
		/* make sure *ALL* contain SI1 */
		f_ensure_si_vec_contains_only(si_per_tc, 0, SYSTEM_INFORMATION_TYPE_1);
	}
	f_ensure_si_vec_contains(si_per_tc, 1, SYSTEM_INFORMATION_TYPE_2);
	/* iii) A SI 2 message will be sent at least every time TC = 1 */
	f_ensure_si_vec_contains(si_per_tc, 2, SYSTEM_INFORMATION_TYPE_3);
	f_ensure_si_vec_contains(si_per_tc, 6, SYSTEM_INFORMATION_TYPE_3);
	f_ensure_si_vec_contains(si_per_tc, 3, SYSTEM_INFORMATION_TYPE_4);
	f_ensure_si_vec_contains(si_per_tc, 7, SYSTEM_INFORMATION_TYPE_4);

	/*  iii) System information type 2 bis or 2 ter messages are sent if needed, as determined by the
	 *  system operator. If only one of them is needed, it is sent when TC = 5. If both are
	 *  needed, 2bis is sent when TC = 5 and 2ter is sent at least once within any of 4
	 *  consecutive occurrences of TC = 4. */
	if (cfg.si2bis_present and not cfg.si2ter_present) {
		f_ensure_si_vec_contains(si_per_tc, 5, SYSTEM_INFORMATION_TYPE_2bis);
	} else if (cfg.si2ter_present and not cfg.si2bis_present) {
		f_ensure_si_vec_contains(si_per_tc, 5, SYSTEM_INFORMATION_TYPE_2ter);
	} else if (cfg.si2ter_present and cfg.si2bis_present) {
		f_ensure_si_vec_contains(si_per_tc, 5, SYSTEM_INFORMATION_TYPE_2bis);
		f_ensure_si_vec_contains_n_of_m(si_per_tc, 4, SYSTEM_INFORMATION_TYPE_2ter, false, 1, 4);
	}

	if (cfg.si7_present or cfg.si8_present) {
		/* vi) Use of System Information type 7 and 8 is not always necessary. It is necessary
		 * if System Information type 4 does not contain all information needed for cell
		 * selection and reselection. */
		if (not cfg.bcch_extended) {
			testcase.stop("Error: SI7/SI8 require BCCH Extd.");
		}
		if (cfg.si7_present) {
			f_ensure_si_vec_contains(si_per_tc, 7, SYSTEM_INFORMATION_TYPE_7, true);
		}
		if (cfg.si8_present) {
			f_ensure_si_vec_contains(si_per_tc, 3, SYSTEM_INFORMATION_TYPE_8, true);
		}
	}

	if (cfg.si2quater_present) {
		/*  iii) System information type 2 quater is sent if needed, as determined by the system
		 *  operator.  If sent on BCCH Norm, it shall be sent when TC = 5 if neither of 2bis
		 *  and 2ter are used, otherwise it shall be sent at least once within any of 4
		 *  consecutive occurrences of TC = 4. If sent on BCCH Ext, it is sent at least once
		 *  within any of 4 consecutive occurrences of TC = 5. */
		if (not (cfg.bcch_extended)) {
			if (not (cfg.si2bis_present or cfg.si2ter_present)) {
				f_ensure_si_vec_contains(si_per_tc, 5, SYSTEM_INFORMATION_TYPE_2quater);
			} else {
				f_ensure_si_vec_contains_n_of_m(si_per_tc, 4, SYSTEM_INFORMATION_TYPE_2quater, false, 1, 4);
			}
		} else {
			f_ensure_si_vec_contains_n_of_m(si_per_tc, 5, SYSTEM_INFORMATION_TYPE_2quater, true, 1, 4);
		}
	}
	if (cfg.si9_present) {
		/* vi) System Information type 9 is sent in those blocks with TC = 4 which are specified
		 * in system information type 3 as defined in 3GPP TS 44.018. */
		f_ensure_si_vec_contains(si_per_tc, 4, SYSTEM_INFORMATION_TYPE_9); // FIXME SI3
	}
	if (cfg.si13_present) {
		/* vii) System Information type 13 is only related to the GPRS service. System Information
		 * Type 13 need only be sent if GPRS support is indicated in one or more of System
		 * Information Type 3 or 4 or 7 or 8 messages. These messages also indicate if the
		 * message is sent on the BCCH Norm or if the message is transmitted on the BCCH Ext.
		 * In the case that the message is sent on the BCCH Norm, it is sent at least once
		 * within any of 4 consecutive occurrences of TC=4. */
		if (not cfg.bcch_extended) {
			log("not-bccch-extended");
			f_ensure_si_vec_contains_n_of_m(si_per_tc, 4, SYSTEM_INFORMATION_TYPE_13, false, 1, 4);
		} else {
			log("bccch-extended");
			f_ensure_si_vec_contains(si_per_tc, 0, SYSTEM_INFORMATION_TYPE_13, true);
		}
		if (f_si_vec_contains(si_per_tc, SYSTEM_INFORMATION_TYPE_13alt)) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Cannot have SI13alt and SI13");
		}
	}
	if (cfg.si16_present or cfg.si17_present) {
		/* viii) System Information type 16 and 17 are only related to the SoLSA service. They
		 * should not be sent in a cell where network sharing is used (see rule xv). */
		if (cfg.si22_present) {
			testcase.stop("Error: Cannot have SI16/SI17 and SI22!");
		}
		if (f_si_vec_contains(si_per_tc, SYSTEM_INFORMATION_TYPE_22)) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Cannot have SI16/SI17 and SI22!");
		}
		if (not cfg.bcch_extended) {
			testcase.stop("Error: SI16/SI17 requires BCCH Extd!");
		}
		if (cfg.si16_present) {
			f_ensure_si_vec_contains(si_per_tc, 6, SYSTEM_INFORMATION_TYPE_16, true);
		}
		if (cfg.si17_present) {
			f_ensure_si_vec_contains(si_per_tc, 2, SYSTEM_INFORMATION_TYPE_17, true);
		}
	}

		/* ix) System Information type 18 and 20 are sent in order to transmit non-GSM
		 * broadcast information. The frequency with which they are sent is determined by the
		 * system operator. System Information type 9 identifies the scheduling of System
		 * Information type 18 and 20 messages. */

		/* x) System Information Type 19 is sent if COMPACT neighbours exist. If System
		 * Information Type 19 is present, then its scheduling shall be indicated in System
		 * Information Type 9. */

	if (cfg.si15_present) {
		/* xi) System Information Type 15 is broadcast if dynamic ARFCN mapping is used in the
		 * PLMN. If sent on BCCH Norm, it is sent at least once within any of 4 consecutive
		 * occurrences of TC = 4. If sent on BCCH Ext, it is sent at least once within any of
		 * 4 consecutive occurrences of TC = 1. */
		if (not cfg.bcch_extended) {
			f_ensure_si_vec_contains_n_of_m(si_per_tc, 4, SYSTEM_INFORMATION_TYPE_15, false, 1, 4);
		} else {
			f_ensure_si_vec_contains_n_of_m(si_per_tc, 1, SYSTEM_INFORMATION_TYPE_15, true, 1, 4);
		}
	}
	if (cfg.si13alt_present) {
		/* xii) System Information type 13 alt is only related to the GERAN Iu mode. System
		 * Information Type 13 alt need only be sent if GERAN Iu mode support is indicated in
		 * one or more of System Information Type 3 or 4 or 7 or 8 messages and SI 13 is not
		 * broadcast. These messages also indicate if the message is sent on the BCCH Norm or
		 * if the message is transmitted on the BCCH Ext. In the case that the message is sent
		 * on the BCCH Norm, it is sent at least once within any of 4 consecutive occurrences
		 * of TC = 4. */
		if (cfg.si13_present) {
			testcase.stop("Error: Cannot have SI13alt and SI13");
		}
		if (f_si_vec_contains(si_per_tc, SYSTEM_INFORMATION_TYPE_13)) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Cannot have SI13alt and SI13");
		}
		if (not cfg.bcch_extended) {
			f_ensure_si_vec_contains_n_of_m(si_per_tc, 4, SYSTEM_INFORMATION_TYPE_13alt, false, 1, 4);
		} else {
			f_ensure_si_vec_contains(si_per_tc, 0, SYSTEM_INFORMATION_TYPE_13alt, true);
		}
	}
	if (cfg.si2n_present) {
		/* xiii) System Information Type 2n is optionally sent on BCCH Norm or BCCH Ext if needed,
		 * as determined by the system operator. In the case that the message is sent on the
		 * BCCH Norm, it is sent at least once within any of 4 consecutive occurrences of TC =
		 * 4. If the message is sent on BCCH Ext, it is sent at least once within any of 2
		 * consecutive occurrences of TC = 4. */
		if (not cfg.bcch_extended) {
			f_ensure_si_vec_contains_n_of_m(si_per_tc, 4, SYSTEM_INFORMATION_TYPE_2n, false, 1, 4);
		} else {
			f_ensure_si_vec_contains_n_of_m(si_per_tc, 4, SYSTEM_INFORMATION_TYPE_2n, true, 2, 4);
		}
	}
	if (cfg.si21_present) {
		/* xiv) System Information Type 21 is optionally sent on BCCH Norm or BCCH Ext, as
		 * determined by the system operator. If Extended Access Barring is in use in the cell
		 * then this message is sent at least once within any of 4 consecutive occurrences of
		 * TC = 4 regardless if it is sent on BCCH Norm or BCCH Ext. If BCCH Ext is used in a
		 * cell then this message shall only be sent on BCCH Ext. */
		if (not cfg.bcch_extended) {
			f_ensure_si_vec_contains_n_of_m(si_per_tc, 4, SYSTEM_INFORMATION_TYPE_21, false, 1, 4);
		} else {
			f_ensure_si_vec_contains_n_of_m(si_per_tc, 4, SYSTEM_INFORMATION_TYPE_21, true, 1, 4);
			if (f_si_vecslot_contains(si_per_tc[4], SYSTEM_INFORMATION_TYPE_21)) {
				Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Cannot have SI21 on BCCH Norm if BCCH Extd enabled!");
			}
		}
	}
	if (cfg.si22_present) {
		/* xv) System Information Type 22 is sent if network sharing is in use in the cell. It
		 * should not be sent in a cell where SoLSA is used (see rule viii). System
		 * Information Type 22 instances shall be sent on BCCH Ext within any occurrence of TC
		 * =2 and TC=6. */
		if (cfg.si16_present or cfg.si17_present) {
			testcase.stop("Error: Cannot have SI16/SI17 and SI22!");
		}
		if (f_si_vec_contains(si_per_tc, SYSTEM_INFORMATION_TYPE_16) or
		    f_si_vec_contains(si_per_tc, SYSTEM_INFORMATION_TYPE_17)) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Cannot have SI16/SI17 and SI22!");
		}
		if (not cfg.bcch_extended) {
			testcase.stop("Error: SI22 requires BCCH Extd!");
		} else {
			f_ensure_si_vec_contains_only(si_per_tc, 2, SYSTEM_INFORMATION_TYPE_22, true);
			f_ensure_si_vec_contains_only(si_per_tc, 6, SYSTEM_INFORMATION_TYPE_22, true);
		}
	}
}

/* sample Systme Information for specified duration via L1CTL */
private function f_l1_sample_si(L1CTL_PT pt, float duration := 8.0)
return SystemInformationVectorPerTc {
	timer T := duration;
	var SystemInformationVectorPerTc si_per_tc;
	var L1ctlMessage l1_dl;

	/* initialize all per-TC vectors empty */
	for (var integer i:= 0; i < sizeof(si_per_tc); i := i+1) {
		si_per_tc[i] := {};
	}

	/* flush all previous L1 queued msgs */
	pt.clear;

	T.start;
	alt {
	[] pt.receive(tr_L1CTL_DATA_IND(t_RslChanNr_BCCH(0), ?)) -> value l1_dl {
		var SystemInformationFn sig := { frame_number := l1_dl.dl_info.frame_nr };
		if (dec_SystemInformationSafe(l1_dl.payload.data_ind.payload, sig.si) != 0) {
			log("Ignoring non-RR or invalid SI ", l1_dl);
			repeat;
		}

		var integer tc := f_gsm_compute_tc(sig.frame_number);
		log("SI received at TC=", tc, ": ", sig.si);
		/* append to the per-TC bucket */
		si_per_tc[tc] := si_per_tc[tc] & { sig };
		repeat;
		}
	[] pt.receive { repeat; }
	[] T.timeout { }
	}

	for (var integer i:= 0; i < sizeof(si_per_tc); i := i+1) {
		log(testcasename(), ": TC=", i, " has #of SI=", sizeof(si_per_tc[i]));
	}
	log("si_per_tc=", si_per_tc);
	return si_per_tc;
}

/* helper function: Set given SI via RSL + validate scheduling.
 * CALLER MUST MAKE SURE TO CHANGE GLOBAL si_cfg! */
private function f_TC_si_sched(float duration := 8.0) runs on test_CT {
	var SystemInformationVectorPerTc si_per_tc;
	f_init_l1ctl();
	f_l1_tune(L1CTL);

	/* Sample + Validate Scheduling */
	si_per_tc := f_l1_sample_si(L1CTL, duration);
	f_validate_si_scheduling(si_cfg, si_per_tc);

	setverdict(pass);
}

testcase TC_si_sched_default() runs on test_CT {
	f_init();
	/* 2+3+4 are mandatory and set in f_init() */
	f_TC_si_sched();
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

testcase TC_si_sched_1() runs on test_CT {
	f_init();
	si_cfg.si1_present := true;
	f_rsl_bcch_fill_raw(RSL_SYSTEM_INFO_1, '5506198fb38000000000000000000000000000e504002b'O);
	f_TC_si_sched();
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

testcase TC_si_sched_2bis() runs on test_CT {
	f_init();
	si_cfg.si2bis_present := true;
	f_rsl_bcch_fill_raw(RSL_SYSTEM_INFO_2bis, '550602bfe809b3ff00000000000000000000007900002b'O);
	f_TC_si_sched();
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

testcase TC_si_sched_2ter() runs on test_CT {
	f_init();
	si_cfg.si2ter_present := true;
	f_rsl_bcch_fill_raw(RSL_SYSTEM_INFO_2ter, '010603bf66b0aa0a00000002000000000000002b2b2b2b'O);
	f_TC_si_sched();
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

testcase TC_si_sched_2ter_2bis() runs on test_CT {
	f_init();
	si_cfg.si2bis_present := true;
	f_rsl_bcch_fill_raw(RSL_SYSTEM_INFO_2bis, '550602bfe809b3ff00000000000000000000007900002b'O);
	si_cfg.si2ter_present := true;
	f_rsl_bcch_fill_raw(RSL_SYSTEM_INFO_2ter, '010603bf66b0aa0a00000002000000000000002b2b2b2b'O);
	f_TC_si_sched();
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

testcase TC_si_sched_2quater() runs on test_CT {
	f_init();
	si_cfg.si2quater_present := true;
	f_rsl_bcch_fill_raw(RSL_SYSTEM_INFO_2quater, '050607b10004864982eddb8d555867ee3c95540b2b2b2b'O);
	f_TC_si_sched(16.0);
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

testcase TC_si_sched_13() runs on test_CT {
	/* NOTE: PCUIF connection is not used in this test case, but
	 * without it the IUT would not broadcast SI13 (see OS#3075). */
	f_init_with_pcuif();
	si_cfg.si13_present := true;
	f_rsl_bcch_fill_raw(RSL_SYSTEM_INFO_13, '0106009000185a6fc9e08410ab2b2b2b2b2b2b2b2b2b2b'O);
	f_TC_si_sched();
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

testcase TC_si_sched_13_2bis_2ter_2quater() runs on test_CT {
	/* NOTE: PCUIF connection is not used in this test case, but
	 * without it the IUT would not broadcast SI13 (see OS#3075). */
	f_init_with_pcuif();
	si_cfg.si2bis_present := true;
	f_rsl_bcch_fill_raw(RSL_SYSTEM_INFO_2bis, '550602bfe809b3ff00000000000000000000007900002b'O);
	si_cfg.si2ter_present := true;
	f_rsl_bcch_fill_raw(RSL_SYSTEM_INFO_2ter, '010603bf66b0aa0a00000002000000000000002b2b2b2b'O);
	si_cfg.si2quater_present := true;
	f_rsl_bcch_fill_raw(RSL_SYSTEM_INFO_2quater, '050607b10004864982eddb8d555867ee3c95540b2b2b2b'O);
	si_cfg.si13_present := true;
	f_rsl_bcch_fill_raw(RSL_SYSTEM_INFO_13, '0106009000185a6fc9e08410ab2b2b2b2b2b2b2b2b2b2b'O);
	f_TC_si_sched(16.0);
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}


testcase TC_bcch_info() runs on test_CT {
	f_init();
	/* FIXME: enable / disable individual BCCH info */
	//ts_RSL_BCCH_INFO(si_type, info);
	/* expect no ERROR REPORT after either of them *
	/* negative test: ensure ERROR REPORT on unsupported types */
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/***********************************************************************
 * Low-Level Protocol Errors / ERROR REPORT
 ***********************************************************************/

private function f_exp_err_rep(template RSL_Cause cause) runs on test_CT {
	timer T := 5.0;
	T.start;
	alt {
	[] RSL_CCHAN.receive(tr_ASP_RSL_UD(tr_RSL_ERROR_REPORT(cause))) {
		setverdict(pass);
		}
	[] RSL_CCHAN.receive(tr_ASP_RSL_UD(tr_RSL_ERROR_REPORT(?))) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Wrong cause in RSL ERR REP");
		}
	[] RSL_CCHAN.receive {
		repeat;
		}
	[] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for RSL ERR REP");
		}
	}
}

/* Provoke a protocol error (message too short) and match on ERROR REPORT */
testcase TC_rsl_protocol_error() runs on test_CT {
	f_init();
	var RSL_Message rsl := valueof(ts_RSL_BCCH_INFO(RSL_SYSTEM_INFO_1, ''O));
	rsl.ies := omit;
	RSL_CCHAN.send(ts_ASP_RSL_UD(rsl));

	f_exp_err_rep(RSL_ERR_PROTO);
}

/* Provoke a mandatory IE error and match on ERROR REPORT */
testcase TC_rsl_mand_ie_error() runs on test_CT {
	f_init();

	var RSL_Message rsl := valueof(ts_RSL_BCCH_INFO(RSL_SYSTEM_INFO_1, ''O));
	rsl.ies := { rsl.ies[0] };
	RSL_CCHAN.send(ts_ASP_RSL_UD(rsl));

	f_exp_err_rep(RSL_ERR_MAND_IE_ERROR);
}

/* Provoke an IE content error and match on ERROR REPORT */
testcase TC_rsl_ie_content_error() runs on test_CT {
	f_init();
	var RSL_Message rsl := valueof(ts_RSL_BCCH_INFO(RSL_SYSTEM_INFO_1, ''O));
	rsl.ies[1].body.sysinfo_type := RSL_SYSTEM_INFO_5;
	RSL_CCHAN.send(ts_ASP_RSL_UD(rsl));

	f_exp_err_rep(RSL_ERR_IE_CONTENT);
}

/* attempt to activate channel with wrong RSL Message Discriminator IE */
function f_TC_chan_act_wrong_mdisc(charstring id) runs on ConnHdlr {
	var template RSL_Message rsl := ts_RSL_CHAN_ACT(g_chan_nr, g_pars.chan_mode);
	rsl.msg_disc := ts_RSL_MsgDisc(RSL_MDISC_RESERVED, false);
	RSL.send(rsl);
	f_rslem_unregister(0, g_chan_nr);
}
testcase TC_err_rep_wrong_mdisc() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars := valueof(t_Pars(ts_RslChanNr_SDCCH4(0,0), ts_RSL_ChanMode_SIGN));

	f_init();

	vc_conn := f_start_handler(refers(f_TC_chan_act_wrong_mdisc), pars);
	vc_conn.done;
	f_exp_err_rep(RSL_ERR_MSG_DISCR);

	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/* Send messages with wrong message type */
private function f_TC_wrong_msg_type_dchan(charstring id) runs on ConnHdlr {
	var template (value) RSL_Message rsl_tx;
	rsl_tx := ts_RSL_CHAN_ACT(g_chan_nr, g_pars.chan_mode);
	rsl_tx.msg_type := RSL_MT_NOT_CMD;
	RSL.send(rsl_tx);
	f_rslem_unregister(0, g_chan_nr);
}
private function f_TC_wrong_msg_type_rll(charstring id) runs on ConnHdlr {
	var template (value) RSL_Message rsl_tx;
	/* we first have to activate the dedicated channel */
	f_rsl_chan_act(g_pars.chan_mode);
	/* ... to then send an invalid RLL message */
	rsl_tx := ts_RSL_UNITDATA_REQ(g_chan_nr, ts_RslLinkID_DCCH(0), '0102'O);
	rsl_tx.msg_type := RSL_MT_CBCH_LOAD_IND;
	RSL.send(rsl_tx);
	f_rslem_unregister(0, g_chan_nr);
}
testcase TC_err_rep_wrong_msg_type() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars := valueof(t_Pars(ts_RslChanNr_SDCCH4(0,0), ts_RSL_ChanMode_SIGN));
	var template (value) RSL_Message rsl_tx;

	f_init();

	/* Common Channel with wrong message type */
	RSL_CCHAN.clear;
	rsl_tx := valueof(ts_RSL_BCCH_INFO(RSL_SYSTEM_INFO_1, ''O));
	rsl_tx.msg_type := RSL_MT_LOCATION_INFO;
	RSL_CCHAN.send(ts_ASP_RSL_UD(rsl_tx));
	f_exp_err_rep(RSL_ERR_MSG_TYPE);

	/* TRX Management */
	RSL_CCHAN.clear;
	rsl_tx := ts_RSL_SACCH_FILL(RSL_SYSTEM_INFO_5, ''O);
	rsl_tx.msg_type := RSL_MT_UNIT_DATA_IND;
	RSL_CCHAN.send(ts_ASP_RSL_UD(rsl_tx));
	f_exp_err_rep(RSL_ERR_MSG_TYPE);

	/* Dedicated Channel */
	RSL_CCHAN.clear;
	vc_conn := f_start_handler(refers(f_TC_wrong_msg_type_dchan), pars);
	vc_conn.done;
	f_exp_err_rep(RSL_ERR_MSG_TYPE);

	/* RLL */
	RSL_CCHAN.clear;
	vc_conn := f_start_handler(refers(f_TC_wrong_msg_type_rll), pars);
	vc_conn.done;
	f_exp_err_rep(RSL_ERR_MSG_TYPE);
}

/* Send messages in wrong sequence (RLL to an inactive lchan) */
private function f_TC_err_rep_wrong_sequence(charstring id) runs on ConnHdlr {
	RSL.send(ts_RSL_UNITDATA_REQ(g_chan_nr, ts_RslLinkID_DCCH(0), '0102'O));
	f_rslem_unregister(0, g_chan_nr);
}
testcase TC_err_rep_wrong_sequence() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars := valueof(t_Pars(ts_RslChanNr_SDCCH4(0,0), ts_RSL_ChanMode_SIGN));

	f_init();

	RSL_CCHAN.clear;
	vc_conn := f_start_handler(refers(f_TC_err_rep_wrong_sequence), pars);
	vc_conn.done;
	f_exp_err_rep(RSL_ERR_MSG_SEQ);
}

/***********************************************************************
 * IPA CRCX/MDCX/DLCS media stream handling
 ***********************************************************************/

/* Send IPA DLCX to inactive lchan */
private function f_TC_ipa_dlcx_not_active(charstring id) runs on ConnHdlr {
	f_rsl_transceive(ts_RSL_IPA_DLCX(g_chan_nr, 0), tr_RSL_IPA_DLCX_ACK(g_chan_nr, ?, ?),
			 "IPA DLCX ACK");
}
testcase TC_ipa_dlcx_not_active() runs on test_CT {
	var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN));
	f_init();
	var ConnHdlr vc_conn := f_start_handler(refers(f_TC_ipa_dlcx_not_active), pars);
	vc_conn.done;
}

/* Send IPA CRCX twice to inactive lchan */
private function f_TC_ipa_crcx_twice_not_active(charstring id) runs on ConnHdlr {
	f_rsl_transceive(ts_RSL_IPA_CRCX(g_chan_nr), tr_RSL_IPA_CRCX_ACK(g_chan_nr, ?, ?, ?),
			 "IPA CRCX ACK");
	f_rsl_transceive(ts_RSL_IPA_CRCX(g_chan_nr), tr_RSL_IPA_CRCX_NACK(g_chan_nr, RSL_ERR_RES_UNAVAIL),
			 "IPA CRCX NACK");
}
testcase TC_ipa_crcx_twice_not_active() runs on test_CT {
	var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN));
	f_init();
	var ConnHdlr vc_conn := f_start_handler(refers(f_TC_ipa_crcx_twice_not_active), pars);
	vc_conn.done;
}

/* Regular sequence of CRCX/MDCX/DLCX */
private function f_TC_ipa_crcx_mdcx_dlcx_not_active(charstring id) runs on ConnHdlr {
	f_rsl_transceive(ts_RSL_IPA_CRCX(g_chan_nr), tr_RSL_IPA_CRCX_ACK(g_chan_nr, ?, ?, ?),
			 "IPA CRCX ACK");
	var OCT4 remote_ip := f_rnd_octstring(4);
	var uint16_t remote_port := f_rnd_int(c_UINT16_MAX);
	var uint7_t rtp_pt2 := f_rnd_int(127);
	var uint16_t fake_conn_id := 23; /* we're too lazy to read it out from the CRCX ACK above */
	f_rsl_transceive(ts_RSL_IPA_MDCX(g_chan_nr, fake_conn_id, remote_ip, remote_port, rtp_pt2),
			 tr_RSL_IPA_MDCX_ACK(g_chan_nr, ?, ?, ?, rtp_pt2),
			 "IPA MDCX ACK");
	f_rsl_transceive(ts_RSL_IPA_DLCX(g_chan_nr, fake_conn_id), tr_RSL_IPA_DLCX_ACK(g_chan_nr, ?, ?),
			 "IPA DLCX ACK");
}
testcase TC_ipa_crcx_mdcx_dlcx_not_active() runs on test_CT {
	var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN));
	f_init();
	var ConnHdlr vc_conn := f_start_handler(refers(f_TC_ipa_crcx_mdcx_dlcx_not_active), pars);
	vc_conn.done;
}

/* Sequence of CRCX, 2x MDCX, DLCX */
private function f_TC_ipa_crcx_mdcx_mdcx_dlcx_not_active(charstring id) runs on ConnHdlr {
	f_rsl_transceive(ts_RSL_IPA_CRCX(g_chan_nr), tr_RSL_IPA_CRCX_ACK(g_chan_nr, ?, ?, ?),
			 "IPA CRCX ACK");
	var OCT4 remote_ip := f_rnd_octstring(4);
	var uint16_t remote_port := f_rnd_int(c_UINT16_MAX);
	var uint7_t rtp_pt2 := f_rnd_int(127);
	var uint16_t fake_conn_id := 23; /* we're too lazy to read it out from the CRCX ACK above */
	f_rsl_transceive(ts_RSL_IPA_MDCX(g_chan_nr, fake_conn_id, remote_ip, remote_port, rtp_pt2),
			 tr_RSL_IPA_MDCX_ACK(g_chan_nr, ?, ?, ?, rtp_pt2),
			 "IPA MDCX ACK");
	/* Second MDCX */
	remote_ip := f_rnd_octstring(4);
	remote_port := f_rnd_int(c_UINT16_MAX);
	f_rsl_transceive(ts_RSL_IPA_MDCX(g_chan_nr, fake_conn_id, remote_ip, remote_port, rtp_pt2),
			 tr_RSL_IPA_MDCX_ACK(g_chan_nr, ?, ?, ?, rtp_pt2),
			 "IPA MDCX ACK");
	f_rsl_transceive(ts_RSL_IPA_DLCX(g_chan_nr, fake_conn_id), tr_RSL_IPA_DLCX_ACK(g_chan_nr, ?, ?),
			 "IPA DLCX ACK");
}
testcase TC_ipa_crcx_mdcx_mdcx_dlcx_not_active() runs on test_CT {
	var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN));
	f_init();
	var ConnHdlr vc_conn := f_start_handler(refers(f_TC_ipa_crcx_mdcx_mdcx_dlcx_not_active), pars);
	vc_conn.done;
}

/* IPA CRCX on SDCCH/4 and SDCCH/8 (doesn't make sense) */
private function f_TC_ipa_crcx_sdcch_not_active(charstring id) runs on ConnHdlr {
	f_rsl_transceive(ts_RSL_IPA_CRCX(g_chan_nr), tr_RSL_IPA_CRCX_NACK(g_chan_nr, ?),
			 "IPA CRCX NACK");
}
testcase TC_ipa_crcx_sdcch_not_active() runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;
	f_init();

	pars := valueof(t_Pars(t_RslChanNr_SDCCH4(0,1), ts_RSL_ChanMode_SIGN));
	vc_conn := f_start_handler(refers(f_TC_ipa_crcx_sdcch_not_active), pars);
	vc_conn.done;

	pars := valueof(t_Pars(t_RslChanNr_SDCCH8(6,5), ts_RSL_ChanMode_SIGN));
	vc_conn := f_start_handler(refers(f_TC_ipa_crcx_sdcch_not_active), pars);
	vc_conn.done;
}

/* Make sure that CRCX ACK contains a valid listen address (see OS#5242) */
private function f_TC_ipa_crcx_ack_addr(charstring id) runs on ConnHdlr {
	var OCT4 bind_ip := f_inet_addr("192.168.1.1");
	var PortNumber bind_port := 16811;
	var RSL_Message crcx_ack;

	crcx_ack := f_rsl_transceive_ret(ts_RSL_IPA_CRCX(g_chan_nr, bind_ip, bind_port),
					 tr_RSL_IPA_CRCX_ACK(g_chan_nr, ?, ?, ?),
					 "IPA CRCX ACK");
	var HostName bts_bind_ip := f_inet_ntoa(crcx_ack.ies[2].body.ipa_local_ip);
	if (match(bts_bind_ip, "0.0.0.0")) {
		setverdict(fail, "CRCX ACK indicates nonsense addr ", bts_bind_ip);
	}

	var uint16_t conn_id := crcx_ack.ies[1].body.ipa_conn_id;
	f_rsl_transceive(ts_RSL_IPA_DLCX(g_chan_nr, conn_id),
			 tr_RSL_IPA_DLCX_ACK(g_chan_nr, ?, ?),
			 "IPA DLCX ACK");
}
testcase TC_ipa_crcx_ack_addr() runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;
	f_init();

	pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM1)));
	vc_conn := f_start_handler(refers(f_TC_ipa_crcx_ack_addr), pars);
	vc_conn.done;

	pars := valueof(t_Pars(ts_RslChanNr_Lm(5, 0), ts_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM1)));
	vc_conn := f_start_handler(refers(f_TC_ipa_crcx_ack_addr), pars);
	vc_conn.done;
}


/***********************************************************************
 * PCU Socket related tests
 ***********************************************************************/

/* Catch a PCUIF message (without having to use t_SD_PCUIF) */
private altstep as_pcuif_msg(out PCUIF_Message msg,
			     template (present) PCUIF_Message tr_msg := ?)
runs on test_CT {
	var PCUIF_send_data sd;

	[] PCU.receive(t_SD_PCUIF(g_pcu_conn_id, tr_msg)) -> value sd {
		msg := sd.data;
	}
}

/* Tune the L1 to PDCH on the given timeslot number */
private function f_TC_pcu_l1ctl_est_pdch(uint3_t tn) runs on test_CT {
	var ConnHdlrPars pars := valueof(t_Pars(ts_RslChanNr_PDCH(tn), ts_RSL_ChanMode_SIGN));
	if (mp_freq_hop_enabled and mp_transceiver_num > 1)
		{ f_resolve_fh_params(pars.fhp, tn); }
	f_l1ctl_est_dchan(L1CTL, pars);
}

/* Verify no RTS before ACT_REQ; verify RTS after ACT_REQ */
friend function f_TC_pcu_act_req(uint8_t bts_nr, uint8_t trx_nr, uint8_t ts_nr, boolean exp_success)
runs on test_CT {
	var PCUIF_Message msg;
	timer T := 3.0;

	/* we don't expect any RTS.req before PDCH are active */
	T.start;
	alt {
	[] as_pcuif_msg(msg, tr_PCUIF_RTS_REQ(bts_nr)) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "PCU RTS.req before PDCH active?");
		}
	[] PCU.receive { repeat; }
	[] T.timeout { }
	}

	/* Send PDCH activate request for known PDCH timeslot */
	PCU.send(t_SD_PCUIF(g_pcu_conn_id, ts_PCUIF_ACT_REQ(bts_nr, trx_nr, ts_nr)));

	/* we now expect RTS.req for this timeslot (only) */
	T.start;
	alt {
	[exp_success] as_pcuif_msg(msg, tr_PCUIF_RTS_REQ(bts_nr, trx_nr, ts_nr)) {
		setverdict(pass);
		}
	[not exp_success] as_pcuif_msg(msg, tr_PCUIF_RTS_REQ(bts_nr, trx_nr, ts_nr)) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Unexpected RTS.req for supposedly failing activation");
		}
	[] as_pcuif_msg(msg, tr_PCUIF_RTS_REQ) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "RTS.req for wrong TRX/TS");
		}
	[] PCU.receive { repeat; }
	[exp_success] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for PCU RTS.req");
		}
	[not exp_success] T.timeout {
		setverdict(pass);
		}
	}
}

/* verify no more RTS after DEACT_REQ */
friend function f_TC_pcu_deact_req(uint8_t bts_nr, uint8_t trx_nr, uint8_t ts_nr)
runs on test_CT {
	var PCUIF_Message msg;
	timer T := 3.0;

	/* Send PDCH activate request for known PDCH timeslot */
	PCU.send(t_SD_PCUIF(g_pcu_conn_id, ts_PCUIF_DEACT_REQ(bts_nr, trx_nr, ts_nr)));
	/* wait for some time as there is no PCUIF_DEACT_RESP or the like, so we don't know
	 * when it will actually have been executed in the BTS */
	f_sleep(1.0);
	PCU.clear;
	/* we now expect no RTS.req for this timeslot */
	T.start;
	alt {
	[] as_pcuif_msg(msg, tr_PCUIF_RTS_REQ(bts_nr, trx_nr, ts_nr)) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received unexpected PCU RTS.req");
		}
	[] PCU.receive { repeat; }
	[] T.timeout {
		setverdict(pass);
		}
	}
}

friend function f_init_with_pcuif() runs on test_CT {
	f_init();
	map(self:PCU, system:PCU);
	f_init_pcu(PCU, testcasename(), g_pcu_conn_id, g_pcu_last_info);
	PCU.send(t_SD_PCUIF(g_pcu_conn_id, ts_PCUIF_TXT_IND(0, PCU_VERSION, testcasename())));
}

/* PDCH activation via PCU socket; check for presence of RTS.req */
testcase TC_pcu_act_req() runs on test_CT {
	f_init_with_pcuif();

	f_TC_pcu_act_req(0, 0, 7, true);
}

/* PDCH activation via PCU socket on non-PDCU timeslot */
testcase TC_pcu_act_req_wrong_ts() runs on test_CT {
	f_init_with_pcuif();

	f_TC_pcu_act_req(0, 0, 1, false);
}

/* PDCH activation via PCU socket on wrong BTS */
testcase TC_pcu_act_req_wrong_bts() runs on test_CT {
	f_init_with_pcuif();

	f_TC_pcu_act_req(23, 0, 7, false);
}

/* PDCH activation via PCU socket on wrong TRX */
testcase TC_pcu_act_req_wrong_trx() runs on test_CT {
	f_init_with_pcuif();

	f_TC_pcu_act_req(0, 23, 7, false);
}

/* PDCH deactivation via PCU socket; check for absence of RTS.req */
testcase TC_pcu_deact_req() runs on test_CT {
	f_init_with_pcuif();

	/* Activate PDCH */
	f_TC_pcu_act_req(0, 0, 7, true);
	f_sleep(1.0);
	/* and De-Activate again */
	f_TC_pcu_deact_req(0, 0, 7);
}

/* Attempt to deactivate a PDCH on a non-PDCH timeslot */
testcase TC_pcu_deact_req_wrong_ts() runs on test_CT {
	f_init_with_pcuif();

	f_TC_pcu_deact_req(0, 0, 1);
}

/* Test the PCU->BTS Version and BTS->PCU SI13 handshake */
function f_TC_pcu_ver_siXX(octetstring si, RSL_IE_SysinfoType rsl_si_type) runs on test_CT {
	var PCUIF_Message msg;
	timer T := 3.0;

	f_init_with_pcuif();

	/* Set SI13 via RSL */
	f_rsl_bcch_fill_raw(rsl_si_type, si);

	T.start;
	alt {
	[] as_pcuif_msg(msg, tr_PCUIF_DATA_IND(0, 0, 0, sapi := PCU_IF_SAPI_BCCH)) {
		if (substr(msg.u.data_ind.data, 0, lengthof(si)) == si) {
			setverdict(pass);
		} else {
			repeat;
		}
		}
	[] PCU.receive { repeat; }
	[] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for SI");
		}
	}
}

/* Test the PCU->BTS Version and BTS->PCU SI1 handshake */
testcase TC_pcu_ver_si1() runs on test_CT {
	const octetstring si1 := '550111132A252B27CC29AA11BB33CC'O;
	f_TC_pcu_ver_siXX(si1, RSL_SYSTEM_INFO_1);
}

/* Test the PCU->BTS Version and BTS->PCU SI3 handshake */
testcase TC_pcu_ver_si3() runs on test_CT {
	const octetstring si3 := '49012223242526272929AABBCC'O;
	f_TC_pcu_ver_siXX(si3, RSL_SYSTEM_INFO_3);
}

/* Test the PCU->BTS Version and BTS->PCU SI13 handshake */
testcase TC_pcu_ver_si13() runs on test_CT {
	const octetstring si13 := '01010203040506070909'O;
	f_TC_pcu_ver_siXX(si13, RSL_SYSTEM_INFO_13);
}

private const octetstring c_PCU_DATA := '000102030405060708090a0b0c0d0e0f10111213141516'O;

/* helper function to send a PCU DATA.req */
friend function f_pcu_data_req(uint8_t bts_nr, uint8_t trx_nr, uint8_t ts_nr,
				uint8_t block_nr, uint32_t fn, PCUIF_Sapi sapi, octetstring data)
runs on test_CT
{
	PCU.send(t_SD_PCUIF(g_pcu_conn_id,
			ts_PCUIF_DATA_REQ(bts_nr, trx_nr, ts_nr, block_nr, fn, sapi, data)));
}

/* helper function to wait for RTS.ind for given SAPI on given BTS/TRX/TS and then send */
friend function f_pcu_wait_rts_and_data_req(uint8_t bts_nr, uint8_t trx_nr, uint8_t ts_nr,
					    PCUIF_Sapi sapi, octetstring data)
runs on test_CT
{
	var PCUIF_Message msg;
	timer T := 3.0;

	T.start;
	alt {
	[] as_pcuif_msg(msg, tr_PCUIF_RTS_REQ(bts_nr, trx_nr, ts_nr, sapi)) {
		f_pcu_data_req(bts_nr, trx_nr, ts_nr, msg.u.rts_req.block_nr,
			       msg.u.rts_req.fn, sapi, data);
		}
	[] PCU.receive { repeat; }
	[] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for RTS.ind");
		}
	}
}

/* Send DATA.req on invalid BTS */
testcase TC_pcu_data_req_wrong_bts() runs on test_CT {
	var octetstring data := '0000'O & f_rnd_octstring(21);

	f_TC_pcu_init();

	f_TC_pcu_act_req(0, 0, 7, true);
	f_TC_pcu_l1ctl_est_pdch(7);

	L1CTL.send(ts_L1CTL_GPRS_DL_TBF_CFG_REQ(0, '00000001'B));
	f_pcu_to_l1(23, 0, 7, PCU_IF_SAPI_PDTCH, data, false, false);
}

/* Send DATA.req on invalid TRX */
testcase TC_pcu_data_req_wrong_trx() runs on test_CT {
	var octetstring data := '0000'O & f_rnd_octstring(21);

	f_TC_pcu_init();

	f_TC_pcu_act_req(0, 0, 7, true);
	f_TC_pcu_l1ctl_est_pdch(7);

	L1CTL.send(ts_L1CTL_GPRS_DL_TBF_CFG_REQ(0, '00000001'B));
	f_pcu_to_l1(0, 100, 7, PCU_IF_SAPI_PDTCH, data, false, false);
}

/* Send DATA.req on invalid timeslot */
testcase TC_pcu_data_req_wrong_ts() runs on test_CT {
	var octetstring data := '0000'O & f_rnd_octstring(21);

	f_TC_pcu_init();

	f_TC_pcu_act_req(0, 0, 7, true);
	f_TC_pcu_l1ctl_est_pdch(7);

	L1CTL.send(ts_L1CTL_GPRS_DL_TBF_CFG_REQ(0, '00000001'B));
	f_pcu_to_l1(0, 0, 70, PCU_IF_SAPI_PDTCH, data, false, false);
}

/* Send DATA.req on timeslot that hasn't been activated */
testcase TC_pcu_data_req_ts_inactive() runs on test_CT {
	var octetstring data := '0000'O & f_rnd_octstring(21);

	f_TC_pcu_init();

	/* intentionally not calling f_TC_pcu_act_req() */
	f_TC_pcu_l1ctl_est_pdch(7);

	L1CTL.send(ts_L1CTL_GPRS_DL_TBF_CFG_REQ(0, '00000001'B));
	f_pcu_to_l1(0, 0, 7, PCU_IF_SAPI_PDTCH, data, false, false);
}

private function f_pcu_to_l1(uint8_t bts_nr, uint8_t trx_nr, uint8_t ts_nr,
			     PCUIF_Sapi sapi, octetstring data, boolean expect_data := true,
			     boolean wait_rts := true)
runs on test_CT {
	timer T := 5.0;
	var L1ctlMessage rx_dl;

	L1CTL.clear;
	PCU.clear;
	if (wait_rts) {
		f_pcu_wait_rts_and_data_req(bts_nr, trx_nr, ts_nr, sapi, data);
	} else {
		f_pcu_data_req(bts_nr, trx_nr, ts_nr, 0, 0, sapi, data);
	}

	T.start;
	alt {
	[expect_data] L1CTL.receive(tr_L1CTL_GPRS_DL_BLOCK_IND(tn := ts_nr, data := data)) {
		/* FIXME: why is fn of DL BLOCK.ind different to fn of RTS / DATA_REQ above? */
		setverdict(pass);
		}
	[not expect_data] L1CTL.receive(tr_L1CTL_GPRS_DL_BLOCK_IND(tn := ts_nr, data := data)) -> value rx_dl {
		setverdict(fail, "Received unexpected ", rx_dl);
		}
	[] L1CTL.receive {
		repeat;
		}
	[expect_data] T.timeout {
		setverdict(fail, "Timeout waiting for ", data);
		}
	[not expect_data] T.timeout {
		setverdict(pass);
		}
	}
}

private function f_TC_pcu_init() runs on test_CT {
	f_init_with_pcuif();
	f_init_l1ctl();
	f_l1_tune(L1CTL);
}

testcase TC_pcu_data_req_pdtch() runs on test_CT {
	var octetstring data := '0000'O & f_rnd_octstring(21);

	f_TC_pcu_init();

	f_TC_pcu_act_req(0, 0, 7, true);
	f_TC_pcu_l1ctl_est_pdch(7);

	L1CTL.send(ts_L1CTL_GPRS_DL_TBF_CFG_REQ(0, '00000001'B));
	f_pcu_to_l1(0, 0, 7, PCU_IF_SAPI_PDTCH, data); //c_PCU_DATA);
}

testcase TC_pcu_data_req_ptcch() runs on test_CT {
	var octetstring data := '0000'O & f_rnd_octstring(21);

	f_TC_pcu_init();

	f_TC_pcu_act_req(0, 0, 7, true);
	f_TC_pcu_l1ctl_est_pdch(7);

	L1CTL.send(ts_L1CTL_GPRS_DL_TBF_CFG_REQ(0, '00000001'B));
	f_pcu_to_l1(0, 0, 7, PCU_IF_SAPI_PTCCH, data);
}

private function f_TC_pcu_ptcch_ul(uint16_t ra)
runs on test_CT {
	var template PCUIF_Message pcu_rach_ind;
	var PCUIF_Message msg;
	var GsmFrameNumber fn;
	timer T;

	/* Send an Access Burst on PTCCH/U over the Um-interface */
	fn := f_L1CTL_RACH(L1CTL, ra := ra, combined := 0, offset := 0,
			   chan_nr := ts_RslChanNr_PDCH(7),
			   link_id := ts_RslLinkID_OSMO_PTCCH(0));

	pcu_rach_ind := tr_PCUIF_RACH_IND(bts_nr := 0, trx_nr := 0, ts_nr := 7,
					  ra := ra, fn := fn, sapi := PCU_IF_SAPI_PTCCH);

	/* Expect a RACH.ind on the PCU interface (timeout is one multi-frame) */
	T.start(52.0 * 4.615 / 1000.0);
	alt {
	[] as_pcuif_msg(msg, pcu_rach_ind) {
		log("Rx an Access Burst on the PCU interface: ", msg);
		setverdict(pass);
		T.stop;
		}
	[] PCU.receive { repeat; }
	[] T.timeout {
		setverdict(fail, "Timeout waiting for RACH.ind on the PCU interface");
		/* Keep going, that's not the end of the world */
		}
	}
}

testcase TC_pcu_ptcch() runs on test_CT {
	var L1ctlMessage dl;
	var octetstring data;
	timer T;

	f_init_with_pcuif();
	f_init_l1ctl();
	f_l1_tune(L1CTL);

	/* Activate PDCH channel on TS7 */
	f_TC_pcu_act_req(0, 0, 7, true);

	/* Tune the L1 to that PDCH channel */
	f_TC_pcu_l1ctl_est_pdch(7);
	L1CTL.send(ts_L1CTL_GPRS_DL_TBF_CFG_REQ(0, '00000001'B));

	/* Verify PTCCH/U: send several access bursts, make sure they're received */
	for (var integer i := 0; i < 16; i := i + 1) {
		log("Sending an Access Burst towards the L1CTL interface");
		f_TC_pcu_ptcch_ul(oct2int(f_rnd_ra_ps()));
	}

	/* Generate a random payload for PTCCH/D (23 octets, CS-1) */
	data := f_rnd_octstring(23);

	/* Verify PTCCH/D: send a random data block, make sure it's received */
	log("Sending a PTCCH/D block towards the PCU interface: ", data);
	f_pcu_wait_rts_and_data_req(0, 0, 7, PCU_IF_SAPI_PTCCH, data);

	/* PTCCH/D period is 2 multi-frames (2 * 52 * 4.615 ms), but
	 * let's give it more time in case if we miss the beginning. */
	T.start(2.0 * 2.0 * 52.0 * 4.615 / 1000.0);
	alt {
	[] L1CTL.receive(tr_L1CTL_GPRS_DL_BLOCK_IND(fn := ?, tn := 7, data := data)) {
		setverdict(pass);
		T.stop;
		}
	[] L1CTL.receive { repeat; }
	[] T.timeout {
		setverdict(fail, "Timeout waiting DL BLOCK.ind with PTCCH/D");
		}
	}
}

/* Send AGCH from PCU; check it appears on Um side */
testcase TC_pcu_data_req_agch() runs on test_CT {
	timer T := 3.0;
	f_init_with_pcuif();
	f_init_l1ctl();
	f_l1_tune(L1CTL);

	f_TC_pcu_act_req(0, 0, 7, true);
	f_pcu_data_req(0, 0, 7, 0, 0, PCU_IF_SAPI_AGCH, c_PCU_DATA);

	T.start;
	alt {
	[] L1CTL.receive(tr_L1CTL_DATA_IND(t_RslChanNr_PCH_AGCH(0), ?, c_PCU_DATA)) {
		setverdict(pass);
		}
	[] L1CTL.receive { repeat; }
	[] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for PCU-originated AGCH block on Um");
		}
	}
}

/* Send AGCH from PCU; check it appears on Um side */
testcase TC_pcu_data_req_pch() runs on test_CT {
	timer T := 3.0;
	f_init_with_pcuif();
	f_init_l1ctl();
	f_l1_tune(L1CTL);

	f_TC_pcu_act_req(0, 0, 7, true);
	/* three characters prefix: last 3 digits of IMSI as ASCII */
	f_pcu_data_req(0, 0, 7, 0, 0, PCU_IF_SAPI_PCH, '313233'O & c_PCU_DATA);

	T.start;
	alt {
	[] L1CTL.receive(tr_L1CTL_DATA_IND(t_RslChanNr_PCH_AGCH(0), ?, c_PCU_DATA)) {
		setverdict(pass);
		}
	[] L1CTL.receive { repeat; }
	[] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for PCU-originated PCH block on Um");
		}
	}
}

/* Send IMM.ASS from PCU for PCH; check it appears on Um side */
testcase TC_pcu_data_req_imm_ass_pch() runs on test_CT {
	var octetstring imm_ass := f_rnd_octstring(23);
	f_init_with_pcuif();
	f_init_l1ctl();
	f_l1_tune(L1CTL);

	/* append 3 last imsi digits so BTS can compute pagng group */
	var uint32_t fn := f_PCUIF_tx_imm_ass_pch(PCU, g_pcu_conn_id, imm_ass, '123459987'H);

	timer T := 0.5;
	T.start;
	alt {
	[] L1CTL.receive(tr_L1CTL_DATA_IND(t_RslChanNr_PCH_AGCH(0), ?, imm_ass)) {
		/* TODO: verify paging group */
		setverdict(pass);
		}
	[] L1CTL.receive { repeat; }
	[] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for PCU-originated AGCH block on Um");
		}
	}
}

/* Send RACH from Um side, expect it to show up on PCU socket */
testcase TC_pcu_rach_content() runs on test_CT {
	f_init_with_pcuif();
	f_init_l1ctl();
	f_l1_tune(L1CTL);

	var GsmFrameNumber fn_last := 0;
	for (var integer i := 0; i < 1000; i := i+1) {
		var PCUIF_Message msg;
		var OCT1 ra := f_rnd_ra_ps();
		var GsmFrameNumber fn := f_L1CTL_RACH(L1CTL, oct2int(ra));
		if (fn == fn_last) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Two RACH in same FN?!?");
		}
		fn_last := fn;

		timer T := 2.0;
		T.start;
		alt {
		[] as_pcuif_msg(msg, tr_PCUIF_RACH_IND(0, 0, 0, oct2int(ra), 0, ?, fn)) {
			T.stop;
			}
		[] as_pcuif_msg(msg, tr_PCUIF_RACH_IND) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Unexpected RACH IND");
			}
		[] PCU.receive { repeat; }
		[] T.timeout {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for RACH IND");
			}
		}
	}
	setverdict(pass);
}

/* Send extended (11-bit, TS1 & TS2) RACH bursts from the Um side,
 * expect them to show up on PCU socket (with proper BURST_TYPE_*). */
testcase TC_pcu_ext_rach_content() runs on test_CT {
	var template PCUIF_Message pcu_rach_ind;
	var GsmFrameNumber fn_last := 0;
	var L1ctlRachSynchSeq synch_seq;
	var PCUIF_BurstType pcu_bt;
	var GsmFrameNumber fn
	var BIT11 ra11;

	f_init_with_pcuif();
	f_init_l1ctl();
	f_l1_tune(L1CTL);

	for (var integer i := 0; i < 1000; i := i+1) {
		/* We need to test both TS1 & TS2 */
		if (i rem 2 == 0) {
			synch_seq := RACH_SYNCH_SEQ_TS1;
			pcu_bt := BURST_TYPE_1;
		} else {
			synch_seq := RACH_SYNCH_SEQ_TS2;
			pcu_bt := BURST_TYPE_2;
		}

		ra11 := f_rnd_ra11_ps();
		fn := f_L1CTL_EXT_RACH(L1CTL, bit2int(ra11), synch_seq);
		if (fn == fn_last) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
						"Two RACH in same FN?!?");
		}
		fn_last := fn;

		/* Compose the expected message */
		pcu_rach_ind := tr_PCUIF_RACH_IND(
			bts_nr := 0, trx_nr := 0, ts_nr := 0,
			ra := bit2int(ra11),
			is_11bit := 1,
			burst_type := pcu_bt,
			fn := fn);

		var PCUIF_Message msg;
		timer T := 2.0;
		T.start;
		alt {
		[] as_pcuif_msg(msg, pcu_rach_ind) {
			T.stop;
			}
		[] as_pcuif_msg(msg, tr_PCUIF_RACH_IND) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Unexpected RACH IND");
			}
		[] PCU.receive { repeat; }
		[] T.timeout {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for RACH IND");
			}
		}
	}
	setverdict(pass);
}

private function f_TC_pcu_data_ind_lqual_cb(int16_t lqual_cb_exp, int16_t thresh)
runs on test_CT {
	var PCUIF_Message msg;
	var int16_t lqual_cb;
	timer T := 1.0;

	/* Send a random PDTCH frame over Um
	 * FIXME: we need to wait for a DL block and user Fn from there. */
	L1CTL.send(ts_L1CTL_GPRS_UL_BLOCK_REQ(0, 7, '0000'O & f_rnd_octstring(21)));

	T.start;
	alt {
	/* If expected link quality is above the threshold */
	[lqual_cb_exp >= thresh] as_pcuif_msg(msg, tr_PCUIF_DATA_IND) {
		lqual_cb := msg.u.data_ind.lqual_cb;
		log("Rx PCUIF_DATA.ind (lqual_cb=", lqual_cb, ")");

		/* Make sure the actual link quality matches the expected value */
		if (not match(lqual_cb, lqual_cb_exp)) {
			setverdict(fail, log2str("Link quality ", lqual_cb, " does not match ",
						 "expected value ", lqual_cb_exp));
		} else {
			setverdict(pass);
		}
		}
	/* If expected link quality is below the threshold */
	[lqual_cb_exp < thresh] as_pcuif_msg(msg, tr_PCUIF_DATA_IND) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
					log2str("Rx unexpected PCUIF_DATA.ind: ", msg));
		}
	/* Ignore PCUIF_RTS.req and PCUIF_TIME.ind */
	[] PCU.receive { repeat; }
	[lqual_cb_exp < thresh] T.timeout {
		log("Rx nothing, as expected");
		setverdict(pass);
		}
	[lqual_cb_exp >= thresh] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
					"Timeout waiting for PCUIF_DATA.ind");
		}
	}
}

/* Verify C/I (Carrier-to-Interference ratio) processing of PDTCH frames */
testcase TC_pcu_data_ind_lqual_cb() runs on test_CT {
	f_init_with_pcuif();
	PCU.clear;

	f_init_l1ctl();
	f_l1_tune(L1CTL);

	/* Activate a PDCH channel on TS7 */
	f_TC_pcu_act_req(0, 0, 7, true);

	/* Tune trxcon to that PDCH channel on TS7 */
	f_TC_pcu_l1ctl_est_pdch(7);
	L1CTL.send(ts_L1CTL_GPRS_UL_TBF_CFG_REQ(0, '00000001'B));

	/* C/I in centiBels, test range: -256 .. +1280, step 128 */
	for (var int16_t i := -256; i <= 1280; i := i + 128) {
		var TrxcMessage ret;

		ret := f_TRXC_transceive(BTS_TRXC, g_bts_trxc_conn_id, ts_TRXC_FAKE_CI(i));

		/* FIXME: OsmoBTS may have different threshold (see MIN_QUAL_NORM) */
		log("Testing C/I=", i, " cB");
		f_TC_pcu_data_ind_lqual_cb(i, thresh := 0);
	}
}

/* Send PAGING via RSL, expect it to shw up on PCU socket */
testcase TC_pcu_paging_from_rsl() runs on test_CT {
	f_init_with_pcuif();

	for (var integer i := 0; i < 100; i := i+1) {
		var MobileIdentityLV mi_lv;
		var octetstring mi_lv_enc;
		var MobileIdentityV mi;
		var PCUIF_Message msg;
		timer T := 3.0;

		if (i < 50) {
			mi := valueof(t_MI_TMSI(f_rnd_octstring(4)));
		} else {
			mi := valueof(ts_MI_IMSI(f_gen_imsi(i)));
		}

		/* Fancy encoding for PCUIF */
		mi_lv := valueof(ts_MI_LV(mi));
		mi_lv_enc := enc_MobileIdentityLV(mi_lv);
		mi_lv_enc := f_pad_oct(mi_lv_enc, 9, '00'O);

		/* Send RSL PAGING COMMAND */
		RSL_CCHAN.send(ts_ASP_RSL_UD(ts_RSL_PAGING_CMD(mi, i mod 4)));
		T.start;
		alt {
		[] as_pcuif_msg(msg, tr_PCUIF_PAG_REQ(0, mi_lv_enc)) {
			}
		[] as_pcuif_msg(msg, tr_PCUIF_PAG_REQ) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Unexpected PAGING REQ");
			}
		[] PCU.receive { repeat; }
		[] T.timeout {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for PAGING REQ");
			}
		}
	}
	setverdict(pass);
}

/* test for periodic TIME_IND; check number of FN expired and number of TIME_IND within frames */
testcase TC_pcu_time_ind() runs on test_CT {
	var integer num_time_ind := 0;
	var integer first_fn, last_fn;
	var float test_duration := 5.0;
	var PCUIF_Message msg;
	timer T;

	f_init_with_pcuif();
	f_TC_pcu_act_req(0, 0, 7, true);

	PCU.clear;
	T.start(test_duration);
	alt {
	[] as_pcuif_msg(msg, tr_PCUIF_TIME_IND(0, ?)) {
		num_time_ind := num_time_ind + 1;
		if (not isbound(first_fn)) {
			first_fn := msg.u.time_ind.fn;
		}
		last_fn := msg.u.time_ind.fn;
		repeat;
		}
	[] as_pcuif_msg(msg, tr_PCUIF_TIME_IND(?, ?)) {
		setverdict(fail, "Received unexpected PCUIF_TIME_IND: ", msg);
		repeat;
		}
	[] PCU.receive {
		repeat;
		}
	[] T.timeout {}
	}
	var integer fn_expired := last_fn - first_fn;
	log(fn_expired, " fn expired with ", num_time_ind, " PCU_TIME.ind");

	/* verify the number of frames expired matches our expectation */
	const float c_GSM_FN_DURATION_MS := 4.61538;
	var float fn_expected := test_duration * 1000.0 / c_GSM_FN_DURATION_MS;
	var template integer t_fn_expected := f_tolerance(float2int(fn_expected), 1, 100000, 20);
	if (not match(fn_expired, t_fn_expected)) {
		setverdict(fail, "Number of TDMA Frames (", fn_expired, ") not matching ", t_fn_expected);
	}

	/* There are three TIME.ind in every fn MOD 13 */
	var float time_ind_expected := int2float(fn_expired) * 3.0 / 13.0;
	/* Add some tolerance */
	var template integer t_time_ind_exp := f_tolerance(float2int(time_ind_expected), 1, 100000, 5);
	if (not match(num_time_ind, t_time_ind_exp)) {
		setverdict(fail, "Number of TIME.ind (", num_time_ind, ") not matching ", t_time_ind_exp);
	}

	setverdict(pass);
}

/* test for periodic RTS_REQ; check number of FN expired and number of RTS_IND per SAPI */
testcase TC_pcu_rts_req() runs on test_CT {
	var integer first_fn, last_fn;
	var integer num_rts_pdtch := 0;
	var integer num_rts_ptcch := 0;
	var float test_duration := 5.0;
	var PCUIF_Message msg;
	timer T;

	f_init_with_pcuif();
	f_TC_pcu_act_req(0, 0, 7, true);

	PCU.clear;
	T.start(test_duration);
	alt {
	[] as_pcuif_msg(msg, tr_PCUIF_RTS_REQ(0, 0, 7, PCU_IF_SAPI_PDTCH, ?, ?)) {
		num_rts_pdtch := num_rts_pdtch + 1;
		if (not isbound(first_fn)) {
			first_fn := msg.u.rts_req.fn;
		}
		last_fn := msg.u.rts_req.fn;
		repeat;
		}
	[] as_pcuif_msg(msg, tr_PCUIF_RTS_REQ(0, 0, 7, PCU_IF_SAPI_PTCCH, ?, ?)) {
		num_rts_ptcch := num_rts_ptcch + 1;
		if (not isbound(first_fn)) {
			first_fn := msg.u.rts_req.fn;
		}
		last_fn := msg.u.rts_req.fn;
		repeat;
		}
	[] as_pcuif_msg(msg, tr_PCUIF_RTS_REQ) {
		setverdict(fail, "Received unexpected PCUIF_RTS_REQ: ", msg);
		repeat;
		}
	[] PCU.receive {
		repeat;
		}
	[] T.timeout {}
	}
	var integer fn_expired := last_fn - first_fn;
	log(fn_expired, " fn expired with num_rts_pdtch=", num_rts_pdtch,
		", num_rts_ptcch=", num_rts_ptcch);

	/* verify the number of frames expired matches our expectation */
	const float c_GSM_FN_DURATION_MS := 4.61538;
	var float fn_expected := test_duration * 1000.0 / c_GSM_FN_DURATION_MS;
	var template integer t_fn_expected := f_tolerance(float2int(fn_expected), 1, 100000, 20);
	if (not match(fn_expired, t_fn_expected)) {
		setverdict(fail, "Number of TDMA Frames (", fn_expired, ") not matching ", t_fn_expected);
	}

	/* PTCCH is in pos. 12 + 38 of 52-multiframe, but four slots/bursts required per block */
	var float ptcch_expected := int2float(fn_expired) / 52.0 * 0.5;
	var template integer t_ptcch_exp := f_tolerance(float2int(ptcch_expected), 1, 100000, 1);
	if (not match(num_rts_ptcch, t_ptcch_exp)) {
		setverdict(fail, "Number of RTS.ind for PTCCH (", num_rts_ptcch, ") not matching ",
				t_ptcch_exp);
	}

	/* We have 12 PDTCH blocks every 52-multiframe */
	var float pdtch_expected := int2float(fn_expired) / 52.0 * 12.0;
	var template integer t_pdtch_exp := f_tolerance(float2int(pdtch_expected), 1, 100000, 2);
	if (not match(num_rts_pdtch, t_pdtch_exp)) {
		setverdict(fail, "Number of RTS.ind for PDTCH (", num_rts_pdtch, ") not matching ",
				t_pdtch_exp);
	}

	setverdict(pass);
}

/* test for generating Abis side OML ALERT from the PCU */
testcase TC_pcu_oml_alert() runs on test_CT {
	var PCUIF_send_data pcu_sd;
	var integer num_time_ind := 0;
	var integer first_fn, last_fn;
	var float test_duration := 5.0;
	timer T;

	f_init_with_pcuif();
	f_TC_pcu_act_req(0, 0, 7, true);

	/* re-connect CTRL port from BTS to BSC */
	f_ipa_ctrl_stop();
	f_ipa_ctrl_start_client(mp_bsc_ctrl_ip, mp_bsc_ctrl_port);

	/* Send that OML Alert */
	PCU.send(t_SD_PCUIF(g_pcu_conn_id, ts_PCUIF_TXT_IND(0, PCU_OML_ALERT, testcasename())));

	/* This requires https://gerrit.osmocom.org/#/c/osmo-bsc/+/14177 to be merged */
	f_ctrl_exp_trap(IPA_CTRL, "bts.0.oml_failure_report", ?);
	setverdict(pass);
}

/* test for forwarding of RR SUSPEND from CS lchan to PCU via PCU socket */
private function f_TC_rr_suspend_req(charstring id) runs on ConnHdlr {
	var PCUIF_Message first_info;
	var integer pcu_conn_id := -1;
	var RslLinkId link_id := valueof(ts_RslLinkID_DCCH(0));
	var RoutingAreaIdentificationV rai := f_RAI('262'H, '42F'H, '2342'O, '55'O);
	var OCT4 tlli := '01020304'O;
	var OCT1 cause := '23'O;
	timer T := 5.0;

	f_init_pcu(PCU, id, pcu_conn_id, first_info);

	f_l1_tune(L1CTL);
	RSL.clear;

	f_est_dchan();
	L1CTL.clear;

	f_est_rll_mo(link_id.sapi, link_id, '23420815'O);

	var PDU_ML3_MS_NW susp_req := valueof(ts_RRM_GprsSuspReq(tlli, rai, cause));
	var octetstring l3 := enc_PDU_ML3_MS_NW(susp_req);
	f_tx_lapdm(ts_LAPDm_I(link_id.sapi, cr_MO_CMD, true, 1, 0, l3), link_id);

	/* ConnHdlr has terminated after sending the RR SUSP REQ over a dedicaed channel */
	T.start;
	alt {
	[] PCU.receive(t_SD_PCUIF(pcu_conn_id, tr_PCUIF_SUSP_REQ(0, tlli, ?, oct2int(cause)))) {
		setverdict(pass);
		}
	[] PCU.receive(t_SD_PCUIF(pcu_conn_id, tr_PCUIF_SUSP_REQ(?, ?, ?, ?))) {
		setverdict(fail, "Received unexpected PCUIF SUSPE REQ: ");
		}
	[] PCU.receive {
		repeat;
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for SUSP REQ on PCUIF");
		}
	}

	/* release the channel */
	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
	f_rslem_unregister(0, g_chan_nr);
}
testcase TC_pcu_rr_suspend() runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;

	f_init_with_pcuif();

	pars := valueof(t_Pars(t_RslChanNr_SDCCH4(0,3), ts_RSL_ChanMode_SIGN));
	vc_conn := f_start_handler(refers(f_TC_rr_suspend_req), pars, true);
	vc_conn.done;
}

/* Ensure that PCUIF socket can accept only a single connection */
testcase TC_pcu_socket_connect_multi() runs on test_CT {
	var boolean connected := false;
	var UD_connect_result cr;
	var integer cid;
	timer T := 5.0;

	var template UD_Result tr_ok := { result_code := SUCCESS, err := omit };
	var template UD_Result tr_err := { result_code := ERROR, err := ? };

	/* this (among other things) establishes the first connection to the PCUIF socket */
	f_init_with_pcuif();

	/* try to establish a second connection */
	PCU.send(UD_connect:{mp_pcu_socket, -1});
	T.start;
	alt {
	/* the IUT will first accept() the new connection, and close() it immediately */
	[not connected] PCU.receive(UD_connect_result:{ id := ?, result := tr_ok }) -> value cr {
		log("BTS has accept()ed connection");
		connected := true;
		cid := cr.id;
		repeat;
		}
	[connected] PCU.receive(UD_connect_result:{ id := cid, result := tr_err }) {
		log("BTS has close()d connection");
		setverdict(pass);
		}
	/* ignore other messages related to the first connection */
	[] PCU.receive { repeat; }
	[] T.timeout {
		setverdict(fail, "Timeout waiting for connection result");
		}
	}

	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/* Ensure that PCUIF socket can disconnect + reconnect */
testcase TC_pcu_socket_reconnect() runs on test_CT {
	/* this (among other things) establishes the first connection to the PCUIF socket */
	f_init_with_pcuif();

	f_sleep(1.0);

	f_pcuif_close(PCU, g_pcu_conn_id);
	g_pcu_conn_id := -1;

	f_sleep(1.0);

	/* re-connect */
	PCU.clear;
	f_init_pcu(PCU, testcasename(), g_pcu_conn_id, g_pcu_last_info);
	setverdict(pass);

	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/* Ensure that GPRS capability is not advertised before PCU socket conncet */
private function f_get_si(L1CTL_PT pt, RrMessageType si_type)
runs on test_CT return SystemInformation {
	var L1ctlMessage l1_dl;
	var SystemInformation si;
	var integer rc;
	timer T := 5.0;
	T.start;
	alt {
	[] pt.receive(tr_L1CTL_DATA_IND(t_RslChanNr_BCCH(0), ?)) -> value l1_dl {
		rc := dec_SystemInformationSafe(l1_dl.payload.data_ind.payload, si);
		if (rc != 0 or si.header.message_type != si_type) {
			repeat;
		}
		}
	[] pt.receive {
		repeat;
		}
	[] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
					log2str("Timeout waiting for ", si_type));
		}
	}
	return si;
}

/* Check if GPRS Indicator is present in RR System Information of a given type */
private function f_si_has_gprs_indicator(RrMessageType si_type)
runs on test_CT return boolean {
	var SystemInformation si := f_get_si(L1CTL, si_type);

	if (si_type == SYSTEM_INFORMATION_TYPE_3) {
		return si.payload.si3.rest_octets.gprs_ind.presence == '1'B;
	} else if (si_type == SYSTEM_INFORMATION_TYPE_4) {
		return si.payload.si4.rest_octets.gprs_ind.presence == '1'B;
	}

	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Unhandled SI type");
	return false;
}

/* Make sure that GPRS Indicator is absent when the PCU is not connected */
private function f_TC_pcu_socket_noconnect(RrMessageType si_type)
runs on test_CT {
	f_init();
	f_init_l1ctl();
	f_l1_tune(L1CTL);
	f_sleep(2.0);
	L1CTL.clear;

	if (f_si_has_gprs_indicator(si_type)) {
		setverdict(fail, si_type, " indicates GPRS even before PCU socket connected");
	} else {
		setverdict(pass);
	}

	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

testcase TC_pcu_socket_noconnect_nosi3gprs() runs on test_CT {
	f_TC_pcu_socket_noconnect(SYSTEM_INFORMATION_TYPE_3);
}

testcase TC_pcu_socket_noconnect_nosi4gprs() runs on test_CT {
	f_TC_pcu_socket_noconnect(SYSTEM_INFORMATION_TYPE_4);
}

/* Ensure that GPRS capability is advertised after PCU socket connect */
private function f_TC_pcu_socket_connect(RrMessageType si_type)
runs on test_CT {
	/* this (among other things) establishes the first connection to the PCUIF socket */
	f_init_with_pcuif();
	f_init_l1ctl();
	f_l1_tune(L1CTL);

	f_sleep(2.0);
	L1CTL.clear;

	if (not f_si_has_gprs_indicator(si_type)) {
		setverdict(fail, si_type, " indicates no GPRS despite PCU socket connected");
	} else {
		setverdict(pass);
	}

	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

testcase TC_pcu_socket_connect_si3gprs() runs on test_CT {
	f_TC_pcu_socket_connect(SYSTEM_INFORMATION_TYPE_3);
}

testcase TC_pcu_socket_connect_si4gprs() runs on test_CT {
	f_TC_pcu_socket_connect(SYSTEM_INFORMATION_TYPE_4);
}

/* Ensure that GPRS capability is no longer advertised after PCU socket disconnect */
private function f_TC_pcu_socket_disconnect(RrMessageType si_type)
runs on test_CT {
	/* this (among other things) establishes the first connection to the PCUIF socket */
	f_init_with_pcuif();
	f_init_l1ctl();
	f_l1_tune(L1CTL);

	f_pcuif_close(PCU, g_pcu_conn_id);
	g_pcu_conn_id := -1;

	f_sleep(1.0);

	/* re-connect */
	PCU.clear;
	f_init_pcu(PCU, testcasename(), g_pcu_conn_id, g_pcu_last_info);

	f_sleep(2.0);
	L1CTL.clear;

	if (f_si_has_gprs_indicator(si_type)) {
		setverdict(fail, si_type, " indicates GPRS after PCU socket disconnected");
	} else {
		setverdict(pass);
	}

	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

testcase TC_pcu_socket_disconnect_nosi3gprs() runs on test_CT {
	f_TC_pcu_socket_disconnect(SYSTEM_INFORMATION_TYPE_3);
}

testcase TC_pcu_socket_disconnect_nosi4gprs() runs on test_CT {
	f_TC_pcu_socket_disconnect(SYSTEM_INFORMATION_TYPE_4);
}

/* Verify that the cell_id of SI3 (TS 04.08 9.1.35) and other values are passed properly to the PCU socket (OS#3854) */
testcase TC_pcu_socket_verify_info_ind() runs on test_CT {
	var SystemInformation si3 := valueof(ts_SI3_default);

	f_init_with_pcuif();

	/* actually give the BTS some time to fully come up and to send a PCU INFO IND with the correct
	 * information */
	timer T := 2.0;
	T.start;
	alt {
	[] as_pcu_info_ind(PCU, g_pcu_conn_id, g_pcu_last_info) { repeat; }
	[] T.timeout {}
	}

	/* Verify cell_id */
	var uint16_t cell_id_si3 := si3.payload.si3.cell_id;
	var uint16_t cell_id_pcu := g_pcu_last_info.u.info_ind.cell_id;
	if (cell_id_si3 != cell_id_pcu) {
		setverdict(fail, "Expected cell_id '", cell_id_si3, "' and got '", cell_id_pcu, "'. This either means,",
				 " that the BTS is sending the wrong cell_id, or that the BTS sent it too early",
				 " (OS#4179)");
	}

	/* Verify LAC */
	var uint16_t lac_si3 := si3.payload.si3.lai.lac;
	var uint16_t lac_pcu := g_pcu_last_info.u.info_ind.lac;
	if (lac_si3 != lac_pcu) {
		setverdict(fail, "Expected LAC ", lac_si3, " got: ", lac_pcu);
	}

	setverdict(pass);
}

/* Verify hopping parameters in the INFO.ind message (version >= 10) */
testcase TC_pcu_info_ind_fh_params() runs on test_CT {
	var PCUIF_info_ind info_ind;
	var FreqHopPars fhp;

	f_init_with_pcuif();

	info_ind := g_pcu_last_info.u.info_ind;

	for (var integer i := 0; i < mp_transceiver_num; i := i + 1) {
		for (var integer tn := 0; tn < 8; tn := tn + 1) {
			if (info_ind.trx[i].pdch_mask[tn] != '1'B) {
				/* Skip inactive timeslots */
				continue;
			}

			if (mp_freq_hop_enabled and mp_transceiver_num > 1)
				{ f_resolve_fh_params(fhp, tn, trx_nr := i); }
			else
				{ fhp.enabled := false; }

			var template PCUIF_InfoTrxTs tr_ts;
			if (fhp.enabled) {
				tr_ts := tr_PCUIF_InfoTrxTsH1(
						hsn := fhp.maio_hsn.hsn,
						maio := fhp.maio_hsn.maio,
						ma := f_pad_bit(fhp.ma_map.ma, 64, '0'B),
						ma_bit_len := mp_transceiver_num);
			} else {
				tr_ts := tr_PCUIF_InfoTrxTsH0;
			}

			var PCUIF_InfoTrxTs ts := info_ind.trx[i].ts[tn];
			log("Checking timeslot #", tn, " of trx#", i, ": ", ts);
			if (not match(ts, tr_ts)) {
				setverdict(fail, "Hopping parameters do not match: ",
					   "received ", ts, " vs expected ", tr_ts);
			} else {
				setverdict(pass);
			}
		}
	}
}

/* Verify IPv4 NSVC address in the INFO.ind message */
testcase TC_pcu_socket_nsvc_ipv4() runs on test_CT {
	f_init_vty_bsc();
	f_vty_config2(BSCVTY, {"network", "bts 0"} , "gprs nsvc 0 remote ip 127.127.127.127");
	f_vty_transceive(BSCVTY, "drop bts connection 0 oml");

	f_init_with_pcuif();

	var PCUIF_RemoteAddr remote_addr := g_pcu_last_info.u.info_ind.remote_addr;
	var template PCUIF_RemoteAddr tr_remote_addr := {
		addr_type := { PCUIF_ADDR_TYPE_IPV4, ? },
		addr := { f_pad_oct(f_inet_addr("127.127.127.127"), 16, '00'O), ? }
	};

	if (not match(remote_addr, tr_remote_addr)) {
		setverdict(fail, "NSVC address ", remote_addr, " does not match ", tr_remote_addr);
	}

	setverdict(pass);
}

/* Verify IPv4 NSVC address in the INFO.ind message */
testcase TC_pcu_socket_nsvc_ipv6() runs on test_CT {
	f_init_vty_bsc();
	f_vty_config2(BSCVTY, {"network", "bts 0"} , "gprs nsvc 0 remote ip fd00::ca:ff:ee");

	f_init_with_pcuif();

	var PCUIF_RemoteAddr remote_addr := g_pcu_last_info.u.info_ind.remote_addr;
	var template PCUIF_RemoteAddr tr_remote_addr := {
		addr_type := { PCUIF_ADDR_TYPE_IPV6, ? },
		addr := { f_inet6_addr("fd00::ca:ff:ee"), ? }
	};

	if (not match(remote_addr, tr_remote_addr)) {
		setverdict(fail, "NSVC address ", remote_addr, " does not match ", tr_remote_addr);
	}

	setverdict(pass);
}

/* Verify coding of two NSVCs in the INFO.ind message */
testcase TC_pcu_socket_two_nsvc() runs on test_CT {
	f_init_vty_bsc();

	f_vty_config2(BSCVTY, {"network", "bts 0"} , "gprs nsvc 0 nsvci 1234");
	f_vty_config2(BSCVTY, {"network", "bts 0"} , "gprs nsvc 0 local udp port 1234");
	f_vty_config2(BSCVTY, {"network", "bts 0"} , "gprs nsvc 0 remote ip 127.127.127.127");
	f_vty_config2(BSCVTY, {"network", "bts 0"} , "gprs nsvc 0 remote udp port 1234");

	f_vty_config2(BSCVTY, {"network", "bts 0"} , "gprs nsvc 1 nsvci 5678");
	f_vty_config2(BSCVTY, {"network", "bts 0"} , "gprs nsvc 1 local udp port 5678");
	f_vty_config2(BSCVTY, {"network", "bts 0"} , "gprs nsvc 1 remote ip fd00::ca:ff:ee");
	f_vty_config2(BSCVTY, {"network", "bts 0"} , "gprs nsvc 1 remote udp port 5678");

	f_init_with_pcuif();

	var PCUIF_info_ind info_ind := g_pcu_last_info.u.info_ind;
	var PCUIF_RemoteAddr remote_addr := info_ind.remote_addr;
	var template PCUIF_RemoteAddr tr_remote_addr := {
		addr_type := { PCUIF_ADDR_TYPE_IPV4, PCUIF_ADDR_TYPE_IPV6 },
		addr := {
			f_pad_oct(f_inet_addr("127.127.127.127"), 16, '00'O),
			f_inet6_addr("fd00::ca:ff:ee")
		}
	};

	if (not match(info_ind.nsvci, { 1234, 5678 }))
		{ setverdict(fail, "NSVCI ", info_ind.nsvci, " does not match { 1234, 5678 }"); }
	if (not match(remote_addr, tr_remote_addr))
		{ setverdict(fail, "NSVC address ", remote_addr, " does not match ", tr_remote_addr); }
	if (not match(info_ind.local_port, { 1234, 5678 }))
		{ setverdict(fail, "NSVC lport ", info_ind.local_port, " does not match { 1234, 5678 }"); }
	if (not match(info_ind.remote_port, { 1234, 5678 }))
		{ setverdict(fail, "NSVC rport ", info_ind.remote_port, " does not match { 1234, 5678 }"); }

	setverdict(pass);
}

/* Verify periodic interference reports on PDCH */
testcase TC_pcu_interf_ind() runs on test_CT {
	var template PCUIF_Message tr_interf_ind;
	var integer interf_ind_num := 0;
	var boolean first := true;
	var PCUIF_Message msg;
	timer T;

	/* Set the averaging/reporting period to 480ms */
	f_init_vty_bsc();
	f_vty_cfg_bts(BSCVTY, 0, { "interference-meas avg-period 1" });
	f_vty_transceive(BSCVTY, "drop bts connection 0 oml");

	f_init_with_pcuif();
	f_TC_pcu_act_req(0, 0, 7, true);

	/* We need trxcon for NOPE indications */
	f_init_l1ctl();
	f_l1_tune(L1CTL);

	/* Expect -120 .. -90 dBm on TS7 of BTS0/TRX0 */
	tr_interf_ind := tr_PCUIF_INTERF_IND(
		bts_nr := 0,
		trx_nr := 0,
		fn := ?,
		interf := { 0, 0, 0, 0, 0, 0, 0, (90..120) }
	);

	T.start(0.480 * 1.5);
	alt {
	/* The first interference report may contain unreliable values, so we ignore it */
	[first] as_pcuif_msg(msg, tr_PCUIF_INTERF_IND(0, 0)) {
		/* 4 SACCH periods => 4 reports (plus some guard time) */
		T.start(0.480 * 4.0 + 0.480 / 2.0);
		first := false;
		repeat;
		}
	/* Subsequent interference reports shall match our expectations */
	[not first] as_pcuif_msg(msg, tr_interf_ind) {
		/* Check TDMA frame number period */
		if (msg.u.interf_ind.fn mod 104 != 0) {
			setverdict(fail, "Odd TDMA frame number := ",
				   msg.u.interf_ind.fn);
		}
		interf_ind_num := interf_ind_num + 1;
		if (interf_ind_num < 4)
			{ repeat; }
		}
	[not first] as_pcuif_msg(msg, tr_PCUIF_INTERF_IND(0, 0)) {
		setverdict(fail, "Received unexpected interference report: ", msg);
		}
	[] PCU.receive { repeat; }
	[] T.timeout {
		setverdict(fail, "Timeout waiting for interference reports");
		}
	}

	/* Reset the averaging/reporting period back to default */
	f_vty_cfg_bts(BSCVTY, 0, { "interference-meas avg-period 6" });

	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/***********************************************************************
 * Osmocom Style Dynamic Timeslot Support
 ***********************************************************************/

private altstep as_pcuif_check_pdch_mask(integer pcu_conn_id, BIT1 exp,
					 integer bts_nr, integer trx_nr)
runs on ConnHdlr {
	var PCUIF_send_data sd;

	[] PCU.receive(t_SD_PCUIF(pcu_conn_id, tr_PCUIF_INFO_IND(bts_nr, ?))) -> value sd {
		var BIT8 pdch_mask := sd.data.u.info_ind.trx[trx_nr].pdch_mask;
		if (substr(pdch_mask, g_chan_nr.tn, 1) != exp) {
			repeat;
		}
	}
}

private function f_dyn_osmo_pdch_act(integer pcu_conn_id, integer bts_nr, integer trx_nr)
runs on ConnHdlr {
	/* Expect BTS to immediately acknowledge activation as PDCH */
	PCU.clear;
	f_rsl_chan_act(g_pars.chan_mode);
	/* expect INFO_IND on PCU interface listing TS as PDCH */
	timer T_wait := 2.0;
	T_wait.start;
	alt {
	[] as_pcuif_check_pdch_mask(pcu_conn_id, '1'B, bts_nr, trx_nr);
	[] PCU.receive { repeat; }
	[] T_wait.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
			log2str("Timeout waiting for PCUIF_INFO_IND PDCH_MASK to be '1' on TS", g_chan_nr.tn));
		}
	}
	/* try to activate this PDCH from the PCU point of view */
	PCU.send(t_SD_PCUIF(pcu_conn_id, ts_PCUIF_ACT_REQ(bts_nr, trx_nr, g_chan_nr.tn)));
	/* FIXME: is there a response? */
}

private function f_dyn_osmo_pdch_deact(integer pcu_conn_id, integer bts_nr, integer trx_nr)
runs on ConnHdlr {
	/* Send RSL CHAN REL (deactivate) */
	PCU.clear;
	RSL.send(ts_RSL_RF_CHAN_REL(g_chan_nr));
	/* expect BTS to ask PCU to deactivate the channel */
	timer T_wait := 2.0;
	T_wait.start;
	alt {
	[] as_pcuif_check_pdch_mask(pcu_conn_id, '0'B, bts_nr, trx_nr);
	[] PCU.receive { repeat; }
	[] T_wait.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
			log2str("Timeout waiting for PCUIF_INFO_IND PDCH_MASK to be '0' on TS", g_chan_nr.tn));
		}
	}
	/* Emulate PCU asking BTS to deactivate PDCH */
	PCU.send(t_SD_PCUIF(pcu_conn_id, ts_PCUIF_DEACT_REQ(bts_nr, trx_nr, g_chan_nr.tn)));
	alt {
	[] RSL.receive(tr_RSL_RF_CHAN_REL_ACK(g_chan_nr)) {
		setverdict(pass);
		}
	[] RSL.receive { repeat; }
	}
}

/* Activate Osmocom-style dynamic PDCH from BSC side */
private function f_TC_dyn_osmo_pdch_act_deact(charstring id) runs on ConnHdlr {
	var PCUIF_Message first_info;
	var integer ts_nr := g_chan_nr.tn;
	var integer trx_nr := 0;
	var integer bts_nr := 0;
	var integer pcu_conn_id := -1;

	f_init_pcu(PCU, id, pcu_conn_id, first_info);

	f_dyn_osmo_pdch_act(pcu_conn_id, bts_nr, trx_nr);
	f_sleep(3.0);
	f_dyn_osmo_pdch_deact(pcu_conn_id, bts_nr, trx_nr);
	setverdict(pass);
}
testcase TC_dyn_osmo_pdch_act_deact() runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;
	f_init();

	pars := valueof(t_Pars(t_RslChanNr_PDCH(4), ts_RSL_ChanMode_SIGN));
	vc_conn := f_start_handler(refers(f_TC_dyn_osmo_pdch_act_deact), pars, true);
	vc_conn.done;
}

/* send a RF CHAN REL for PDCH on an osmocom dynamci PDCH that's already inactive */
private function f_TC_dyn_osmo_pdch_unsol_deact(charstring id) runs on ConnHdlr {
	var PCUIF_Message first_info;
	var integer pcu_conn_id := -1;

	f_init_pcu(PCU, id, pcu_conn_id, first_info);

	RSL.send(ts_RSL_RF_CHAN_REL(g_chan_nr));
	/* since the lchan is already released, we don't expect any PCU changes, just a rel ack. */
	RSL.receive(tr_RSL_RF_CHAN_REL_ACK(g_chan_nr));
	setverdict(pass);
}
testcase TC_dyn_osmo_pdch_unsol_deact() runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;
	f_init();

	pars := valueof(t_Pars(t_RslChanNr_PDCH(4), ts_RSL_ChanMode_SIGN));
	vc_conn := f_start_handler(refers(f_TC_dyn_osmo_pdch_unsol_deact), pars, true);
	vc_conn.done;
}

/* try to RSL CHAN ACT a PDCH on an osmocom-style PDCH that's already active */
private function f_TC_dyn_osmo_pdch_double_act(charstring id) runs on ConnHdlr {
	var PCUIF_Message first_info;
	var integer ts_nr := g_chan_nr.tn;
	var integer trx_nr := 0;
	var integer bts_nr := 0;
	var integer pcu_conn_id := -1;

	f_init_pcu(PCU, id, pcu_conn_id, first_info);

	f_dyn_osmo_pdch_act(pcu_conn_id, bts_nr, trx_nr);
	/* Send a second Chan Activ and expect it to be NACKed */
	f_rsl_transceive(ts_RSL_CHAN_ACT(g_chan_nr, g_pars.chan_mode), tr_RSL_CHAN_ACT_NACK(g_chan_nr),
			 "RSL CHAN ACT NACK");
	setverdict(pass);
}
testcase TC_dyn_osmo_pdch_double_act() runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;
	f_init();

	pars := valueof(t_Pars(t_RslChanNr_PDCH(4), ts_RSL_ChanMode_SIGN));
	vc_conn := f_start_handler(refers(f_TC_dyn_osmo_pdch_double_act), pars, true);
	vc_conn.done;
}

/* try to RSL CHAN ACT a TCH/F on an osmocom-style PDCH */
private function f_TC_dyn_osmo_pdch_tchf_act(charstring id) runs on ConnHdlr {
	var PCUIF_Message first_info;
	var integer ts_nr := g_chan_nr.tn;
	var integer trx_nr := 0;
	var integer bts_nr := 0;
	var integer pcu_conn_id := -1;
	var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(g_chan_nr.tn));

	/* register for the TCH/F channel number */
	f_rslem_register(0, chan_nr);

	f_init_pcu(PCU, id, pcu_conn_id, first_info);

	f_rsl_transceive(ts_RSL_CHAN_ACT(chan_nr, g_pars.chan_mode), tr_RSL_CHAN_ACT_ACK(chan_nr),
			 "RSL CHAN ACT");
	setverdict(pass);
}
testcase TC_dyn_osmo_pdch_tchf_act() runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;
	f_init();

	pars := valueof(t_Pars(t_RslChanNr_PDCH(4), ts_RSL_ChanMode_SIGN));
	vc_conn := f_start_handler(refers(f_TC_dyn_osmo_pdch_tchf_act), pars, true);
	vc_conn.done;
}

/* try to RSL CHAN ACT the TCH/H on an osmocom-style PDCH */
private function f_TC_dyn_osmo_pdch_tchh_act(charstring id) runs on ConnHdlr {
	var PCUIF_Message first_info;
	var integer ts_nr := g_chan_nr.tn;
	var integer trx_nr := 0;
	var integer bts_nr := 0;
	var integer pcu_conn_id := -1;
	var RslChannelNr chan_nr[2] := { valueof(t_RslChanNr_Lm(g_chan_nr.tn, 0)),
					 valueof(t_RslChanNr_Lm(g_chan_nr.tn, 1)) };

	/* register for the TCH/H channel numbers */
	f_rslem_register(0, chan_nr[0]);
	f_rslem_register(0, chan_nr[1]);

	f_init_pcu(PCU, id, pcu_conn_id, first_info);

	f_rsl_transceive(ts_RSL_CHAN_ACT(chan_nr[1], g_pars.chan_mode),
			 tr_RSL_CHAN_ACT_ACK(chan_nr[1]), "RSL CHAN ACT [1]");
	f_rsl_transceive(ts_RSL_CHAN_ACT(chan_nr[0], g_pars.chan_mode),
			 tr_RSL_CHAN_ACT_ACK(chan_nr[0]), "RSL CHAN ACT [0]");
	setverdict(pass);
}
testcase TC_dyn_osmo_pdch_tchh_act() runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;
	f_init();

	pars := valueof(t_Pars(t_RslChanNr_PDCH(4), ts_RSL_ChanMode_SIGN));
	vc_conn := f_start_handler(refers(f_TC_dyn_osmo_pdch_tchh_act), pars, true);
	vc_conn.done;
}

/* try to RSL CHAN ACT the SDCCH8 on an osmocom-style PDCH */
private function f_TC_dyn_osmo_pdch_sdcch8_act(charstring id) runs on ConnHdlr {
	var PCUIF_Message first_info;
	var integer ts_nr := g_chan_nr.tn;
	var integer trx_nr := 0;
	var integer bts_nr := 0;
	var integer pcu_conn_id := -1;
	var RslChannelNr chan_nr[8] := { valueof(t_RslChanNr_SDCCH8(g_chan_nr.tn, 0)),
					 valueof(t_RslChanNr_SDCCH8(g_chan_nr.tn, 1)),
					 valueof(t_RslChanNr_SDCCH8(g_chan_nr.tn, 2)),
					 valueof(t_RslChanNr_SDCCH8(g_chan_nr.tn, 3)),
					 valueof(t_RslChanNr_SDCCH8(g_chan_nr.tn, 4)),
					 valueof(t_RslChanNr_SDCCH8(g_chan_nr.tn, 5)),
					 valueof(t_RslChanNr_SDCCH8(g_chan_nr.tn, 6)),
					 valueof(t_RslChanNr_SDCCH8(g_chan_nr.tn, 7)) };

	/* register for the TCH/H channel numbers */
	for (var integer i := 0; i < lengthof(chan_nr); i := i + 1) {
		f_rslem_register(0, chan_nr[i]);
	}

	f_init_pcu(PCU, id, pcu_conn_id, first_info);

	for (var integer i := 0; i < lengthof(chan_nr); i := i + 1) {
		f_rsl_transceive(ts_RSL_CHAN_ACT(chan_nr[i], g_pars.chan_mode),
				 tr_RSL_CHAN_ACT_ACK(chan_nr[i]), "RSL CHAN ACT [" & int2str(i) & "]");
	}
	setverdict(pass);
}
testcase TC_dyn_osmo_pdch_sdcch8_act() runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;
	f_init();

	pars := valueof(t_Pars(t_RslChanNr_PDCH(4), ts_RSL_ChanMode_SIGN));
	vc_conn := f_start_handler(refers(f_TC_dyn_osmo_pdch_sdcch8_act), pars, true);
	vc_conn.done;
}

/* Reproduce a race condition described in OS#5245 */
private function f_rsl_chan_act_deact(charstring id) runs on ConnHdlr {
	f_rsl_chan_act(g_pars.chan_mode);
	f_sleep(1.0);
	f_rsl_chan_deact();
	setverdict(pass);
}
testcase TC_dyn_osmo_pdch_tchh_race_act() runs on test_CT {
	var ConnHdlrPars pars[2];
	var ConnHdlr vc_conn[2];
	var TrxcMessage rsp;

	f_init();

	/* Configure an artificial delay of 200 ms for TRXC RSP messages */
	rsp := f_TRXC_transceive(BTS_TRXC, g_bts_trxc_conn_id,
				 ts_TRXC_FAKE_TRXC_DELAY(200));

	/* Activate all sub-channels of TCH/H on TS4 immediately in hope that the second
	 * CHANnel ACTIVation message will be handled before the PHY responds to 'SETSLOT' */
	for (var integer i := 0; i < sizeof(pars); i := i + 1) {
		/* TS4 is an Osmocom style dynamic timeslot, we want it to be TCH/H */
		pars[i] := valueof(t_Pars(t_RslChanNr_Lm(4, i), ts_RSL_ChanMode_SIGN));
		vc_conn[i] := f_start_handler(refers(f_rsl_chan_act_deact),
					      pars[i], l1ctl := false);
	}

	/* Wait for all components to finish */
	for (var integer i := 0; i < sizeof(pars); i := i + 1) {
		vc_conn[i].done;
	}

	/* Disable the artificial delay for TRXC RSP messages */
	rsp := f_TRXC_transceive(BTS_TRXC, g_bts_trxc_conn_id,
				 ts_TRXC_FAKE_TRXC_DELAY(0));
}
testcase TC_dyn_osmo_pdch_sdcch8_race_act() runs on test_CT {
	var ConnHdlrPars pars[8];
	var ConnHdlr vc_conn[8];
	var TrxcMessage rsp;

	f_init();

	/* Configure an artificial delay of 200 ms for TRXC RSP messages */
	rsp := f_TRXC_transceive(BTS_TRXC, g_bts_trxc_conn_id,
				 ts_TRXC_FAKE_TRXC_DELAY(200));

	/* Activate all sub-channels of SDCCH/8 on TS4 immediately in hope that subsequent
	 * CHANnel ACTIVation messages will be handled before the PHY responds to 'SETSLOT' */
	for (var integer i := 0; i < sizeof(pars); i := i + 1) {
		/* TS4 is an Osmocom style dynamic timeslot, we want it to be SDCCH/8 */
		pars[i] := valueof(t_Pars(t_RslChanNr_SDCCH8(4, i), ts_RSL_ChanMode_SIGN));
		vc_conn[i] := f_start_handler(refers(f_rsl_chan_act_deact),
					      pars[i], l1ctl := false);
	}

	/* Wait for all components to finish */
	for (var integer i := 0; i < sizeof(pars); i := i + 1) {
		vc_conn[i].done;
	}

	/* Disable the artificial delay for TRXC RSP messages */
	rsp := f_TRXC_transceive(BTS_TRXC, g_bts_trxc_conn_id,
				 ts_TRXC_FAKE_TRXC_DELAY(0));
}

/***********************************************************************
 * IPA Style Dynamic Timeslot Support
 ***********************************************************************/

private function f_dyn_ipa_pdch_act(integer pcu_conn_id, integer bts_nr, integer trx_nr)
runs on ConnHdlr {
	/* Expect BTS to immediately acknowledge activation as PDCH */
	PCU.clear;
	RSL.send(ts_RSL_IPA_PDCH_ACT(g_chan_nr));
	/* expect INFO_IND on PCU interface listing TS as PDCH */
	timer T_wait := 2.0;
	T_wait.start;
	alt {
	[] as_pcuif_check_pdch_mask(pcu_conn_id, '1'B, bts_nr, trx_nr);
	[] PCU.receive { repeat; }
	[] T_wait.timeout {
	        Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
			log2str("Timeout waiting for PCUIF_INFO_IND PDCH_MASK to be '1' on TS", g_chan_nr.tn));
	        }
	}
	/* try to activate this PDCH from the PCU point of view */
	PCU.send(t_SD_PCUIF(pcu_conn_id, ts_PCUIF_ACT_REQ(bts_nr, trx_nr, g_chan_nr.tn)));
	/* FIXME: is there a response? */

	RSL.receive(tr_RSL_IPA_PDCH_ACT_ACK(g_chan_nr, ?));
}

private function f_dyn_ipa_pdch_deact(integer pcu_conn_id, integer bts_nr, integer trx_nr)
runs on ConnHdlr {
	/* Send RSL CHAN REL (deactivate) */
	RSL.send(ts_RSL_IPA_PDCH_DEACT(g_chan_nr));
	PCU.clear;
	/* expect BTS to ask PCU to deactivate the channel */
	timer T_wait := 2.0;
	T_wait.start;
	alt {
	[] as_pcuif_check_pdch_mask(pcu_conn_id, '0'B, bts_nr, trx_nr);
	[] PCU.receive { repeat; }
	[] T_wait.timeout {
	        Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
			log2str("Timeout waiting for PCUIF_INFO_IND PDCH_MASK to be '0' on TS", g_chan_nr.tn));
	        }
	}
	/* Emulate PCU asking BTS to deactivate PDCH */
	PCU.send(t_SD_PCUIF(pcu_conn_id, ts_PCUIF_DEACT_REQ(bts_nr, trx_nr, g_chan_nr.tn)));
	alt {
	[] RSL.receive(tr_RSL_IPA_PDCH_DEACT_ACK(g_chan_nr)) {
		setverdict(pass);
		}
	[] RSL.receive { repeat; }
	}
}

/* Activate and de-activate an IPA-style dynamic TCH/F + PDCH */
private function f_TC_dyn_ipa_pdch_act_deact(charstring id) runs on ConnHdlr {
	var PCUIF_Message first_info;
	var integer ts_nr := g_chan_nr.tn;
	var integer trx_nr := 0;
	var integer bts_nr := 0;
	var integer pcu_conn_id := -1;

	f_init_pcu(PCU, id, pcu_conn_id, first_info);

	f_dyn_ipa_pdch_act(pcu_conn_id, bts_nr, trx_nr);
	f_sleep(3.0);
	f_dyn_ipa_pdch_deact(pcu_conn_id, bts_nr, trx_nr);

	setverdict(pass);

}
testcase TC_dyn_ipa_pdch_act_deact() runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;
	f_init();

	pars := valueof(t_Pars(t_RslChanNr_Bm(3), ts_RSL_ChanMode_SIGN));
	vc_conn := f_start_handler(refers(f_TC_dyn_ipa_pdch_act_deact), pars, true);
	vc_conn.done;
}

/* try to RSL CHAN ACT a TCH/F on an IPA-style PDCH */
private function f_TC_dyn_ipa_pdch_tchf_act(charstring id) runs on ConnHdlr {
	var PCUIF_Message first_info;
	var integer ts_nr := g_chan_nr.tn;
	var integer trx_nr := 0;
	var integer bts_nr := 0;
	var integer pcu_conn_id := -1;

	f_init_pcu(PCU, id, pcu_conn_id, first_info);

	f_rsl_transceive(ts_RSL_CHAN_ACT(g_chan_nr, g_pars.chan_mode), tr_RSL_CHAN_ACT_ACK(g_chan_nr),
			 "RSL CHAN ACT");
	f_rsl_transceive(ts_RSL_RF_CHAN_REL(g_chan_nr), tr_RSL_RF_CHAN_REL_ACK(g_chan_nr),
			"RF CHAN REL", true);
	setverdict(pass);
}
testcase TC_dyn_ipa_pdch_tchf_act() runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;
	f_init();

	pars := valueof(t_Pars(t_RslChanNr_Bm(3), ts_RSL_ChanMode_SIGN));
	vc_conn := f_start_handler(refers(f_TC_dyn_ipa_pdch_tchf_act), pars, true);
	vc_conn.done;
}

/* Activate IPA style dyn PDCH as TCH/F and then illegally try to activate it as PDCH, too */
private function f_TC_dyn_ipa_pdch_tchf_act_pdch_act_nack(charstring id) runs on ConnHdlr {
	var PCUIF_Message first_info;
	var integer ts_nr := g_chan_nr.tn;
	var integer trx_nr := 0;
	var integer bts_nr := 0;
	var integer pcu_conn_id := -1;

	f_init_pcu(PCU, id, pcu_conn_id, first_info);

	f_rsl_transceive(ts_RSL_CHAN_ACT(g_chan_nr, g_pars.chan_mode), tr_RSL_CHAN_ACT_ACK(g_chan_nr),
			 "RSL CHAN ACT");

	RSL.send(ts_RSL_IPA_PDCH_ACT(g_chan_nr));
	alt {
	[] RSL.receive(tr_RSL_IPA_PDCH_ACT_NACK(g_chan_nr, ?));
	[] RSL.receive(tr_RSL_IPA_PDCH_ACT_ACK(g_chan_nr, ?)) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Unexpected PDCH ACT ACK");
		}
	[] RSL.receive { repeat; }
	}

	f_rsl_transceive(ts_RSL_RF_CHAN_REL(g_chan_nr), tr_RSL_RF_CHAN_REL_ACK(g_chan_nr),
			"RF CHAN REL", true);
	setverdict(pass);
}
testcase TC_dyn_ipa_pdch_tchf_act_pdch_act_nack() runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;
	f_init();

	pars := valueof(t_Pars(t_RslChanNr_Bm(3), ts_RSL_ChanMode_SIGN));
	vc_conn := f_start_handler(refers(f_TC_dyn_ipa_pdch_tchf_act_pdch_act_nack), pars, true);
	vc_conn.done;
}

/* try to RSL CHAN ACT a TCH/F on an IPA-style PDCH that's already in PDCH mode; expect NACK */
private function f_TC_dyn_ipa_pdch_act_tchf_act_nack(charstring id) runs on ConnHdlr {
	var PCUIF_Message first_info;
	var integer ts_nr := g_chan_nr.tn;
	var integer trx_nr := 0;
	var integer bts_nr := 0;
	var integer pcu_conn_id := -1;

	/* register for the TCH/F channel number */
	f_rslem_register(0, g_chan_nr);

	f_init_pcu(PCU, id, pcu_conn_id, first_info);

	f_dyn_ipa_pdch_act(pcu_conn_id, bts_nr, trx_nr);

	f_rsl_transceive(ts_RSL_CHAN_ACT(g_chan_nr, g_pars.chan_mode), tr_RSL_CHAN_ACT_NACK(g_chan_nr),
			 "RSL CHAN ACT");

	f_dyn_ipa_pdch_deact(pcu_conn_id, bts_nr, trx_nr);

	setverdict(pass);
}
testcase TC_dyn_ipa_pdch_act_tchf_act_nack() runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;
	f_init();

	pars := valueof(t_Pars(t_RslChanNr_Bm(3), ts_RSL_ChanMode_SIGN));
	vc_conn := f_start_handler(refers(f_TC_dyn_ipa_pdch_act_tchf_act_nack), pars, true);
	vc_conn.done;
}


/***********************************************************************
 * LAPDm / RLL related
 ***********************************************************************/

private function f_tx_lapdm(template (value) LapdmFrame l,
			    template (value) RslLinkId link_id) runs on ConnHdlr {
	var octetstring l2 := enc_LapdmFrame(valueof(l));
	var template (value) SacchL1Header l1h;

	/* TODO: we can use an extension of TTCN-3 for padding, i.e. PADDING('2B'O) */
	if (valueof(link_id.c) == SACCH) {
		/* Compose dummy L1 header */
		l1h := ts_SacchL1Header(g_pars.l1_pars.ms_power_level, g_pars.l1_pars.ms_actual_ta);
		L1CTL.send(ts_L1CTL_DATA_REQ_SACCH(g_chan_nr, link_id, l1h, f_pad_oct(l2, 21, '2B'O)));
	} else {
		/* If required, pad L2 frame with constant 0x2b filling */
		L1CTL.send(ts_L1CTL_DATA_REQ(g_chan_nr, link_id, f_pad_oct(l2, 23, '2B'O)));
	}
}

friend type record RllTestCase {
	uint3_t		sapi,
	RslLinkId	link_id,
	octetstring	l3,
	boolean		exp
}
friend type record of RllTestCase RllTestCases;
friend template RllTestCase t_EITC(template (present) uint3_t sapi,
				   template (present) RslLinkId id,
				   octetstring l3, boolean exp) := {
	sapi := sapi,
	link_id := id,
	l3 := l3,
	exp := exp
}

/* execute the same callback function with a set of different parameters (tcs) on a
 * variety of logical channels */
private function f_rll_testmatrix(RllTestCases tcs, void_fn fn) runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;
	f_init();

	/* test on each of the channels we have */
	for (var integer i := 0; i < sizeof(g_AllChanTypes); i := i+1) {
		pars := valueof(t_Pars(g_AllChanTypes[i], ts_RSL_ChanMode_SIGN));

		/* test each of the test cases on the current channel */
		for (var integer j := 0; j < sizeof(tcs); j := j+1) {
			pars.spec.rll := tcs[j];
			log(testcasename(), ": XXX Starting ", tcs[j] , " on ", g_AllChanTypes[i]);
			vc_conn := f_start_handler(fn, pars);
			vc_conn.done;
		}
	}

	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/* test if SABM on Um triggers EST IND (TS 48.058 3.1) */
private function f_TC_rll_est_ind(charstring id) runs on ConnHdlr {
	var RllTestCase tc := g_pars.spec.rll;
	timer T := 3.0;

	f_l1_tune(L1CTL);
	RSL.clear;

	/* activate the logical channel */
	f_est_dchan();
	L1CTL.clear;

	f_tx_lapdm(ts_LAPDm_SABM(tc.sapi, cr_MO_CMD, true, tc.l3), tc.link_id);
	T.start;
	alt {
	[tc.l3 != ''O] RSL.receive(tr_RSL_EST_IND(g_chan_nr, tc.link_id, tc.l3)) {
		if (tc.exp) {
			setverdict(pass);
		} else {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Unexpected EST IND with L3 in ", tc));
		}
		}
	[tc.l3 == ''O] RSL.receive(tr_RSL_EST_IND_NOL3(g_chan_nr, tc.link_id)) {
		if (tc.exp) {
			setverdict(pass);
		} else {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Unexpected EST IND without L3 in ", tc));
		}
		}
	/* We also expect to receive the measurements */
	[] as_meas_res(verify_meas := false);
	[tc.exp] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for EST IND");
		}
	[not tc.exp] T.timeout {
		setverdict(pass);
		}
	}

	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
	f_rslem_unregister(0, g_chan_nr);
}
testcase TC_rll_est_ind() runs on test_CT {
	var RllTestCases tcs := {
		/* SAPI0 establishment (contention resolution) */
		valueof(t_EITC(0, ts_RslLinkID_DCCH(0), '01020304'O, true)),
		/* normal SAPI0 establishment */
		valueof(t_EITC(0, ts_RslLinkID_DCCH(0), ''O, true)),
		/* SAPI 3 doesn't support contention resolution */
		valueof(t_EITC(3, ts_RslLinkID_DCCH(3), '01020304'O, false)),
		valueof(t_EITC(3, ts_RslLinkID_SACCH(3), '01020304'O, false)),
		/* normal SAPI3 establishment on main DCCH */
		valueof(t_EITC(3, ts_RslLinkID_DCCH(3), ''O, true)),
		/* normal SAPI3 establishment on SACCH */
		valueof(t_EITC(3, ts_RslLinkID_SACCH(3), ''O, true))
	};
	f_rll_testmatrix(tcs, refers(f_TC_rll_est_ind));
}

/* test if RLL EST REQ trigeres SABM on Um; UA on Um triggers EST CONF (TS 48.058 3.2) */
private function f_TC_rll_est_req(charstring id) runs on ConnHdlr {
	var RllTestCase tc := g_pars.spec.rll;
	var L1ctlMessage dl;
	timer T := 3.0;

	f_l1_tune(L1CTL);
	RSL.clear;

	/* activate the logical channel */
	f_est_dchan();
	L1CTL.clear;

	/* Send a RSL EST REQ for SAPI3 on main DCCH */
	RSL.send(ts_RSL_EST_REQ(g_chan_nr, tc.link_id));
	T.start;
	alt {
	[] as_l1_exp_lapdm(tr_LAPDm_SABM(tc.sapi, cr_MT_CMD, true, ''O));
	[] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for SABM");
		}
	}

	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
	f_rslem_unregister(0, g_chan_nr);
}
testcase TC_rll_est_req_DCCH_3() runs on test_CT {
	var RllTestCases tcs := {
		/* normal SAPI3 establishment on main DCCH */
		valueof(t_EITC(3, ts_RslLinkID_DCCH(3), ''O, true))//,
	};
	f_rll_testmatrix(tcs, refers(f_TC_rll_est_req));
}
testcase TC_rll_est_req_ACCH_3() runs on test_CT {
	var RllTestCases tcs := {
		/* normal SAPI3 establishment on SACCH */
		valueof(t_EITC(3, ts_RslLinkID_SACCH(3), ''O, true))
	}
	f_rll_testmatrix(tcs, refers(f_TC_rll_est_req));
}

/* altstep to receive a LAPDm frame matching the given template */
friend altstep as_l1_exp_lapdm(template LapdmFrame exp) runs on ConnHdlr {
	var L1ctlMessage dl;
	[] L1CTL.receive(tr_L1CTL_DATA_IND(g_chan_nr, ?)) -> value dl {
		var LapdmFrame lapdm;
		var octetstring l2 := dl.payload.data_ind.payload;
		if (dl.dl_info.link_id.c == SACCH) {
			/* remove L1 header */
			l2 := substr(l2, 2, lengthof(l2)-2);
		}
		if (ischosen(exp.ab)) {
			lapdm.ab := dec_LapdmFrameAB(l2);
		} else if (ischosen(exp.b4)) {
			lapdm.b4 := dec_LapdmFrameB4(l2);
		} else if (ischosen(exp.bbis)) {
			lapdm.bbis := dec_LapdmFrameBbis(l2);
		}
		log("Rx LAPDm ", lapdm);
		if (match(lapdm, exp)) {
			setverdict(pass);
		} else {
			repeat;
		}
		}
	[] L1CTL.receive { repeat; }
}
private function f_l1_exp_lapdm(template LapdmFrame exp, float t := 3.0) runs on ConnHdlr {
	timer T := t;
	T.start;
	alt {
	[] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Timeout waiting for LAPDm ", exp));
		}
	[] as_l1_exp_lapdm(exp);
	}
}

/* establish one Radio Link Layer via SABM -> UA. Use l3 for contention resolution */
private function f_est_rll_mo(uint3_t sapi, RslLinkId link_id, octetstring l3) runs on ConnHdlr {
	timer T := 2.0;
	/* send SABM from MS -> BTS */
	f_tx_lapdm(ts_LAPDm_SABM(sapi, cr_MO_CMD, true, l3), link_id);
	/* expect RLL EST IND on Abis */
	T.start;
	alt {
	[l3 != ''O] RSL.receive(tr_RSL_EST_IND(g_chan_nr, link_id, l3));
	[l3 == ''O] RSL.receive(tr_RSL_EST_IND_NOL3(g_chan_nr, link_id));
	[] RSL.receive(tr_RSL_ERROR_IND(g_chan_nr, link_id, ?)) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Failing due to RSL_ERROR_IND");
		}
	[] RSL.receive { repeat; }
	[] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for RLL EST IND");
		}
	}
	/* expect UA from BTS -> MS */
	f_l1_exp_lapdm(tr_LAPDm_UA(sapi, cr_MT_RSP, true, l3));
}

/* test if DISC on Um triggers RLL REL IND (TS 48.058 3.3) */
private function f_TC_rll_rel_ind(charstring id) runs on ConnHdlr {
	var RllTestCase tc := g_pars.spec.rll;

	f_l1_tune(L1CTL);
	RSL.clear;

	/* activate the logical channel */
	f_est_dchan();
	L1CTL.clear;

	/* first establish the link-layer */
	f_est_rll_mo(tc.sapi, tc.link_id, tc.l3);

	/* then send the DISC */
	f_tx_lapdm(ts_LAPDm_DISC(tc.sapi, cr_MO_CMD, true), tc.link_id);
	/* ... and expect the REL IND on the RSL side */
	alt {
	[] RSL.receive(tr_RSL_REL_IND(g_chan_nr, tc.link_id)) {
		setverdict(pass);
		}
	/* We also expect to receive the measurements */
	[] as_meas_res(verify_meas := false);
	}

	/* release the channel */
	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
	f_rslem_unregister(0, g_chan_nr);
}
testcase TC_rll_rel_ind_DCCH_0() runs on test_CT {
	var RllTestCases tcs := {
		valueof(t_EITC(0, ts_RslLinkID_DCCH(0), '01020304'O, true))
	};
	f_rll_testmatrix(tcs, refers(f_TC_rll_rel_ind));
}

testcase TC_rll_rel_ind_ACCH_0() runs on test_CT {
	var RllTestCases tcs := {
		valueof(t_EITC(0, ts_RslLinkID_SACCH(0), ''O, true))
	};
	f_rll_testmatrix(tcs, refers(f_TC_rll_rel_ind));
}
testcase TC_rll_rel_ind_DCCH_3() runs on test_CT {
	var RllTestCases tcs := {
		valueof(t_EITC(3, ts_RslLinkID_DCCH(3), ''O, true))
	};
	f_rll_testmatrix(tcs, refers(f_TC_rll_rel_ind));
}
testcase TC_rll_rel_ind_ACCH_3() runs on test_CT {
	var RllTestCases tcs := {
		valueof(t_EITC(3, ts_RslLinkID_SACCH(3), ''O, true))
	};
	f_rll_testmatrix(tcs, refers(f_TC_rll_rel_ind));
}

/* test if RLL REL REQ triggers DISC on Um; UA/DM triggers RLL REL CONF (TS 48.058 3.4) */
private function f_TC_rll_rel_req(charstring id) runs on ConnHdlr {
	var RllTestCase tc := g_pars.spec.rll;
	f_l1_tune(L1CTL);
	RSL.clear;

	/* activate the logical channel */
	f_est_dchan();
	L1CTL.clear;

	/* first establish the link-layer */
	f_est_rll_mo(tc.sapi, tc.link_id, tc.l3);

	/* then send the REL REQ via RSL */
	RSL.send(ts_RSL_REL_REQ(g_chan_nr, tc.link_id, RSL_REL_MODE_NORMAL));
	/* ... and expect the DISC on the Um side */
	alt {
	[] as_l1_exp_lapdm(tr_LAPDm_DISC(tc.sapi, cr_MT_CMD, true))  {
		/* FIXME: send a UA in response to the DISC */
		}
	}

	/* release the channel */
	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
	f_rslem_unregister(0, g_chan_nr);
}
testcase TC_rll_rel_req() runs on test_CT {
	var RllTestCases tcs := {
		valueof(t_EITC(0, ts_RslLinkID_DCCH(0), '01020304'O, true)),
		valueof(t_EITC(0, ts_RslLinkID_SACCH(0), ''O, true)),
		valueof(t_EITC(3, ts_RslLinkID_DCCH(3), ''O, true)),
		valueof(t_EITC(3, ts_RslLinkID_SACCH(3), ''O, true))
	};
	f_rll_testmatrix(tcs, refers(f_TC_rll_rel_req));
}

/* TODO: test if RLL DATA REQ triggers I-frames on Um (TS 48.058 3.5) */
testcase TC_rll_data_req() runs on test_CT {
}

/* TODO: test if I-frames on Um trigger RLL DATA IND (TS 48.058 3.6) */
testcase TC_rll_data_ind() runs on test_CT {
}

/* test if RLL UNIT DATA REQ triggers UI-frame on Um (TS 48.058 3.7) */
private function f_TC_rll_ud_req(charstring id) runs on ConnHdlr {
	var RllTestCase tc := g_pars.spec.rll;

	f_l1_tune(L1CTL);
	RSL.clear;

	f_est_dchan();
	L1CTL.clear;

	/* Send UNITDATA REQ on RSL side */
	RSL.send(ts_RSL_UNITDATA_REQ(g_chan_nr, tc.link_id, tc.l3));
	/* Expect it to arrive on the other side */
	if (tc.link_id.c == SACCH) {
		f_l1_exp_lapdm(tr_LAPDm_B4_UI(tc.sapi, cr_MT_CMD, tc.l3));
	} else {
		f_l1_exp_lapdm(tr_LAPDm_UI(tc.sapi, cr_MT_CMD, tc.l3));
	}

	/* release the channel */
	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
	f_rslem_unregister(0, g_chan_nr);
}
testcase TC_rll_unit_data_req_DCCH() runs on test_CT {
	var octetstring l3 := f_rnd_octstring(15);
	var RllTestCases tcs := {
		valueof(t_EITC(0, ts_RslLinkID_DCCH(0), l3, true)),
		valueof(t_EITC(3, ts_RslLinkID_DCCH(3), l3, true))
	};
	f_rll_testmatrix(tcs, refers(f_TC_rll_ud_req));
}
testcase TC_rll_unit_data_req_ACCH() runs on test_CT {
	var octetstring l3 := f_rnd_octstring(19);
	var RllTestCases tcs := {
		valueof(t_EITC(0, ts_RslLinkID_SACCH(0), l3, true)),
		valueof(t_EITC(3, ts_RslLinkID_SACCH(3), l3, true))
	};
	f_rll_testmatrix(tcs, refers(f_TC_rll_ud_req));
}

/* test if UI-frames on Um trigger RLL UNIT DATA IND (TS 48.058 3.8) */
private function f_TC_rll_ud_ind(charstring id) runs on ConnHdlr {
	var RllTestCase tc := g_pars.spec.rll;

	f_l1_tune(L1CTL);
	RSL.clear;

	f_est_dchan();
	L1CTL.clear;

	/* Send LAPDm UI frame. There is no B4 format in uplink! */
	f_tx_lapdm(ts_LAPDm_UI(tc.sapi, cr_MO_CMD, tc.l3), tc.link_id);
	/* Expdct RLL UNITDATA IND on RSL side */
	alt {
	[] RSL.receive(tr_RSL_UNITDATA_IND(g_chan_nr, tc.link_id, tc.l3)) {
		setverdict(pass);
		}
	[] RSL.receive { repeat; }
	}

	/* release the channel */
	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
	f_rslem_unregister(0, g_chan_nr);
}
testcase TC_rll_unit_data_ind_DCCH() runs on test_CT {
	var octetstring l3 := f_rnd_octstring(20);
	var RllTestCases tcs := {
		valueof(t_EITC(0, ts_RslLinkID_DCCH(0), l3, true)),
		valueof(t_EITC(3, ts_RslLinkID_DCCH(3), l3, true))
	};
	f_rll_testmatrix(tcs, refers(f_TC_rll_ud_ind));
}
testcase TC_rll_unit_data_ind_ACCH() runs on test_CT {
	var octetstring l3 := f_rnd_octstring(18);
	var RllTestCases tcs := {
		valueof(t_EITC(0, ts_RslLinkID_SACCH(0), l3, true)),
		valueof(t_EITC(3, ts_RslLinkID_SACCH(3), l3, true))
	};
	f_rll_testmatrix(tcs, refers(f_TC_rll_ud_ind));
}

/***********************************************************************
 * Encryption Related
 ***********************************************************************/

/* send UNITDATA_REQ from BTS to MS and expect it to arrive */
private function f_unitdata_mt(RslLinkId link_id, octetstring l3) runs on ConnHdlr {
	RSL.send(ts_RSL_UNITDATA_REQ(g_chan_nr, link_id, l3));
	if (link_id.c == SACCH) {
		f_l1_exp_lapdm(tr_LAPDm_B4_UI(link_id.sapi, cr_MT_CMD, l3));
	} else {
		f_l1_exp_lapdm(tr_LAPDm_UI(link_id.sapi, cr_MT_CMD, l3));
	}
}

/* Expect (or not expect) other kinds of messages */
private altstep as_rsl_any_ind(boolean exp_any) runs on ConnHdlr {
	[exp_any] RSL.receive { repeat; }
	[not exp_any] RSL.receive {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Unexpected RSL message!");
		}
}

/* Send UI frame from MS and expect it to arrive as RLL UNITDATA IND on Abis */
private function f_unitdata_mo(
	RslLinkId link_id,
	octetstring l3,
	boolean exp_sacch := true, /* Should tolerate SACCH messages? */
	boolean exp_any := false /* Should tolerate any other RSL messages? */
) runs on ConnHdlr {
	timer T := 3.0;
	f_tx_lapdm(ts_LAPDm_UI(link_id.sapi, cr_MO_CMD, l3), link_id);
	T.start;
	/* Expect RLL UNITDATA IND on RSL side */
	alt {
	[] RSL.receive(tr_RSL_UNITDATA_IND(g_chan_nr, link_id, l3)) {
		setverdict(pass);
		}
	[exp_sacch] as_meas_res(verify_meas := false);
	[] as_rsl_any_ind(exp_any);
	[] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for UNIT_DATA_IND");
		}
	}
}

/* Send I-frame from MS and expect it to arrive as RLL DATA IND on Abis */
private function f_data_mo(
	RslLinkId link_id,
	boolean p, uint3_t nr, uint3_t ns,
	octetstring l3,
	boolean exp_sacch := true, /* Should tolerate SACCH messages? */
	boolean exp_any := false /* Should tolerate any other RSL messages? */
) runs on ConnHdlr {
	timer T := 3.0;
	f_tx_lapdm(ts_LAPDm_I(link_id.sapi, cr_MO_CMD, p, nr, ns, l3), link_id);
	T.start;
	/* Expect RLL DATA IND on RSL side */
	alt {
	[] RSL.receive(tr_RSL_DATA_IND(g_chan_nr, link_id, l3)) {
		setverdict(pass);
		}
	[exp_sacch] as_meas_res(verify_meas := false);
	[] as_rsl_any_ind(exp_any);
	[] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for DATA_IND");
		}
	}
}

/* Test channel activation with A5/n right from the beginning (like in assignment + hand-over) */
private function f_TC_chan_act_encr(charstring id) runs on ConnHdlr {
	f_l1_tune(L1CTL);
	f_est_dchan(true);

	/* now we actually need to transmit some data both ways to check if the encryption works */
	var L1ctlMessage dl;

	var octetstring l3 := f_rnd_octstring(20);
	var RslLinkId link_id := valueof(ts_RslLinkID_DCCH(0));

	/* send UNITDATA_REQ from BTS to MS and expect it to arrive */
	f_unitdata_mt(link_id, l3);

	/* Send UI frame from MS and expect it to arrive as RLL UNITDATA IND on Abis */
	f_unitdata_mo(link_id, l3);

	/* release the channel */
	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
	f_rslem_unregister(0, g_chan_nr);
}
testcase TC_chan_act_a51() runs on test_CT {
	var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN));
	pars.encr := valueof(ts_RSL_IE_EncrInfo(RSL_ALG_ID_A5_1, f_rnd_octstring(8)));
	f_testmatrix_each_chan(pars, refers(f_TC_chan_act_encr));
}
testcase TC_chan_act_a52() runs on test_CT {
	var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN));
	pars.encr := valueof(ts_RSL_IE_EncrInfo(RSL_ALG_ID_A5_2, f_rnd_octstring(8)));
	f_testmatrix_each_chan(pars, refers(f_TC_chan_act_encr));
}
testcase TC_chan_act_a53() runs on test_CT {
	var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN));
	pars.encr := valueof(ts_RSL_IE_EncrInfo(RSL_ALG_ID_A5_3, f_rnd_octstring(8)));
	f_testmatrix_each_chan(pars, refers(f_TC_chan_act_encr));
}
testcase TC_chan_act_a54() runs on test_CT {
	var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN));
	pars.encr := valueof(ts_RSL_IE_EncrInfo(RSL_ALG_ID_A5_4, f_rnd_octstring(16)));
	f_testmatrix_each_chan(pars, refers(f_TC_chan_act_encr));
}

/* Test channel activation with A5/n right from the beginning and RSL MODE MODIFY
 which should break the en/decryption on purpose by supplying a new key that is unknown to the MS*/
private function f_TC_rsl_modify_encr(charstring id) runs on ConnHdlr {
	f_l1_tune(L1CTL);
	f_est_dchan(true);

	/* now we actually need to transmit some data both ways to check if the encryption works */
	var L1ctlMessage dl;

	var octetstring l3 := f_rnd_octstring(20);
	var RslLinkId link_id := valueof(ts_RslLinkID_DCCH(0));

	/* send UNITDATA_REQ from BTS to MS and expect it to arrive */
	f_unitdata_mt(link_id, l3);

	/* Send UI frame from MS and expect it to arrive as RLL UNITDATA IND on Abis */
	f_unitdata_mo(link_id, l3);

	var RSL_Message rsl;
	rsl := valueof(ts_RSL_MODE_MODIFY_REQ(g_chan_nr, ts_RSL_ChanMode_SIGN));

	/* modify key to break proper encryption */
	g_pars.encr.key :=  f_rnd_octstring(8);
	var RSL_IE ei := valueof(t_RSL_IE(RSL_IE_ENCR_INFO, RSL_IE_Body:{encr_info := g_pars.encr}));
	rsl.ies := rsl.ies & { ei };
	RSL.send(rsl);

	timer T0 := 1.0;
	T0.start;
	/* Expect RSL MODIFY ACK */
	alt {
	[] RSL.receive(tr_RSL_MODE_MODIFY_ACK(g_chan_nr)) {}
	[] RSL.receive(tr_RSL_MODE_MODIFY_NACK(g_chan_nr, ?)) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,"MODE MODIFY NACK");
		}
	[] T0.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for MODE MODIFY (N)ACK");
		}
	}

	var octetstring l3msg := f_rnd_octstring(15);
	timer T1 := 3.0;
	/* Send UI frame from MS, do not expect it to arrive as RLL UNITDATA IND on Abis
	due to broken encryption  */
	f_tx_lapdm(ts_LAPDm_UI(link_id.sapi, cr_MO_CMD, l3msg), link_id);
	T1.start;
	alt {
	[] RSL.receive(tr_RSL_UNITDATA_IND(g_chan_nr, link_id, l3msg)) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "BTS shouldn't be able to decrypt after key change")
		}
	[] T1.timeout {
		setverdict(pass);
		}
	}

	/* release the channel */
	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
	f_rslem_unregister(0, g_chan_nr);
}
testcase TC_rsl_modify_encr() runs on test_CT {
	var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN));
	pars.encr := valueof(ts_RSL_IE_EncrInfo(RSL_ALG_ID_A5_1, f_rnd_octstring(8)));
	f_testmatrix_each_chan(pars, refers(f_TC_rsl_modify_encr));
}

/* Verify RF RESource INDication messages (periodically sent over the RSL) */
private function f_TC_rsl_rf_resource_ind(template (present) RSL_ResourceInfo info)
runs on test_CT {
	const IpaStreamId sid := IPAC_PROTO_RSL_TRX0;
	var ASP_RSL_Unitdata ud;
	timer T;

	/* Intave is 6 SACCH periods by default */
	var float Tval := int2float(6 * 480) / 1000.0 + 0.5;

	T.start(Tval);
	alt {
	[] RSL_CCHAN.receive(tr_ASP_RSL_UD(tr_RSL_RF_RES_IND(info), sid)) {
		setverdict(pass);
		}
	[] RSL_CCHAN.receive(tr_ASP_RSL_UD(tr_RSL_RF_RES_IND(?), sid)) -> value ud {
		setverdict(fail, "RF RESource INDication mismatch: ", ud.rsl);
		}
	[] RSL_CCHAN.receive { repeat; }
	[] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
			"Timeout waiting for RF RESource INDication");
		}
	}
}
testcase TC_rsl_rf_resource_ind() runs on test_CT {
	var RSL_ResourceInfo info := { };

	f_init(trx_nr := 0);

	f_init_l1ctl();
	f_l1_tune(L1CTL);

	/* g_AllChannels contains all logical channels */
	for (var integer i := 0; i < lengthof(g_AllChannels); i := i + 1) {
		var RslChannelNr chan_nr := g_AllChannels[i];

		/* FIXME: osmo-bts does not report for Osmocom style dynamic timeslots */
		if (mp_trx_pars[0].ts[chan_nr.tn].config == GSM_PCHAN_TCHH_TCHF_PDCH)
			{ continue; }

		info := info & { valueof(ts_RSL_ResourceInfoItem(chan_nr, mp_interf_band)) };
	}

	/* Align to the first interference report */
	f_TC_rsl_rf_resource_ind(?);

	/* Test 4 consecutive messages */
	for (var integer i := 0; i < 4; i := i + 1) {
		f_TC_rsl_rf_resource_ind(info);
	}

	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/* Test unencrypted channel activation followed by explicit ENCR CMD later */
private function f_TC_encr_cmd(charstring id) runs on ConnHdlr {
	/* L3 payload doesn't matter, as it is passed transparently */
	var BIT3 l3_alg_id := f_alg_id_to_l3(g_pars.encr.alg_id);
	var octetstring l3 := enc_PDU_ML3_NW_MS(valueof(ts_RRM_CiphModeCmd(l3_alg_id)));
	var RslLinkId link_id := valueof(ts_RslLinkID_DCCH(0));

	f_l1_tune(L1CTL);

	/* first establish a dedicated channel in the clear */
	f_est_dchan(false);

	/* Establish ABM */
	f_est_rll_mo(link_id.sapi, link_id, '23420815'O);

	/* then send the RSL ENCR CMD with an actual RR CIPH MOD CMD inside */
	RSL.send(ts_RSL_ENCR_CMD(g_chan_nr, link_id, g_pars.encr.alg_id, g_pars.encr.key, l3));
	/* expect the L3 to arrive still unencrypted on the MS side */
	f_l1_exp_lapdm(tr_LAPDm_I(link_id.sapi, cr_MT_CMD, ?, ?, ?, l3));

	/* configure L1 to apply ciphering */
	var uint8_t alg_id := f_alg_id_to_l1ctl(g_pars.encr.alg_id);
	f_L1CTL_CRYPTO_REQ(L1CTL, g_pars.chan_nr, alg_id, g_pars.encr.key);

	/* send first ciphered I-frame in response and expect it on RSL */
	f_data_mo(link_id, true, 1, 0, '0a0b0c0d'O, exp_sacch := true);

	/* now the BTS code should have detected the first properly encrypted uplink I-frame,
	 * and hence enable encryption also on the downlink */

	/* expect bi-directional communication work in encrypted mode */
	f_unitdata_mo(link_id, f_rnd_octstring(15));
	f_unitdata_mt(link_id, f_rnd_octstring(15));

	/* release the channel */
	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
	f_rslem_unregister(0, g_chan_nr);
}
testcase TC_encr_cmd_a51() runs on test_CT {
	var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN));
	pars.encr := valueof(ts_RSL_IE_EncrInfo(RSL_ALG_ID_A5_1, f_rnd_octstring(8)));
	f_testmatrix_each_chan(pars, refers(f_TC_encr_cmd));
}
testcase TC_encr_cmd_a52() runs on test_CT {
	var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN));
	pars.encr := valueof(ts_RSL_IE_EncrInfo(RSL_ALG_ID_A5_2, f_rnd_octstring(8)));
	f_testmatrix_each_chan(pars, refers(f_TC_encr_cmd));
}
testcase TC_encr_cmd_a53() runs on test_CT {
	var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN));
	pars.encr := valueof(ts_RSL_IE_EncrInfo(RSL_ALG_ID_A5_3, f_rnd_octstring(8)));
	f_testmatrix_each_chan(pars, refers(f_TC_encr_cmd));
}
testcase TC_encr_cmd_a54() runs on test_CT {
	var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN));
	pars.encr := valueof(ts_RSL_IE_EncrInfo(RSL_ALG_ID_A5_4, f_rnd_octstring(16)));
	f_testmatrix_each_chan(pars, refers(f_TC_encr_cmd));
}

private function f_assert_lapdm(octetstring enc, template LapdmFrame exp_match, charstring name := "") {
	var LapdmFrame lf;
	var octetstring reenc;

	/* decode the LAPDm frame */
	if (ischosen(exp_match.ab)) {
		lf.ab := dec_LapdmFrameAB(enc);
	} else {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "unsupported frame type");
	}

	/* check if decoder result matches expectation */
	if (not match(lf, exp_match)) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str(name, ": decoded LAPDm doesn't match"));
	} else {
		log(name, ": matched");
		setverdict(pass);
	}

	/* test if re-encoded frame equals original input */
	reenc := enc_LapdmFrame(lf);
	if (enc != reenc) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str(name, ": re-encoded LAPDm frame doesn't match"));
	} else {
		setverdict(pass);
	}
}

testcase TC_lapdm_selftest() runs on test_CT {
	f_assert_lapdm('030301'O, tr_LAPDm_UI(0, true, ''O), "ui_s0_empty");
	f_assert_lapdm('0F0301'O, tr_LAPDm_UI(3, true, ''O), "ui_s3_empty");
	f_assert_lapdm('013F01'O, tr_LAPDm_SABM(0, false, true, ''O), "sabm_s0_empty");
	f_assert_lapdm('013F1123420815'O, tr_LAPDm_SABM(0, false, true, '23420815'O), "sabm_s0_l3");
	f_assert_lapdm('03E101'O, tr_LAPDm_RR(0, true, false, 7), "rr_s0_7");
	f_assert_lapdm('03000d063505'O, tr_LAPDm_I(0, true, false, 0, 0, '063505'O), "I/0/0");
	f_assert_lapdm('03e00d063505'O, tr_LAPDm_I(0, true, false, 7, 0, '063505'O), "I/7/0");
}

/***********************************************************************
 * DTX Related (see GSM 05.08, section 8.3)
 ***********************************************************************/
private function f_TC_tch_sign_l2_fill_frame(charstring id) runs on ConnHdlr {
	var L1ctlMessage dl;
	var GsmFrameNumber first_fn;
	var boolean is_first_frame := true;
	var integer nfill_frames := 0;
	var integer expected_fill_frames := 10000; /* initial value causes test failure if not overridden */
	/* Frames numbers (mod 104) for which a fill frame is expected on TCHF if DTX is enabled. */
	var Integers required_tdma_frames_dtx_tchf := { 52, 53, 54, 55, 56, 57, 58, 59 };
	const integer frame_dtx_tchf_mod := 104;
	/* Frame numbers (mod 104) for which a fill frame is expected at the L1SAP level,
	 * which operates in terms of blocks rather than frames. */
	var Integers required_tdma_blocks_dtx_tchf := { 52, 56 };
	const integer block_dtx_tchf_mod := 26;
	timer T := 5.0;

	f_l1_tune(L1CTL);
	RSL.clear;
	L1CTL.clear;

	/* activate TCHF signalling channel */
	f_est_dchan(false);

	/* A template for matching dummy LAPDm func=UA frames */
	var template L1ctlMessage tr_fill_frame := tr_L1CTL_DATA_IND(
		chan_nr := g_chan_nr, link_id := tr_RslLinkID_DCCH(?),
		l2_data := f_pad_oct('030301'O, 23, '2B'O));

	T.start;
	alt {
	[] L1CTL.receive(tr_fill_frame) -> value dl {
		var GsmFrameNumber fn := dl.dl_info.frame_nr;

		if (is_first_frame) {
			is_first_frame := false;
			first_fn := dl.dl_info.frame_nr;
		}

		if (g_pars.chan_mode.dtx_d) {
			if (fn > first_fn + frame_dtx_tchf_mod) {
				T.stop;
				f_rsl_chan_deact();
				f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);

				/* With DTX enabled we can expect at least 3 fill frames for every 104 frames. */
				expected_fill_frames := 2;

				if (nfill_frames < expected_fill_frames) {
					setverdict(fail, "Not enough fill frames received: ",
						   nfill_frames, " out of ", expected_fill_frames);
					Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
				} else {
					setverdict(pass);
				}
			} else {
				/* On DTX TCH/F channels, fill frames occur only for specific frame numbers mod 104.
				 * Furthermore, the L1SAP layer gives us frame numbers for the start of a block so
				 * we should only see the subset of frames numbers which correspond to a block boundary.
				 * TCH/F blocks are defined to start at 0,4,8,13,17,21 (modulo 26) */
				for (var integer i := 0; i < lengthof(required_tdma_blocks_dtx_tchf); i := i + 1) {
					if (fn mod frame_dtx_tchf_mod == required_tdma_blocks_dtx_tchf[i]) {
						nfill_frames := nfill_frames + 1;
						repeat;
					}
				}
				setverdict(fail, "Received DTX TCH fill frame with bad frame number: ", fn,
					   " (mod ", frame_dtx_tchf_mod, ": ", fn mod frame_dtx_tchf_mod, ")",
					   " (mod ", block_dtx_tchf_mod, ": ", fn mod block_dtx_tchf_mod, ")");
				f_rsl_chan_deact();
				f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
			}
		} else {
			nfill_frames := nfill_frames + 1;
			if (fn > first_fn + frame_dtx_tchf_mod) {
				T.stop;

				select (g_chan_nr) {
				/* TCH/F: we expect 24 fill frames for every 104 frames. */
				case (t_RslChanNr_Bm(?)) { expected_fill_frames := 24; }
				/* TCH/H: we expect 2 fill frames for every 104 frames. */
				case (t_RslChanNr_Lm(?, ?)) { expected_fill_frames := 2; }
				/* SDCCH: we expect 5 fill frames for every 104 frames. */
				case (t_RslChanNr_SDCCH4(?, ?)) { expected_fill_frames := 4; }
				case (t_RslChanNr_SDCCH8(?, ?)) { expected_fill_frames := 4; }
				case else {
					/* This shall not happen, just to be sure */
					Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
					}
				}

				f_rsl_chan_deact();
				f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);

				if (nfill_frames >= expected_fill_frames) {
					setverdict(pass);
				} else {
					setverdict(fail, "Not enough fill frames received: ",
						   nfill_frames, " out of ", expected_fill_frames);
					Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
				}
			} else {
				repeat;
			}
		}
	}
	[] L1CTL.receive { repeat; }
	[] T.timeout {
		f_rsl_chan_deact();
		f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for L2 fill frames on Um");
	}
	}
}

private function f_tch_sign_l2_fill_frame(boolean dtxd) runs on test_CT {
	var template RSL_IE_ChannelMode ch_mode;
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;
	pars.t_guard := 60.0;
	f_init();
	ch_mode := ts_RSL_ChanMode_SIGN(dtxd := dtxd);
	for (var integer i := 0; i < sizeof(g_AllChannels); i := i + 1) {
		pars := valueof(t_Pars(g_AllChannels[i], ch_mode));
		if (dtxd) {
			if (i >= 4) { /* DTX is only allowed on TCH/F */
				break;
			}
		}
		vc_conn := f_start_handler(refers(f_TC_tch_sign_l2_fill_frame), pars);
		vc_conn.done;
	}
}

/* Verify that L2 fill frames are sent on TCH in signaling mode if
 * there is nothing to transmit while DTX is disabled on downlink. */
testcase TC_tch_sign_l2_fill_frame() runs on test_CT {
	f_tch_sign_l2_fill_frame(false);
}

/* Verify that particular L2 fill frames are sent on TCH in signaling mode if
 * there is nothing to transmit while DTX is enabled on downlink. */
testcase TC_tch_sign_l2_fill_frame_dtxd() runs on test_CT {
	f_tch_sign_l2_fill_frame(true);
}

testcase TC_chopped_ipa_ping() runs on test_CT {
	IPA_Testing.f_run_TC_chopped_ipa_ping(mp_rsl_ip, mp_rsl_port, LISTEN_FOR_CLIENT);
}

testcase TC_chopped_ipa_payload() runs on test_CT {
	IPA_Testing.f_run_TC_chopped_ipa_payload(mp_rsl_ip, mp_rsl_port, LISTEN_FOR_CLIENT);
}


/* Callback function to be called by as_TC_ms_pwr_ctrl().
 * Return value: Measurement Report to be sent (encoded octetstring). */
type function f_TC_ms_pwr_ctrl_cb(inout SacchL1Header l1h, integer num_blocks)
	runs on ConnHdlr return octetstring;

private altstep as_TC_ms_pwr_ctrl(f_TC_ms_pwr_ctrl_cb cb, inout integer num_blocks)
runs on ConnHdlr {
	var L1ctlMessage l1_dl;
	var SacchL1Header l1h;
	var octetstring l2;

	[] L1CTL.receive(tr_L1CTL_DATA_IND(g_chan_nr, tr_RslLinkID_SACCH(?))) -> value l1_dl {
		/* Parse the L1 SACCH header (MS Power Level & Timing Advance) */
		l1h := dec_SacchL1Header(substr(l1_dl.payload.data_ind.payload, 0, 2));
		log("as_TC_ms_pwr_ctrl(): Rx SACCH L1 header: ", l1h);

		/* Pass it to the user specified call-back function */
		l2 := cb.apply(l1h, num_blocks);
		/* Send a Measurement Report generated by the call-back */
		L1CTL.send(ts_L1CTL_DATA_REQ_SACCH(l1_dl.dl_info.chan_nr,
						   l1_dl.dl_info.link_id,
						   l1h, l2));

		/* Shall we keep going? */
		num_blocks := num_blocks - 1;
		log("as_TC_ms_pwr_ctrl(): ", num_blocks, " SACCH blocks remaining");
		if (num_blocks > 0) { repeat; }
		}
	[] L1CTL.receive { repeat; }
}

private function f_TC_ms_pwr_ctrl_cb_def(inout SacchL1Header l1h, integer num_blocks)
runs on ConnHdlr return octetstring {
	/* Command the L1 to apply received parameters */
	f_L1CTL_PARAM(L1CTL, l1h.actual_ta, l1h.ms_power_lvl);

	/* Dummy measurement report (the results are invalid) */
	return f_pad_oct('010349'O & '0615004001C0'O, 21, '00'O);
}

private function f_TC_ms_pwr_ctrl_cb_const(inout SacchL1Header l1h, integer num_blocks)
runs on ConnHdlr return octetstring {
	if (l1h.ms_power_lvl != g_pars.l1_pars.ms_power_level) {
		setverdict(fail, "Unexpected MS Power level change: ",
			   g_pars.l1_pars.ms_power_level, " -> ",
			   l1h.ms_power_lvl);
	}

	return f_TC_ms_pwr_ctrl_cb_def(l1h, num_blocks);
}

private function f_TC_ms_pwr_ctrl_cb_rssi_pwm(inout SacchL1Header l1h, integer num_blocks)
runs on ConnHdlr return octetstring {
	/* UL RSSI oscillation driven by SACCH block number */
	if (num_blocks rem 2 == 0) {
		f_trxc_fake_rssi(-100);
	} else {
		f_trxc_fake_rssi(-50);
	}

	/* Make sure that MS power level remains constant */
	return f_TC_ms_pwr_ctrl_cb_const(l1h, num_blocks);
}

/* Make sure that MS power level remains constant when 'rx-current' equals 'rx-target' */
private function f_TC_ms_pwr_ctrl_constant(charstring id)
runs on ConnHdlr {
	var integer num_blocks := 8;
	timer T := int2float(num_blocks);

	f_l1_tune(L1CTL);
	RSL.clear;

	/* These IEs are needed for autonomous MS power control */
	var template (value) RSL_IE_List ies := {
		t_RSL_IE(RSL_IE_MS_POWER, RSL_IE_Body:{
			 ms_power := ts_RSL_IE_MS_Power(g_pars.l1_pars.ms_power_level)
		}),
		t_RSL_IE(RSL_IE_MS_POWER_PARAM, RSL_IE_Body:{
			 ms_power_params := ts_RSL_IE_MS_Power_Parameters(''O)
		})
	};

	/* Ensure that 'rx-current' equals 'rx-target' */
	f_trxc_fake_rssi(mp_uplink_power_target);

	/* Populate SACCH cache with a Measurement Report */
	f_send_meas_rep(ts_MeasurementResults);

	/* Establish a dedicated channel */
	f_est_dchan(more_ies := valueof(ies));

	L1CTL.clear;
	T.start;
	alt {
	[] as_TC_ms_pwr_ctrl(refers(f_TC_ms_pwr_ctrl_cb_const), num_blocks);
	[] T.timeout {
		setverdict(fail, "Not all SACCH blocks were processed in time, ",
				 num_blocks, " were not handled");
		}
	}

	/* Release the channel */
	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
}
testcase TC_ms_pwr_ctrl_constant() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;

	f_init();

	/* Explicitly configure the Uplink power target (in dBm) */
	f_vty_config(BTSVTY, "bts 0", "uplink-power-target " & int2str(mp_uplink_power_target));

	for (var integer i := 0; i < sizeof(g_AllChanTypes); i := i + 1) {
		pars := valueof(t_Pars(g_AllChanTypes[i], ts_RSL_ChanMode_SIGN));
		log(testcasename(), ": starting on ", pars.chan_nr);

		vc_conn := f_start_handler(refers(f_TC_ms_pwr_ctrl_constant),
					   pars, trxc_comp := true);
		vc_conn.done;
	}

	/* No need to reset Uplink power parameters - the IUT restarts anyway */
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/* Test Exponentially Weighted Moving Average (EWMA) power filtering */
private function f_TC_ms_pwr_ctrl_pf_ewma(charstring id)
runs on ConnHdlr {
	var integer num_blocks := 16;
	timer T := int2float(num_blocks);

	f_l1_tune(L1CTL);
	RSL.clear;

	/* These IEs are needed for autonomous MS power control */
	var template (value) RSL_IE_List ies := {
		t_RSL_IE(RSL_IE_MS_POWER, RSL_IE_Body:{
			 ms_power := ts_RSL_IE_MS_Power(g_pars.l1_pars.ms_power_level)
		}),
		t_RSL_IE(RSL_IE_MS_POWER_PARAM, RSL_IE_Body:{
			 ms_power_params := ts_RSL_IE_MS_Power_Parameters(''O)
		})
	};

	/* Ensure that 'rx-current' equals 'rx-target' */
	f_trxc_fake_rssi(mp_uplink_power_target);

	/* Populate SACCH cache with a Measurement Report */
	f_send_meas_rep(ts_MeasurementResults);

	/* Establish a dedicated channel */
	f_est_dchan(more_ies := valueof(ies));

	L1CTL.clear;
	T.start;
	alt {
	[] as_TC_ms_pwr_ctrl(refers(f_TC_ms_pwr_ctrl_cb_rssi_pwm), num_blocks);
	[] T.timeout {
		setverdict(fail, "Not all SACCH blocks were processed in time, ",
				 num_blocks, " were not handled");
		}
	}

	/* Release the channel */
	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
}
testcase TC_ms_pwr_ctrl_pf_ewma() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;

	f_init();

	/* Explicitly configure EWMA filtering with 80% smoothing (alpha = 0.2) */
	f_vty_config(BTSVTY, "bts 0", "uplink-power-filtering algo ewma beta 80");
	/* Explicitly configure the Uplink power range (target and delte) */
	f_vty_config(BTSVTY, "bts 0", "uplink-power-target " & int2str(mp_uplink_power_target)
					    & " hysteresis " & int2str(mp_uplink_power_hysteresis));

	for (var integer i := 0; i < sizeof(g_AllChanTypes); i := i + 1) {
		pars := valueof(t_Pars(g_AllChanTypes[i], ts_RSL_ChanMode_SIGN));
		log(testcasename(), ": starting on ", pars.chan_nr);

		vc_conn := f_start_handler(refers(f_TC_ms_pwr_ctrl_pf_ewma),
					   pars, trxc_comp := true);
		vc_conn.done;
	}

	/* No need to reset Uplink power parameters - the IUT restarts anyway */
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

private function f_TC_speech_no_rtp(charstring id) runs on ConnHdlr {
	var template L1ctlMessage tr_bad_frame;
	var L1ctlMessage l1_dl;
	timer T := 8.0;

	f_l1_tune(L1CTL);
	RSL.clear;

	f_est_dchan();

	/* There may be a few errors right after the channel activation */
	f_sleep(2.0); /* ... so let's give the L1 some time to stabilize */
	L1CTL.clear;

	/* A universal template for bad Downlink frame: {DATA,TRAFFIC}.ind */
	tr_bad_frame := tr_L1CTL_TRAFFIC_IND(g_chan_nr, tr_RslLinkID_DCCH(0));
	tr_bad_frame.header.msg_type := (L1CTL_DATA_IND, L1CTL_TRAFFIC_IND);
	tr_bad_frame.dl_info.fire_crc := (1..255); /* != 0 */
	tr_bad_frame.payload := ?;

	T.start;
	alt {
	/* OS#4823: DATA.ind or TRAFFIC.ind with bad CRC most likely means that
	 * the IUT is sending *dummy bursts*, so the L1 fails to decode them. */
	[] L1CTL.receive(tr_bad_frame) -> value l1_dl {
		setverdict(fail, "Received {DATA,TRAFFIC}.ind with bad CRC: ", l1_dl);
		}
	[] as_l1_sacch();
	[] L1CTL.receive { repeat; }
	[] T.timeout {
		/* We're done, break the loop */
		setverdict(pass);
		}
	}

	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
}
testcase TC_speech_no_rtp_tchf() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;

	f_init();

	/* TS1, TCH/F, V1 (FR codec) */
	pars := valueof(t_Pars(ts_RslChanNr_Bm(1), ts_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM1)));
	vc_conn := f_start_handler(refers(f_TC_speech_no_rtp), pars);
	vc_conn.done;
}
testcase TC_speech_no_rtp_tchh() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;

	f_init();

	/* TS5, TCH/H, V1 (HR codec) */
	pars := valueof(t_Pars(ts_RslChanNr_Lm(5, 0), ts_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM1)));
	vc_conn := f_start_handler(refers(f_TC_speech_no_rtp), pars);
	vc_conn.done;
}

/* Verify handling of Downlink and Uplink speech frames */
private function f_TC_speech_rtp(charstring id) runs on ConnHdlr {
	var L1ctlMessage l1_dl;
	var PDU_RTP rtp_pdu;
	var octetstring pl;
	timer Td, Tu;

	log("Testing channel mode ", g_pars.chan_mode);

	f_l1_tune(L1CTL);
	f_est_dchan();

	/* Activate the RTP emulation */
	pl := f_rnd_octstring(6);
	f_rtpem_activate(pl);

	/* Give the scheduler some time to fill up the buffers */
	f_sleep(2.0);
	L1CTL.clear;
	RSL.clear;

	/* Make sure that Downlink frames are received at the UE */
	Td.start(2.0);
	alt {
	[] L1CTL.receive(tr_L1CTL_TRAFFIC_IND(g_chan_nr, frame := pl)) -> value l1_dl {
		log("TCH received: ", l1_dl.payload.traffic_ind.data);
		L1CTL.send(ts_L1CTL_TRAFFIC_REQ(g_chan_nr, l1_dl.dl_info.link_id,
			   l1_dl.payload.traffic_ind.data));
		setverdict(pass);
		}
	[] L1CTL.receive(tr_L1CTL_TRAFFIC_IND(g_chan_nr, frame := ?)) -> value l1_dl {
		setverdict(fail, "Rx unexpected Downlink speech frame ",
			   "(", l1_dl.payload.traffic_ind.data, ") ",
			   "expected (", pl, ")");
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
		}
	[] as_l1_sacch();
	[] L1CTL.receive { repeat; }
	[] Td.timeout {
		setverdict(fail, "Timeout waiting for Downlink speech frames");
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
		}
	}

	/* Make sure that Uplink frames are received at the BTS */
	RTPEM_DATA.clear;
	Tu.start(2.0);
	alt {
	[] as_l1_tch_loop();
	[] as_l1_sacch();
	[] RTPEM_DATA.receive(PDU_RTP:?) -> value rtp_pdu {
		if (rtp_pdu.data != pl)
			{ repeat; }
		}
	[] RTPEM_DATA.receive { repeat; }
	[] L1CTL.receive { repeat; }
	[] Tu.timeout {
		setverdict(fail, "Timeout waiting for Uplink speech frames");
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
		}
	}

	f_rtpem_mode(RTPEM_CTRL, RTPEM_MODE_NONE);
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
	f_rsl_chan_deact();
	f_rslem_unregister(0, g_chan_nr);
}
testcase TC_speech_rtp_tchf() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;

	f_init();

	/* TS1, TCH/F, V1 (FR codec) */
	pars := valueof(t_Pars(ts_RslChanNr_Bm(1), ts_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM1)));
	vc_conn := f_start_handler(refers(f_TC_speech_rtp), pars);
	vc_conn.done;

	/* TS1, TCH/F, V2 (EFR codec) */
	pars := valueof(t_Pars(ts_RslChanNr_Bm(1), ts_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM2)));
	vc_conn := f_start_handler(refers(f_TC_speech_rtp), pars);
	vc_conn.done;

	/* TS1, TCH/F, V3 (AMR codec) */
	pars := valueof(t_Pars(ts_RslChanNr_Bm(1), ts_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM3)));
	pars.mr_conf := valueof(ts_RSL_MultirateCfg);
	vc_conn := f_start_handler(refers(f_TC_speech_rtp), pars);
	vc_conn.done;

	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}
testcase TC_speech_rtp_tchh() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;

	f_init();

	/* TS5, TCH/H0, V1 (HR codec) */
	pars := valueof(t_Pars(ts_RslChanNr_Lm(5, 0), ts_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM1)));
	vc_conn := f_start_handler(refers(f_TC_speech_rtp), pars);
	vc_conn.done;

	/* TS1, TCH/H0, V3 (AMR codec) */
	pars := valueof(t_Pars(ts_RslChanNr_Lm(5, 0), ts_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM3)));
	pars.mr_conf := valueof(ts_RSL_MultirateCfg);
	vc_conn := f_start_handler(refers(f_TC_speech_rtp), pars);
	vc_conn.done;

	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}


/* Verify handling of Downlink and Uplink Osmux speech frames */
private function f_TC_speech_osmux(charstring id) runs on ConnHdlr {
	var L1ctlMessage l1_dl;
	var OSMUX_PDU osmux_pdu;
	var octetstring pl;
	var octetstring exp_rtp_pl;
	timer Td, Tu;

	f_l1_tune(L1CTL);
	f_est_dchan();

	/* Activate the RTP emulation */
	pl := f_rnd_octstring(6);
	f_osmuxem_activate(pl);

	/* Give the scheduler some time to fill up the buffers */
	f_sleep(2.0);
	L1CTL.clear;
	RSL.clear;

	/* we transmit using AMR_FT_2 (5.90), see t_TxHandleAMR590 in f_osmuxem_activate() */
	var integer amr_ft := get_start_amr_ft();
	var integer amr_pl_len := f_amrft_payload_len(amr_ft);
	var octetstring hdr := enc_RTP_AMR_Hdr(valueof(ts_RTP_AMR_Hdr(amr_ft, amr_ft, '1'B)));
	pl := f_osmux_gen_expected_rx_rtp_payload(amr_ft, pl);
	exp_rtp_pl := hdr & pl;

	/* Make sure that Downlink frames are received at the UE */
	Td.start(2.0);
	alt {
	[] L1CTL.receive(tr_L1CTL_TRAFFIC_IND(g_chan_nr, frame := exp_rtp_pl)) -> value l1_dl {
		log("TCH received: ", l1_dl.payload.traffic_ind.data);
		L1CTL.send(ts_L1CTL_TRAFFIC_REQ(g_chan_nr, l1_dl.dl_info.link_id,
			   l1_dl.payload.traffic_ind.data));
		setverdict(pass);
		}
	[] L1CTL.receive(tr_L1CTL_TRAFFIC_IND(g_chan_nr, frame := ?)) -> value l1_dl {
		setverdict(fail, "Rx unexpected Downlink speech frame ",
			   "(", l1_dl.payload.traffic_ind.data, ") ",
			   "expected (", exp_rtp_pl, ")");
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
		}
	[] as_l1_sacch();
	[] L1CTL.receive { repeat; }
	[] Td.timeout {
		setverdict(fail, "Timeout waiting for Downlink speech frames");
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
		}
	}

	/* Make sure that Uplink frames are received at the BTS */
	OsmuxEM_DATA.clear;
	var template (present) OSMUX_PDU osmux_pdu_exp := tr_PDU_Osmux_AMR(cid := g_pars.loc_osmux_cid,
									   amr_ft := amr_ft,
									   amr_cmr := amr_ft);
	Tu.start(2.0);
	alt {
	[] OsmuxEM_DATA.receive(osmux_pdu_exp) -> value osmux_pdu {
		var boolean matched := false;
		for (var integer i := 0; i < osmux_pdu.osmux_amr.header.ctr + 1; i := i + 1) {
			var octetstring rx_pl;
			rx_pl := f_osmux_amr_get_nth_amr_payload(osmux_pdu.osmux_amr, i);
			log("got ", rx_pl, " vs exp ", pl);
			if (rx_pl == pl) {
				matched := true;
				break;
			}
		}
		if (not matched) {
			repeat;
		}
		}
	[] OsmuxEM_DATA.receive { repeat; }
	[] Tu.timeout {
		setverdict(fail, "Timeout waiting for Uplink speech frames");
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
		}
	}

	f_osmuxem_mode(OsmuxEM_CTRL, OSMUXEM_MODE_NONE);
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
	f_rsl_chan_deact();
	f_rslem_unregister(0, g_chan_nr);
}
testcase TC_speech_osmux_tchf() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;

	f_init();

	/* TS5, TCH/H0, V3 (AMR codec) */
	pars := valueof(t_Pars(ts_RslChanNr_Bm(1), ts_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM3)));
	pars.mr_conf := valueof(ts_RSL_MultirateCfg);
	vc_conn := f_start_handler(refers(f_TC_speech_osmux), pars);
	vc_conn.done;

	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}
testcase TC_speech_osmux_tchh() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;

	f_init();

	/* TS5, TCH/H0, V3 (AMR codec) */
	pars := valueof(t_Pars(ts_RslChanNr_Lm(5, 0), ts_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM3)));
	pars.mr_conf := valueof(ts_RSL_MultirateCfg);
	vc_conn := f_start_handler(refers(f_TC_speech_osmux), pars);
	vc_conn.done;

	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

private function f_TC_early_immediate_assignment(charstring id) runs on ConnHdlr {
	var GsmFrameNumber fn;
	var ChannelDescription ch_desc;
	var integer ra := 23;

	f_l1_tune(L1CTL);
	RSL.clear;

	/* Send RACH request and wait for ChanReq */
	fn := f_rach_req_wait_chan_rqd(ra);

	/* The BSC already sends the Immediate Assignment, before the channel is active.
	 * (Also before the Channel Activation, even. I tried to write this test so that we first send the Chan Act and then the IMM
	 * ASS, but osmo-bts-trx responds so fast that the Chan Activ ACK comes back even before titan dispatches the
	 * IMM ASS. So move the IMM ASS even before the Chan Activ.) */
	if (g_pars.fhp.enabled) {
		ch_desc := valueof(ts_ChanDescH1(g_pars.chan_nr, g_pars.fhp.maio_hsn, g_pars.tsc));
	} else {
		ch_desc := valueof(ts_ChanDescH0(g_pars.chan_nr, mp_trx_pars[0].arfcn, g_pars.tsc));
	}
	var GsmRrMessage rr_msg := valueof(ts_IMM_ASS(ra, fn, 0, ch_desc, g_pars.fhp.ma_map));
	RSL.send(ts_RSL_IMM_ASSIGN(enc_GsmRrMessage(rr_msg)));

	/* Do not expect the Immediate Assignment to show up on MS side yet. Even give it one second before the BSC
	 * requests Chan Activ, to make sure the RR IMM ASS is held back. */
	var L1ctlMessage dl;
	var GsmRrMessage rr;

	var template GsmRrMessage rr_imm_ass := tr_IMM_ASS(ra, fn);
	rr_imm_ass.payload.imm_ass.ded_or_tbf := ?;
	rr_imm_ass.payload.imm_ass.pkt_chan_desc := *;
	rr_imm_ass.payload.imm_ass.chan_desc := *;

	timer T := 1.0;
	T.start;
	alt {
	[] L1CTL.receive(tr_L1CTL_DATA_IND(t_RslChanNr_PCH_AGCH(0))) -> value dl {
			rr := dec_GsmRrMessage(dl.payload.data_ind.payload);
			if (match(rr, rr_imm_ass)) {
				setverdict(fail, "Expected IMM ASS to be delayed until Chan Act ACK, but it was passed to the MS immediately");
				mtc.stop;
			} else {
				repeat;
			}
		}
	[] L1CTL.receive { repeat; }
	[] T.timeout;
	}
	RSL.send(ts_RSL_CHAN_ACT(g_chan_nr, g_pars.chan_mode, t_RSL_IE_ActType_IA));
	RSL.receive(tr_RSL_CHAN_ACT_ACK(g_chan_nr));

	/* Now expect the IMM ASS on Um */
	f_L1CTL_WAIT_IMM_ASS(L1CTL, ra, fn);
	setverdict(pass);

	/* Release the channel */
	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
}

testcase TC_early_immediate_assignment() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN));
	f_init();
	vc_conn := f_start_handler(refers(f_TC_early_immediate_assignment), pars);
	vc_conn.done;
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

private function f_TC_est_dchan(charstring id) runs on ConnHdlr {
	var integer ra := oct2int(f_rnd_ra_cs());
	var ChannelDescription ch_desc;

	/* Tune the MS to BCCH */
	f_l1_tune(L1CTL);

	/* Send RACH request and wait for ChanReq */
	var GsmFrameNumber fn := f_rach_req_wait_chan_rqd(ra);

	/* Activate channel on the BTS side */
	f_rsl_chan_act(g_pars.chan_mode);

	/* Craft channel description (with or without frequency hopping parameters) */
	if (g_pars.fhp.enabled) {
		ch_desc := valueof(ts_ChanDescH1(g_pars.chan_nr, g_pars.fhp.maio_hsn, g_pars.tsc));
	} else {
		ch_desc := valueof(ts_ChanDescH0(g_pars.chan_nr, mp_trx_pars[0].arfcn, g_pars.tsc));
	}

	/* Send IMM.ASS via CCHAN */
	var GsmRrMessage rr_msg := valueof(ts_IMM_ASS(ra, fn, 0, ch_desc, g_pars.fhp.ma_map));
	RSL.send(ts_RSL_IMM_ASSIGN(enc_GsmRrMessage(rr_msg)));

	/* Receive IMM.ASS on the MS side */
	var ImmediateAssignment imm_ass := f_L1CTL_WAIT_IMM_ASS(L1CTL, ra, fn);

	/* Match the Channel Description IE in received IMM.ASS */
	if (not match(imm_ass.chan_desc, ch_desc)) {
		setverdict(fail, "Channel Description IE does not match");
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
	}

	/* Tune the MS to a dedicated channel indicated in the IMM.ASS */
	f_L1CTL_DM_EST_REQ_IA(L1CTL, imm_ass, g_pars.fhp.ma);

	/* Expect SACCH frames on Downlink */
	L1CTL.clear;
	f_exp_sacch(true);

	/* We're done, deactivate and release */
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
	f_rsl_chan_deact();
}
testcase TC_est_dchan() runs on test_CT {
	var ConnHdlr vc_conn;
	var ConnHdlrPars pars;

	f_init();

	for (var integer i := 0; i < sizeof(g_AllChannels); i := i + 1) {
		pars := valueof(t_Pars(g_AllChannels[i], ts_RSL_ChanMode_SIGN));
		vc_conn := f_start_handler(refers(f_TC_est_dchan), pars);
		vc_conn.done;
	}

	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

private type record TopTestCase {
	RSL_IE_BS_Power		bs_power,
	RSL_IE_OSMO_TopAcchCap	top_cap,
	record of TopTestStep	steps
};
private type record TopTestStep {
	MeasurementResults	meas_res optional,
	GsmRxLev		overpower_sacch,
	GsmRxLev		overpower_facch
};

private function f_rxlev_match(template (present) RslLinkId link_id,
			       template (present) GsmRxLev rxlev)
runs on ConnHdlr {
	var L1ctlMessage dl := f_L1CTL_rx_data(L1CTL, g_chan_nr, link_id);
	if (not match(dl.dl_info.rx_level, rxlev)) {
		setverdict(fail, "RxLev(", link_id, ") := ", dl.dl_info.rx_level,
				 " does not match expected RxLev := ", rxlev);
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
	}
}

private function f_TC_acch_overpower(charstring id) runs on ConnHdlr {
	var TopTestCase tc := g_pars.spec.top;
	var GsmRxLev rxlev_dcch;
	var L1ctlMessage dl;

	/* Wait for Pau ramping to complete */
	f_sleep(6.0);

	f_l1_tune(L1CTL);
	L1CTL.clear;
	RSL.clear;

	/* Measure RxLev(BCCH), calculate RxLev(DCCH) */
	dl := f_L1CTL_rx_data(L1CTL, t_RslChanNr_BCCH(0));
	rxlev_dcch := dl.dl_info.rx_level - (tc.bs_power.power_level * 2);

	log("RxLev(BCCH) := ", dl.dl_info.rx_level);
	log("Expected RxLev(DCCH) := ", rxlev_dcch);

	/* Additional IEs for the CHANnel ACTIVation message */
	var template (value) RSL_IE_List ies := {
		/* Employ BS power control in static mode */
		t_RSL_IE(RSL_IE_MS_POWER, RSL_IE_Body:{
			bs_power := tc.bs_power
		}),
		/* Indicate the given Temporary Overpower capability */
		t_RSL_IE(RSL_IE_OSMO_TOP_ACCH_CAP, RSL_IE_Body:{
			top_acch_cap := tc.top_cap
		})
	};

	/* Establish a dedicated channel */
	f_est_dchan(more_ies := valueof(ies));

	/* Give it some time to stabilize */
	f_sleep(0.480 * 2.0);
	L1CTL.clear;
	RSL.clear;

	for (var integer i := 0; i < lengthof(tc.steps); i := i + 1) {
		var TopTestStep step := tc.steps[i];
		var GsmRxLev rxlev_facch := rxlev_dcch + step.overpower_facch;
		var GsmRxLev rxlev_sacch := rxlev_dcch + step.overpower_sacch;

		log("Executing step[", i, "] := ", step);

		/* Send RR Measurement Report (if present) */
		if (ispresent(step.meas_res)) {
			f_transceive_meas_rep(step.meas_res);
			f_sleep(0.480 * 2.0);
			L1CTL.clear;
		}

		/* Check RxLev on both FACCH and SACCH */
		f_rxlev_match(tr_RslLinkID_DCCH(?), rxlev_facch);
		f_rxlev_match(tr_RslLinkID_SACCH(?), rxlev_sacch);

		setverdict(pass);
	}

	f_rsl_chan_deact();
	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
	f_rslem_unregister(g_pars.trx_nr, g_chan_nr);
}
testcase TC_acch_overpower_rxqual_thresh() runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;

	f_init();

	/* Verify lower and upper RxQual thresholds */
	var template (value) TopTestCase top := {
		bs_power := ts_RSL_IE_BS_Power(4), /* 4 x 2dB = 8dB */
		top_cap := ts_RSL_IE_OSMO_TopAcchCap(4), /* 4dB */
		steps := {
			/* Channel established, no overpower */
			{ meas_res := omit,
			  overpower_sacch := 0, overpower_facch := 0 },

			/* Worst possible RxQual value, overpower of 4dB */
			{ meas_res := ts_MeasurementResults(rxq_f := 7),
			  overpower_sacch := 4, overpower_facch := 4 },
			/* Worst possible RxQual value, disabling overpower */
			{ meas_res := ts_MeasurementResults(rxq_f := 0),
			  overpower_sacch := 0, overpower_facch := 0 },

			/* Lower threshold not reached, no overpower */
			{ meas_res := ts_MeasurementResults(rxq_f := 1),
			  overpower_sacch := 0, overpower_facch := 0 },
			/* Lower threshold not reached, no overpower */
			{ meas_res := ts_MeasurementResults(rxq_f := 2),
			  overpower_sacch := 0, overpower_facch := 0 },
			/* Lower threshold reached, overpower of 4dB */
			{ meas_res := ts_MeasurementResults(rxq_f := 4),
			  overpower_sacch := 4, overpower_facch := 4 },
			/* Upper threshold not reached, keeping overpower */
			{ meas_res := ts_MeasurementResults(rxq_f := 3),
			  overpower_sacch := 4, overpower_facch := 4 },
			/* Upper threshold reached, disabling overpower */
			{ meas_res := ts_MeasurementResults(rxq_f := 2),
			  overpower_sacch := 0, overpower_facch := 0 }
		}
	};

	pars := valueof(t_Pars(t_RslChanNr_Bm(0), ts_RSL_ChanMode_SIGN,
			       spec := { top := top }, trx_nr := 1));
	vc_conn := f_start_handler(refers(f_TC_acch_overpower), pars);
	vc_conn.done;

	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}
testcase TC_acch_overpower_rxqual_thresh_dtx() runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;

	f_init();

	/* Verify handling of FULL and SUB values */
	var template (value) TopTestCase top := {
		bs_power := ts_RSL_IE_BS_Power(4), /* 4 x 2dB = 8dB */
		top_cap := ts_RSL_IE_OSMO_TopAcchCap(4), /* 4dB */
		steps := {
			/* Channel established, no overpower */
			{ meas_res := omit,
			  overpower_sacch := 0, overpower_facch := 0 },

			/* Invalid measurement results, no overpower */
			{ meas_res := ts_MeasurementResults(rxq_f := 7,
							    rxq_s := 7,
							    valid := false),
			  overpower_sacch := 0, overpower_facch := 0 },

			/* DTXu was in use, no overpower */
			{ meas_res := ts_MeasurementResults(rxq_f := 7,
							    rxq_s := 0,
							    dtx_used := true),
			  overpower_sacch := 0, overpower_facch := 0 },
			/* DTXu was in use, overpower of 4 dB */
			{ meas_res := ts_MeasurementResults(rxq_f := 0,
							    rxq_s := 7,
							    dtx_used := true),
			  overpower_sacch := 4, overpower_facch := 4 }
		}
	};

	pars := valueof(t_Pars(t_RslChanNr_Bm(0), ts_RSL_ChanMode_SIGN,
			       spec := { top := top }, trx_nr := 1));
	vc_conn := f_start_handler(refers(f_TC_acch_overpower), pars);
	vc_conn.done;

	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}
testcase TC_acch_overpower_always_on_facch() runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;

	f_init();

	/* Overpower is always on, SACCH disabled */
	var template (value) TopTestCase top := {
		bs_power := ts_RSL_IE_BS_Power(4), /* 4 x 2dB = 8dB */
		top_cap := ts_RSL_IE_OSMO_TopAcchCap(overpower := 4, /* 4dB */
						     rxqual := 0, /* always on */
						     sacch_enable := false),
		steps := {
			/* Channel established, FACCH overpower */
			{ meas_res := omit,
			  overpower_sacch := 0, overpower_facch := 4 },
			/* MS indicates good RxQual, no difference */
			{ meas_res := ts_MeasurementResults(rxq_f := 0),
			  overpower_sacch := 0, overpower_facch := 4 },
			/* MS indicates bad RxQual, no difference */
			{ meas_res := ts_MeasurementResults(rxq_f := 7),
			  overpower_sacch := 0, overpower_facch := 4 }
		}
	};

	pars := valueof(t_Pars(t_RslChanNr_Bm(0), ts_RSL_ChanMode_SIGN,
			       spec := { top := top }, trx_nr := 1));
	vc_conn := f_start_handler(refers(f_TC_acch_overpower), pars);
	vc_conn.done;

	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}
testcase TC_acch_overpower_always_on_sacch() runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;

	f_init();

	/* Overpower is always on, FACCH disabled */
	var template (value) TopTestCase top := {
		bs_power := ts_RSL_IE_BS_Power(4), /* 4 x 2dB = 8dB */
		top_cap := ts_RSL_IE_OSMO_TopAcchCap(overpower := 4, /* 4dB */
						     rxqual := 0, /* always on */
						     facch_enable := false),
		steps := {
			/* Channel established, SACCH overpower */
			{ meas_res := omit,
			  overpower_sacch := 4, overpower_facch := 0 },
			/* MS indicates good RxQual, no difference */
			{ meas_res := ts_MeasurementResults(rxq_f := 0),
			  overpower_sacch := 4, overpower_facch := 0 },
			/* MS indicates bad RxQual, no difference */
			{ meas_res := ts_MeasurementResults(rxq_f := 7),
			  overpower_sacch := 4, overpower_facch := 0 }
		}
	};

	pars := valueof(t_Pars(t_RslChanNr_Bm(0), ts_RSL_ChanMode_SIGN,
			       spec := { top := top }, trx_nr := 1));
	vc_conn := f_start_handler(refers(f_TC_acch_overpower), pars);
	vc_conn.done;

	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}
testcase TC_acch_overpower_limit() runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;

	f_init();

	/* Overpower higher than current power reduction level (2dB) */
	var template (value) TopTestCase top := {
		bs_power := ts_RSL_IE_BS_Power(1), /* 1 x 2dB = 2dB */
		top_cap := ts_RSL_IE_OSMO_TopAcchCap(overpower := 4, /* 4dB */
						     rxqual := 0 /* always on */),
		steps := {
			/* Channel established, ACCH overpower of 2dB */
			{ meas_res := omit,
			  overpower_sacch := 2, overpower_facch := 2 },
			/* MS indicates good RxQual, no difference */
			{ meas_res := ts_MeasurementResults(rxq_f := 0),
			  overpower_sacch := 2, overpower_facch := 2 },
			/* MS indicates bad RxQual, no difference */
			{ meas_res := ts_MeasurementResults(rxq_f := 7),
			  overpower_sacch := 2, overpower_facch := 2 }
		}
	};

	pars := valueof(t_Pars(t_RslChanNr_Bm(0), ts_RSL_ChanMode_SIGN,
			       spec := { top := top }, trx_nr := 1));
	vc_conn := f_start_handler(refers(f_TC_acch_overpower), pars);
	vc_conn.done;

	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}

/* test generation of RLL ERR IND based on Um errors (TS 48.058 3.9) */
/*	protocol error as per 44.006 */
/*	link layer failure (repetition of I-frame N200 times without ACK */
/*	repetition of SABM or DISC N200 times without ACK */
/*	receptiom of SABM in multi-frame established state */


/* TODO Areas:

* channel activation
** with BS_Power / MS_Power, bypassing power control loop
** on primary vs. secondary TRX
** with timing advance from initial activation on
* mode modify
** encryption
** multirate
* check DEACTIVATE SACCH
** unsupported algorithm
* BS Power Control
* Physical Context
* error handling
** IE duplicated?
* PCU interface
** DATA_IND from BTS->PCU
** verification of PCU-originated DATA_REQ arrival on Um/MS side

*/

control {
	execute( TC_est_dchan() );
	execute( TC_chan_act_stress() );
	execute( TC_chan_act_react() );
	execute( TC_chan_deact_not_active() );
	execute( TC_chan_act_wrong_nr() );
	execute( TC_deact_sacch() );
	execute( TC_sacch_filling() );
	execute( TC_sacch_info_mod() );
	execute( TC_sacch_multi() );
	execute( TC_sacch_multi_chg() );
	execute( TC_sacch_chan_act() );
	execute( TC_sacch_chan_act_ho_async() );
	execute( TC_sacch_chan_act_ho_sync() );
	execute( TC_rach_content() );
	execute( TC_rach_content_emerg() );
	execute( TC_rach_count() );
	execute( TC_rach_max_ta() );
	execute( TC_ho_rach() );
	execute( TC_ho_physical_info() );
	execute( TC_rach_load_idle_thresh0() );
	execute( TC_rach_load_idle_below_thresh() );
	execute( TC_rach_load_count() );
	execute( TC_meas_res_speech_tchf() );
	execute( TC_meas_res_speech_tchf_facch() );
	execute( TC_meas_res_speech_tchh() );
	execute( TC_meas_res_speech_tchh_facch() );
	execute( TC_meas_res_speech_tchh_toa256() );
	execute( TC_meas_res_sign_tchf() );
	execute( TC_meas_res_sign_tchh() );
	execute( TC_meas_res_sign_sdcch4() );
	execute( TC_meas_res_sign_sdcch8() );
	execute( TC_meas_res_sign_tchh_toa256() );
	execute( TC_meas_res_speech_tchf_sapi3() );
	execute( TC_meas_res_speech_tchh_sapi3() );
	execute( TC_tx_power_start_ramp_up_bcch() );
	execute( TC_tx_power_down_bcch() );
	execute( TC_tx_power_ramp_adm_state_change() );
	execute( TC_rsl_bs_pwr_static_ass() );
	execute( TC_rsl_bs_pwr_static_power_control() );
	execute( TC_rsl_ms_pwr_ctrl() );
	execute( TC_rsl_ms_pwr_dyn_active() );
	execute( TC_rsl_ms_pwr_dyn_active2() );
	execute( TC_rsl_ms_pwr_dyn_up() );
	execute( TC_rsl_ms_pwr_dyn_down() );
	execute( TC_rsl_ms_pwr_dyn_ass_updown() );
	execute( TC_rsl_ms_pwr_dyn_max() );
	execute( TC_rsl_chan_initial_ms_pwr() );
	execute( TC_rsl_chan_initial_ta() );
	execute( TC_rsl_modify_encr() );
	execute( TC_rsl_rf_resource_ind() );
	execute( TC_conn_fail_crit() );
	execute( TC_paging_imsi_80percent() );
	execute( TC_paging_tmsi_80percent() );
	execute( TC_paging_imsi_200percent() );
	execute( TC_paging_tmsi_200percent() );
	execute( TC_rsl_protocol_error() );
	execute( TC_rsl_mand_ie_error() );
	execute( TC_rsl_ie_content_error() );
	execute( TC_si_sched_default() );
	execute( TC_si_sched_1() );
	execute( TC_si_sched_2bis() );
	execute( TC_si_sched_2ter() );
	execute( TC_si_sched_2ter_2bis() );
	execute( TC_si_sched_2quater() );
	execute( TC_si_sched_13() );
	execute( TC_si_sched_13_2bis_2ter_2quater() );
	execute( TC_ipa_dlcx_not_active() );
	execute( TC_ipa_crcx_twice_not_active() );
	execute( TC_ipa_crcx_mdcx_dlcx_not_active() );
	execute( TC_ipa_crcx_mdcx_mdcx_dlcx_not_active() );
	execute( TC_ipa_crcx_sdcch_not_active() );
	execute( TC_ipa_crcx_ack_addr() );

	if (mp_pcu_socket != "") {
		execute( TC_paging_imsi_200percent_with_ps() );
		execute( TC_pcu_act_req() );
		execute( TC_pcu_act_req_wrong_ts() );
		execute( TC_pcu_act_req_wrong_bts() );
		execute( TC_pcu_act_req_wrong_trx() );
		execute( TC_pcu_deact_req() );
		execute( TC_pcu_deact_req_wrong_ts() );
		execute( TC_pcu_ver_si1() );
		execute( TC_pcu_ver_si3() );
		execute( TC_pcu_ver_si13() );
		if (mp_l1_supports_gprs) {
			execute( TC_pcu_data_req_pdtch() );
			execute( TC_pcu_data_req_ptcch() );
			execute( TC_pcu_data_req_wrong_bts() );
			execute( TC_pcu_data_req_wrong_trx() );
			execute( TC_pcu_data_req_wrong_ts() );
			execute( TC_pcu_data_req_ts_inactive() );
		}
		execute( TC_pcu_ptcch() );
		execute( TC_pcu_data_req_agch() );
		execute( TC_pcu_data_req_pch() );
		execute( TC_pcu_data_req_imm_ass_pch() );
		execute( TC_pcu_rach_content() );
		execute( TC_pcu_ext_rach_content() );
		execute( TC_pcu_data_ind_lqual_cb() );
		execute( TC_pcu_paging_from_rsl() );
		execute( TC_pcu_time_ind() );
		execute( TC_pcu_rts_req() );
		execute( TC_pcu_oml_alert() );
		execute( TC_pcu_rr_suspend() );
		execute( TC_pcu_socket_connect_multi() );
		execute( TC_pcu_socket_reconnect() );
		execute( TC_pcu_socket_noconnect_nosi3gprs() );
		execute( TC_pcu_socket_noconnect_nosi4gprs() );
		execute( TC_pcu_socket_connect_si3gprs() );
		execute( TC_pcu_socket_connect_si4gprs() );
		execute( TC_pcu_socket_disconnect_nosi3gprs() );
		execute( TC_pcu_socket_disconnect_nosi4gprs() );
		execute( TC_pcu_socket_verify_info_ind() );
		execute( TC_dyn_osmo_pdch_act_deact() );
		execute( TC_dyn_osmo_pdch_double_act() );
		execute( TC_dyn_ipa_pdch_act_deact() );
		execute( TC_dyn_ipa_pdch_act_tchf_act_nack() );
		execute( TC_pcu_info_ind_fh_params() );
		execute( TC_pcu_socket_nsvc_ipv4() );
		execute( TC_pcu_socket_nsvc_ipv6() );
		execute( TC_pcu_socket_two_nsvc() );
		execute( TC_pcu_interf_ind() );
	} else {
		log("PCU socket path not available, skipping PCU tests");
	}

	execute( TC_dyn_osmo_pdch_unsol_deact() );
	execute( TC_dyn_osmo_pdch_tchf_act() );
	execute( TC_dyn_osmo_pdch_tchh_act() );
	execute( TC_dyn_osmo_pdch_sdcch8_act() );
	execute( TC_dyn_ipa_pdch_tchf_act() );
	execute( TC_dyn_ipa_pdch_tchf_act_pdch_act_nack() );

	execute( TC_rll_est_ind() );
	execute( TC_rll_est_req_DCCH_3() );
	execute( TC_rll_est_req_ACCH_3() );
	execute( TC_rll_rel_ind_DCCH_0() );
	execute( TC_rll_rel_ind_DCCH_3() );
	execute( TC_rll_rel_ind_ACCH_0() );
	execute( TC_rll_rel_ind_ACCH_3() );
	execute( TC_rll_rel_req() );
	execute( TC_rll_unit_data_req_DCCH() );
	execute( TC_rll_unit_data_req_ACCH() );
	execute( TC_rll_unit_data_ind_DCCH() );
	execute( TC_rll_unit_data_ind_ACCH() );

	execute( TC_chan_act_a51() );
	execute( TC_chan_act_a52() );
	execute( TC_chan_act_a53() );
	execute( TC_chan_act_a54() );
	execute( TC_encr_cmd_a51() );
	execute( TC_encr_cmd_a52() );
	execute( TC_encr_cmd_a53() );
	execute( TC_encr_cmd_a54() );

	execute( TC_err_rep_wrong_mdisc() );
	execute( TC_err_rep_wrong_msg_type() );
	execute( TC_err_rep_wrong_sequence() );

	execute( TC_lapdm_selftest() );

	execute( TC_tch_sign_l2_fill_frame() );
	execute( TC_tch_sign_l2_fill_frame_dtxd() );

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

	execute( TC_ms_pwr_ctrl_constant() );
	execute( TC_ms_pwr_ctrl_pf_ewma() );

	execute( TC_speech_no_rtp_tchf() );
	execute( TC_speech_no_rtp_tchh() );
	execute( TC_speech_rtp_tchf() );
	execute( TC_speech_rtp_tchh() );
	execute( TC_speech_osmux_tchf() );
	execute( TC_speech_osmux_tchh() );

	execute( TC_early_immediate_assignment() );

	execute( TC_acch_overpower_rxqual_thresh() );
	execute( TC_acch_overpower_rxqual_thresh_dtx() );
	execute( TC_acch_overpower_always_on_facch() );
	execute( TC_acch_overpower_always_on_sacch() );
	execute( TC_acch_overpower_limit() );

	/* BEWARE: these test cases can potentially break the IUT or cause
	 * weird/unexpected behavior.  Ensure that they are executed last. */
	execute( TC_dyn_osmo_pdch_tchh_race_act() );
	execute( TC_dyn_osmo_pdch_sdcch8_race_act() );
}


}
