module PCU_Tests {

/* "RAW" PCU tests: Talk directly to the PCU socket of OsmoPCU on the one hand side (emulating
   the BTS/BSC side PCU socket server) and the Gb interface on the other hand side.  No NS/BSSGP
   Emulation is used; rather, we simply use the NS_CodecPort to implement both standard and non-
   standard procedures on the NS and BSSGP level.  The goal of these tests is to test exactly
   those NS and BSSGP implementations on the BSS (PCU) side. */

/* (C) 2018-2019 Harald Welte <laforge@gnumonks.org>
 * (C) 2019 Vadim Yanitskiy <axilirator@gmail.com>
 * 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
 */

friend module PCU_Tests_NS;

import from General_Types all;
import from Osmocom_Types all;
import from GSM_Types all;
import from GSM_RR_Types all;

import from Osmocom_VTY_Functions all;
import from TELNETasp_PortType all;

import from MobileL3_GMM_SM_Types all;
import from RLCMAC_CSN1_Types all;
import from RLCMAC_CSN1_Templates all;
import from RLCMAC_Types all;
import from RLCMAC_Templates all;

import from MobileL3_CommonIE_Types all;
import from L3_Templates all;

import from NS_Types all;
import from BSSGP_Types all;
import from Osmocom_Gb_Types all;

import from BSSGP_Emulation all; /* BssgpConfig */
import from NS_Emulation all; /* NSConfiguration */

import from UD_Types all;
import from PCUIF_Types all;
import from PCUIF_CodecPort all;
import from PCUIF_Components all;
import from IPL4asp_Types all;
import from Native_Functions all;
import from SGSN_Components all;

modulepar {
	charstring mp_pcu_sock_path := PCU_SOCK_DEFAULT;

	float X2002 := 0.2; /* Timer -2002, IMM ASSIGN confirm delay */
}


/* FIXME: make sure to use parameters from mp_gb_cfg.cell_id in the PCU INFO IND */
private template (value) PCUIF_info_ind ts_PCUIF_INFO_default := {
	version := PCU_IF_VERSION,
	flags := c_PCUIF_Flags_default,
	trx := valueof(ts_PCUIF_InfoTrxs_def),
	bsic := 7,
	mcc := 262,
	mnc := 42,
	mnc_3_digits := 0,
	lac := 13135,
	rac := 0,
	nsei := mp_nsconfig.nsei,
	nse_timer := { 3, 3, 3, 3, 30, 3, 10 },
	cell_timer := { 3, 3, 3, 3, 3, 10, 3, 10, 3, 10, 3 },
	cell_id := 20960,
	repeat_time := 5 * 50,
	repeat_count := 3,
	bvci := mp_gb_cfg.bvci,
	t3142 := 20,
	t3169 := 5,
	t3191 := 5,
	t3193_10ms := 160,
	t3195 := 5,
	t3101 := 10,
	t3103 := 4,
	t3105 := 8,
	cv_countdown := 15,
	dl_tbf_ext := 250 * 10, /* ms */
	ul_tbf_ext := 250 * 10, /* ms */
	initial_cs := 2,
	initial_mcs := 6,
	nsvci := { mp_nsconfig.nsvci, 0 },
	local_pprt := { mp_nsconfig.remote_udp_port, 0 },
	remote_port := { mp_nsconfig.local_udp_port, 0 },
	remote_ip := { f_inet_haddr(mp_nsconfig.local_ip) , '00000000'O }
}

type record lqual_range {
	/* component reference to the IPA_Client component used for RSL */
	uint8_t low,
	uint8_t high
}

type component RAW_PCU_Test_CT extends bssgp_CT {
	/* PCU interface abstraction component */
	var RAW_PCUIF_CT vc_PCUIF;
	/* Virtual BTS component */
	var RAW_PCU_BTS_CT vc_BTS;

	/* Connection to the BTS component (one for now) */
	port RAW_PCU_MSG_PT BTS;
	/* Connection to the PCUIF component */
	port RAW_PCU_MSG_PT PCUIF;
	/* VTY connection to the PCU */
	port TELNETasp_PT PCUVTY;

	/* Uplink CS/MCS thresholds, default from pcu_main.c: */
	var lqual_range g_cs_lqual_ranges[4] := {{low := 0, high := 6},
						 {low := 5, high := 8},
						 {low := 7, high := 13},
						 {low := 12,high := 35}};
	var lqual_range g_mcs_lqual_ranges[9] := {{low := 0, high := 6},
						 {low := 5, high := 8},
						 {low := 7, high := 13},
						 {low := 12,high := 15},
						 {low := 14, high := 17},
						 {low := 16, high := 18},
						 {low := 17,high := 20},
						 {low := 19, high := 24},
						 {low := 23,high := 35}};
	var uint8_t g_cs_initial_dl := 1;
	var uint8_t g_cs_initial_ul := 1;
	var uint8_t g_mcs_initial_dl := 1;
	var uint8_t g_mcs_initial_ul := 1;
	var uint8_t g_cs_max_dl := 4;
	var uint8_t g_cs_max_ul := 4;
	var uint8_t g_mcs_max_dl := 9;
	var uint8_t g_mcs_max_ul := 9;

	var boolean g_egprs_only := false;

	/* Guard timeout */
	timer g_T_guard := 60.0;
};

private altstep as_Tguard_RAW() runs on RAW_PCU_Test_CT {
	[] g_T_guard.timeout {
		setverdict(fail, "Timeout of T_guard");
		f_shutdown(__BFILE__, __LINE__);
		}
}

private function f_pcuvty_set_allowed_cs_mcs() runs on RAW_PCU_Test_CT {
	f_vty_config2(PCUVTY, {"pcu"}, "cs " & int2str(g_cs_initial_dl) & " " & int2str(g_cs_initial_ul));
	f_vty_config2(PCUVTY, {"pcu"}, "cs max " & int2str(g_cs_max_dl) & " " & int2str(g_cs_max_ul));

	f_vty_config2(PCUVTY, {"pcu"}, "mcs " & int2str(g_mcs_initial_dl) & " " & int2str(g_mcs_initial_ul));
	f_vty_config2(PCUVTY, {"pcu"}, "mcs max " & int2str(g_mcs_max_dl) & " " & int2str(g_mcs_max_ul));
}

private function f_pcuvty_set_link_quality_ranges() runs on RAW_PCU_Test_CT {
	var charstring cmd;

	cmd := "cs link-quality-ranges" &
	       " cs1 " & int2str(g_cs_lqual_ranges[0].high) &
	       " cs2 " & int2str(g_cs_lqual_ranges[1].low) & " " & int2str(g_cs_lqual_ranges[1].high) &
	       " cs3 " & int2str(g_cs_lqual_ranges[2].low) & " " & int2str(g_cs_lqual_ranges[2].high) &
	       " cs4 " & int2str(g_cs_lqual_ranges[3].low);
	f_vty_config2(PCUVTY, {"pcu"}, cmd);

	cmd := "mcs link-quality-ranges" &
	       " mcs1 " & int2str(g_mcs_lqual_ranges[0].high) &
	       " mcs2 " & int2str(g_mcs_lqual_ranges[1].low) & " " & int2str(g_mcs_lqual_ranges[1].high) &
	       " mcs3 " & int2str(g_mcs_lqual_ranges[2].low) & " " & int2str(g_mcs_lqual_ranges[2].high) &
	       " mcs4 " & int2str(g_mcs_lqual_ranges[3].low) & " " & int2str(g_mcs_lqual_ranges[3].high) &
	       " mcs5 " & int2str(g_mcs_lqual_ranges[4].low) & " " & int2str(g_mcs_lqual_ranges[4].high) &
	       " mcs6 " & int2str(g_mcs_lqual_ranges[5].low) & " " & int2str(g_mcs_lqual_ranges[5].high) &
	       " mcs7 " & int2str(g_mcs_lqual_ranges[6].low) & " " & int2str(g_mcs_lqual_ranges[6].high) &
	       " mcs8 " & int2str(g_mcs_lqual_ranges[7].low) & " " & int2str(g_mcs_lqual_ranges[7].high) &
	       " mcs9 " & int2str(g_mcs_lqual_ranges[8].low);
	f_vty_config2(PCUVTY, {"pcu"}, cmd);
}

private function f_init_vty(charstring id) runs on RAW_PCU_Test_CT {
	map(self:PCUVTY, system:PCUVTY);
	f_vty_set_prompts(PCUVTY);
	f_vty_transceive(PCUVTY, "enable");

	if (g_egprs_only) {
		f_vty_config2(PCUVTY, {"pcu"}, "egprs only");
	} else {
		f_vty_config2(PCUVTY, {"pcu"}, "no egprs");
	}
}

function f_init_raw(charstring id, template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default)
runs on RAW_PCU_Test_CT {
	/* Start the guard timer */
	g_T_guard.start;
	activate(as_Tguard_RAW());

	/* Init PCU interface component */
	vc_PCUIF := RAW_PCUIF_CT.create("PCUIF-" & id);
	connect(vc_PCUIF:MTC, self:PCUIF);
	map(vc_PCUIF:PCU, system:PCU);

	/* Create one BTS component (we may want more some day) */
	vc_BTS := RAW_PCU_BTS_CT.create("BTS-" & id);
	connect(vc_BTS:PCUIF, vc_PCUIF:BTS);
	connect(vc_BTS:TC, self:BTS);

	f_init_vty(id);

	vc_PCUIF.start(f_PCUIF_CT_handler(mp_pcu_sock_path));
	vc_BTS.start(f_BTS_CT_handler(0, valueof(info_ind)));

	/* Wait until the BTS is ready (SI13 negotiated) */
	BTS.receive(tr_RAW_PCU_EV(BTS_EV_SI13_NEGO));
}

private function f_shutdown(charstring file, integer line,
			    boolean final := false)
runs on RAW_PCU_Test_CT {
	/* Determine if the test case was aborted in the middle */
	if (not final) {
		log("Test case ", testcasename(), " aborted at ", file, ":", line);
	} else {
		/* Guard verdict to avoid 'none' */
		setverdict(pass);
	}

	/* Properly shutdown virtual BTS and its clock generator */
	BTS.send(ts_RAW_PCU_CMD(GENERAL_CMD_SHUTDOWN));
	vc_BTS.done; /* wait untill it's done */

	/* Shutdown the others and MTC */
	all component.stop;
	mtc.stop;
}

template AckNackDescription t_AckNackDescription_init := {
	final_ack := '0'B,
	starting_seq_nr := 0,
	receive_block_bitmap := '0000000000000000000000000000000000000000000000000000000000000000'B
}

private function f_rlcmac_dl_block_get_tfi(RlcmacDlBlock dl_block) return uint5_t {
	if (ischosen(dl_block.data)) {
		return dl_block.data.mac_hdr.hdr_ext.tfi;
	} else {
		return dl_block.data_egprs.mac_hdr.tfi;
	}
}

/* TS 44.060 sec 12.3 Ack/Nack Description */
private function f_acknackdesc_ack_block(inout AckNackDescription desc, RlcmacDlBlock dl_block, BIT1 final_ack := '0'B)
{
	var uint7_t bsn;
	var integer i;
	var integer inc;

	if (ischosen(dl_block.data)) {
		bsn := dl_block.data.mac_hdr.hdr_ext.bsn;
	} else {
		bsn := dl_block.data_egprs.mac_hdr.bsn1;
	}

	inc := bsn - desc.starting_seq_nr + 1;
	/* Filling hole? */
	if (bsn < desc.starting_seq_nr) {
		desc.receive_block_bitmap[lengthof(desc.receive_block_bitmap) - (desc.starting_seq_nr - bsn)] := int2bit(1, 1);
		return;
	}

	/* SSN is increased, and so RBB values need to be moved */
	for (i := 0; i < lengthof(desc.receive_block_bitmap) - inc; i := i+1) {
		desc.receive_block_bitmap[i] := desc.receive_block_bitmap[i + inc];
	}
	for (i := lengthof(desc.receive_block_bitmap) - inc; i < lengthof(desc.receive_block_bitmap) - 1; i := i+1) {
		desc.receive_block_bitmap[i] := int2bit(0, 1);
	}
	/* Now we can set current bit and update SSN */
	desc.starting_seq_nr := bsn + 1;
	desc.receive_block_bitmap[lengthof(desc.receive_block_bitmap) - 1] := int2bit(1, 1);

	/* Finally update the final_ack bit as requested: */
	desc.final_ack := final_ack;
}

/* This function can be used to send DATA.cnf in response to the IUT originated DATA.req.
 * NOTE: it's the responsibility of caller to make sure that pcu_msg contains u.data_req. */
private function f_pcuif_tx_data_cnf(in PCUIF_Message pcu_msg)
runs on RAW_PCU_Test_CT {
	var PCUIF_Message pcu_msg_cnf := {
		msg_type := PCU_IF_MSG_DATA_CNF,
		bts_nr := pcu_msg.bts_nr,
		spare := pcu_msg.spare,
		u := { data_cnf := pcu_msg.u.data_req }
	};

	/* PCU wants DATA.cnf containing basically everything that was in DATA.req,
	 * but PCU_IF_SAPI_PCH is a special case - paging group shall be excluded. */
	if (pcu_msg.u.data_req.sapi == PCU_IF_SAPI_PCH) {
		pcu_msg_cnf.u.data_cnf.data := substr(pcu_msg.u.data_req.data, 3,
						      pcu_msg.u.data_req.len - 3);
	}

	BTS.send(pcu_msg_cnf);
}

private function f_pcuif_rx_imm_ass(out GsmRrMessage rr_imm_ass,
				    template PCUIF_Sapi sapi := PCU_IF_SAPI_AGCH,
				    template GsmRrMessage t_imm_ass := ?,
				    uint8_t bts_nr := 0)
runs on RAW_PCU_Test_CT return boolean {
	var PCUIF_Message pcu_msg;
	var octetstring data;
	timer T;

	T.start(2.0);
	alt {
	[] BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := bts_nr, trx_nr := 0, ts_nr := 0,
					 sapi := sapi, data := ?)) -> value pcu_msg {
		/* On PCH the payload is prefixed with paging group (3 octets): skip it.
		 * TODO: add an additional template parameter, so we can match it. */
		if (pcu_msg.u.data_req.sapi == PCU_IF_SAPI_PCH) {
			data := substr(pcu_msg.u.data_req.data, 3, pcu_msg.u.data_req.len - 3);
		} else {
			data := pcu_msg.u.data_req.data;
		}

		rr_imm_ass := dec_GsmRrMessage(data);
		if (not match(rr_imm_ass, t_imm_ass)) {
			/* Not for us? Wait for more. */
			repeat;
		}

		log("Rx Immediate Assignment: ", rr_imm_ass);
		setverdict(pass);
		return true;
		}
	[] BTS.receive { repeat; }
	[] T.timeout {
		setverdict(fail, "Timeout waiting for Immediate Assignment");
		}
	}

	return false;
}

/* One phase packet access (see 3GPP TS 44.018, table 9.1.8.1) */
private const BIT8 chan_req_def := '01111000'B;

/* Establish an Uplink TBF by sending RACH.ind towards the PCU */
private function f_establish_tbf(out GsmRrMessage rr_imm_ass, uint8_t bts_nr := 0,
				 uint16_t ra := bit2int(chan_req_def),
				 uint8_t is_11bit := 0,
				 PCUIF_BurstType burst_type := BURST_TYPE_0,
				 TimingAdvance ta := 0)
runs on RAW_PCU_Test_CT return boolean {
	var uint32_t fn;

	/* FIXME: ask the BTS component to give us the current TDMA fn */
	fn := 1337 + ta;

	/* Send RACH.ind */
	log("Sending RACH.ind on fn=", fn, " with RA=", ra, ", TA=", ta);
	BTS.send(ts_PCUIF_RACH_IND(bts_nr := bts_nr, trx_nr := 0, ts_nr := 0,
				   ra := ra, is_11bit := is_11bit,
				   burst_type := burst_type,
				   fn := fn, arfcn := 871,
				   qta := ta * 4));

	/* 3GPP TS 44.018, table 9.1.8.1, note 2b: Request Reference shall be set to 127
	 * when Immediate Assignment is triggered by EGPRS Packet Channel Request. Here
	 * we assume that 11 bit RA always contains EGPRS Packet Channel Request. */
	if (is_11bit != 0) { ra := 127; }

	/* Expect Immediate (TBF) Assignment on TS0/AGCH */
	return f_pcuif_rx_imm_ass(rr_imm_ass, PCU_IF_SAPI_AGCH,
				  tr_IMM_TBF_ASS(false, ra, fn),
				  bts_nr := bts_nr);
}

private function f_imm_ass_verify_ul_tbf_ass(in GsmRrMessage rr_imm_ass, out PacketUlAssign ul_tbf_ass)
runs on RAW_PCU_Test_CT {

	/* Make sure we received an UL TBF Assignment */
	if (match(rr_imm_ass, tr_IMM_TBF_ASS(dl := false, rest := tr_IaRestOctets_ULAss(?)))) {
		ul_tbf_ass := rr_imm_ass.payload.imm_ass.rest_octets.hh.pa.uldl.ass.ul;
		log("Rx Uplink TBF assignment: ", ul_tbf_ass);
		setverdict(pass);
	} else {
		setverdict(fail, "Failed to match UL TBF Assignment");
		f_shutdown(__BFILE__, __LINE__);
	}

	/* Make sure we have got a TBF with Dynamic Block Allocation */
	if (ul_tbf_ass.dynamic == omit) {
		setverdict(fail, "Single Block Allocation is not handled by ", testcasename());
		f_shutdown(__BFILE__, __LINE__);
	}
}

private function f_imm_ass_verify_dl_tbf_ass(in GsmRrMessage rr_imm_ass, out PacketDlAssign dl_tbf_ass)
runs on RAW_PCU_Test_CT {

	/* Make sure we received a DL TBF Assignment */
	if (match(rr_imm_ass, tr_IMM_TBF_ASS(dl := true, rest := tr_IaRestOctets_DLAss(?)))) {
		dl_tbf_ass := rr_imm_ass.payload.imm_ass.rest_octets.hh.pa.uldl.ass.dl;
		log("Rx Downlink TBF assignment: ", dl_tbf_ass);
		setverdict(pass);
	} else {
		setverdict(fail, "Failed to match DL TBF Assignment");
		f_shutdown(__BFILE__, __LINE__);
	}
}

/* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
function f_pcuif_tx_data_ind(octetstring data, int16_t lqual_cb := 0, uint32_t fn := 0)
runs on RAW_PCU_Test_CT {
	var template RAW_PCU_EventParam ev_param := {tdma_fn := ? };
	BTS.send(ts_PCUIF_DATA_IND(bts_nr := 0, trx_nr := 0, ts_nr := 7, block_nr := 0,
				   sapi := PCU_IF_SAPI_PDTCH, data := data,
				   fn := fn, arfcn := 871, lqual_cb := lqual_cb));
	if (fn != 0) {
		ev_param := {tdma_fn := fn };
	}
	BTS.receive(tr_RAW_PCU_EV(TDMA_EV_PDTCH_BLOCK_SENT, ev_param));
}

/* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
private function f_pcuif_rx_data_req(out PCUIF_Message pcu_msg)
runs on RAW_PCU_Test_CT {
	BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
				  sapi := PCU_IF_SAPI_PDTCH, fn := 0,
				  arfcn := 871, block_nr := 0));
	BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
				      sapi := PCU_IF_SAPI_PDTCH)) -> value pcu_msg;
}

/* Expect an Immediate Assignment (paging) from PCU on PCUIF on specified sapi.  */
private function f_pcuif_rx_pch_imm_tbf_ass(out GsmRrMessage rr_imm_ass)
runs on RAW_PCU_Test_CT {
	var PCUIF_Message pcu_msg;
	var octetstring macblock;
	BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 0,
				      sapi := PCU_IF_SAPI_PCH)) -> value pcu_msg;
	/* First 3 bytes contain paging group: */
	macblock := substr(pcu_msg.u.data_req.data, 3, pcu_msg.u.data_req.len - 3);
	rr_imm_ass := dec_GsmRrMessage(macblock);
	if (not match(rr_imm_ass, tr_IMM_TBF_ASS())) {
		setverdict(fail, "Failed to match Immediate Assignment: ", rr_imm_ass);
		f_shutdown(__BFILE__, __LINE__);
	}
	f_pcuif_tx_data_cnf(pcu_msg);
}

/* Expect a Paging Request Type 1 from PCU on PCUIF on specified sapi.  */
private function f_pcuif_rx_pch_pag_req1(template MobileIdentityV mi1 := ?,
					 template integer pag_group := ?)
runs on RAW_PCU_Test_CT return GsmRrMessage {
	var GsmRrMessage rr_pag_req1;
	var PCUIF_Message pcu_msg;
	var octetstring imsi_suff_octstr;
	var integer pag_group_rx;
	var octetstring macblock;

	BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 0,
				      sapi := PCU_IF_SAPI_PCH)) -> value pcu_msg;

	/* First 3 bytes contain IMSI suffix to calculate paging group: */
	imsi_suff_octstr := substr(pcu_msg.u.data_req.data, 0, 3);
	pag_group_rx := str2int(oct2char(imsi_suff_octstr[0])) * 100 +
			str2int(oct2char(imsi_suff_octstr[1])) * 10 +
			str2int(oct2char(imsi_suff_octstr[2]));

	/* Make sure we've got RR Paging Request Type 1 for a given MI */
	macblock := substr(pcu_msg.u.data_req.data, 3, pcu_msg.u.data_req.len - 3);
	rr_pag_req1 := dec_GsmRrMessage(macblock);
	if (not match(rr_pag_req1, tr_PAG_REQ1(tr_MI_LV(mi1)))) {
		setverdict(fail, "Failed to match Paging Request Type 1: ", rr_pag_req1);
		f_shutdown(__BFILE__, __LINE__);
	}

	/* Make sure that received paging froup matches the expected one */
	if (not match(pag_group_rx, pag_group)) {
		setverdict(fail, "Paging group", pag_group_rx, " does not match expected ", pag_group);
		f_shutdown(__BFILE__, __LINE__);
	}

	f_pcuif_tx_data_cnf(pcu_msg);
	return rr_pag_req1;
}

private function f_tx_rlcmac_ul_block(template (value) RlcmacUlBlock ul_data, int16_t lqual_cb := 0, uint32_t fn := 0)
runs on RAW_PCU_Test_CT {
	var octetstring data;
	/* Encode the payload of DATA.ind */
	data := enc_RlcmacUlBlock(valueof(ul_data));
	data := f_pad_oct(data, 23, '00'O); /* CS-1 */

	/* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
	f_pcuif_tx_data_ind(data, lqual_cb, fn);
}

private function f_tx_rlcmac_ul_n_blocks(PacketUlAssign ul_tbf_ass, integer num_blocks := 1)
runs on RAW_PCU_Test_CT {
	var template (value) RlcmacUlBlock ul_data := t_RLCMAC_UL_DATA(
		tfi := ul_tbf_ass.dynamic.tfi_assignment,
		cv := num_blocks - 1, /* num UL blocks to be sent (to be overridden in loop) */
		bsn := 0, /* TODO: what should be here? */
		blocks := { /* To be generated in loop */ });

	/* HACK: patch missing TLLI; otherwise OsmoPCU rejects DATA.req */
	ul_data.data.tlli := '00000001'O;

	for (var integer i := 0; i < num_blocks; i := i + 1) {
		/* Prepare a new UL block (CV, random payload) */
		ul_data.data.mac_hdr.countdown := (num_blocks - i - 1);
		ul_data.data.blocks := { valueof(t_RLCMAC_LLCBLOCK(f_rnd_octstring(10))) };
		f_tx_rlcmac_ul_block(ul_data);
	}
}

private function f_rx_rlcmac_dl_block(out RlcmacDlBlock dl_block, out uint32_t dl_fn, template (present) CodingScheme exp_cs_mcs := ?)
runs on RAW_PCU_Test_CT {
	var PCUIF_Message pcu_msg;
	f_pcuif_rx_data_req(pcu_msg);
	dl_block := dec_RlcmacDlBlock(pcu_msg.u.data_req.data);
	dl_fn := pcu_msg.u.data_req.fn;

	var integer len := lengthof(pcu_msg.u.data_req.data);
	var CodingScheme cs_mcs := f_rlcmac_block_len2cs_mcs(len)
	if (not match(f_rlcmac_block_len2cs_mcs(len), exp_cs_mcs)) {
		setverdict(fail, "Failed to match Coding Scheme exp ", exp_cs_mcs, " vs ", cs_mcs, " (", len, ")");
		f_shutdown(__BFILE__, __LINE__);
	}
}

private function f_rx_rlcmac_dl_block_exp_ack_nack(out RlcmacDlBlock dl_block, out uint32_t poll_fn)
runs on RAW_PCU_Test_CT {
	var uint32_t dl_fn;

	f_rx_rlcmac_dl_block(dl_block, dl_fn);
	if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK(ul_tfi := ?, tlli := ?))) {
		setverdict(fail, "Failed to match Packet Uplink ACK / NACK");
		f_shutdown(__BFILE__, __LINE__);
	}

	poll_fn := f_rrbp_ack_fn(dl_fn, dl_block.ctrl.mac_hdr.rrbp);
}

private function f_rx_rlcmac_dl_block_exp_dummy(out RlcmacDlBlock dl_block)
runs on RAW_PCU_Test_CT {
	var uint32_t dl_fn;

	f_rx_rlcmac_dl_block(dl_block, dl_fn);
	if (not match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
		setverdict(fail, "Failed to match Packet DUMMY DL");
		f_shutdown(__BFILE__, __LINE__);
	}
}

private function f_rx_rlcmac_dl_block_exp_pkt_ass(out RlcmacDlBlock dl_block, out uint32_t poll_fn)
runs on RAW_PCU_Test_CT {
	var uint32_t dl_fn;

	f_rx_rlcmac_dl_block(dl_block, dl_fn);
	if (not match(dl_block, tr_RLCMAC_DL_PACKET_ASS())) {
		setverdict(fail, "Failed to match Packet Downlink Assignment");
		f_shutdown(__BFILE__, __LINE__);
	}

	poll_fn := f_rrbp_ack_fn(dl_fn, dl_block.ctrl.mac_hdr.rrbp);
}

private function f_rx_rlcmac_dl_block_exp_pkt_ul_ass(out RlcmacDlBlock dl_block, out uint32_t poll_fn)
runs on RAW_PCU_Test_CT {
        var uint32_t dl_fn;

        f_rx_rlcmac_dl_block(dl_block, dl_fn);
        if (not match(dl_block, tr_RLCMAC_UL_PACKET_ASS())) {
                setverdict(fail, "Failed to match Packet Uplink Assignment");
		f_shutdown(__BFILE__, __LINE__);
        }

	poll_fn := f_rrbp_ack_fn(dl_fn, dl_block.ctrl.mac_hdr.rrbp);
}


private function f_rx_rlcmac_dl_block_exp_pkt_pag_req(out RlcmacDlBlock dl_block)
runs on RAW_PCU_Test_CT {
	var uint32_t dl_fn;

	f_rx_rlcmac_dl_block(dl_block, dl_fn);
	if (not match(dl_block, tr_RLCMAC_PACKET_PAG_REQ())) {
		setverdict(fail, "Failed to match Packet Paging Request: ", dl_block, " vs ", tr_RLCMAC_PACKET_PAG_REQ());
		f_shutdown(__BFILE__, __LINE__);
	}
}

/* This function does what could probably be done with templates */
private function f_rlcmac_dl_block_verify_data_gprs(in RlcmacDlDataBlock data_block,
						    template (present) octetstring data := ?,
						    template (present) uint7_t exp_bsn := ?,
						    template (present) CodingScheme exp_cs := ?)
runs on RAW_PCU_Test_CT {
	if (not match(data_block.mac_hdr.hdr_ext.bsn, exp_bsn)) {
		setverdict(fail, "DL block BSN doesn't match: ",
			   data_block.mac_hdr.hdr_ext.bsn, " vs exp ", exp_bsn);
	}

	if (lengthof(data_block.blocks) < 1) {
		setverdict(fail, "DL block has no LLC payload: ", data_block);
		f_shutdown(__BFILE__, __LINE__);
	}

	if (not match(data_block.blocks[0].payload, data)) {
		setverdict(fail, "Failed to match content of LLC payload in DL Block: ",
			   data_block.blocks[0].payload, " vs ", data);
		f_shutdown(__BFILE__, __LINE__);
	}

	/* Check next data blocks contain dummy frames */
	if (lengthof(data_block.blocks) > 1 and substr(data_block.blocks[1].payload, 0, 3) != '43C001'O) {
		setverdict(fail, "Second data payload is not a dummy frame: ",
			   data_block.blocks[1].payload);
		f_shutdown(__BFILE__, __LINE__);
	}

	/* TODO: check exp_cs */
}

/* This function does what could probably be done with templates */
private function f_rlcmac_dl_block_verify_data_egprs(in RlcmacDlEgprsDataBlock data_block,
						     template (present) octetstring data := ?,
						     template (present) uint14_t exp_bsn := ?,
						     template (present) CodingScheme exp_cs := ?)
runs on RAW_PCU_Test_CT {
	if (not match(data_block.mac_hdr.bsn1, exp_bsn)) {
		setverdict(fail, "DL block BSN doesn't match: ",
			   data_block.mac_hdr.bsn1, " vs exp ", exp_bsn);
	}

	if (lengthof(data_block.blocks) < 1) {
		setverdict(fail, "DL block has no LLC payload: ", data_block);
		f_shutdown(__BFILE__, __LINE__);
	}

	if (not match(data_block.blocks[0].payload, data)) {
		setverdict(fail, "Failed to match content of LLC payload in DL Block: ",
			   data_block.blocks[0].payload, " vs ", data);
		f_shutdown(__BFILE__, __LINE__);
	}

	/* Check next data blocks contain dummy frames */
	if (lengthof(data_block.blocks) > 1 and substr(data_block.blocks[1].payload, 0, 3) != '43C001'O) {
		setverdict(fail, "Second data payload is not a dummy frame: ",
			   data_block.blocks[1].payload);
		f_shutdown(__BFILE__, __LINE__);
	}

	/* TODO: Check exp_cs. In the case of EGPRS, first check mac_hdr.header_type and then decode CPS = exp_cs based on mac_hdr.header_type.
		See wireshark's egprs_Header_type1_coding_puncturing_scheme_to_mcs. */
}

/* High level (task specific) helper for receiving and matching GPRS/EGPRS data blocks */
private function f_rx_rlcmac_dl_block_exp_data(out RlcmacDlBlock dl_block, out uint32_t dl_fn,
					       template (present) octetstring data := ?,
					       template (present) uint7_t exp_bsn := ?,
					       template (present) CodingScheme exp_cs := ?)
runs on RAW_PCU_Test_CT {
	/* FIXME: ideally we should use an alt statement with timeout here, rather than
	 * having +100500 layers of abstraction. This would facilitate developing the
	 * multi-TBF/-TRX/-BTS tests, where you cannot expect that the first received
	 * block is exactly what you need. */
	f_rx_rlcmac_dl_block(dl_block, dl_fn);

	/* Make sure it's either GPRS or EGPRS data block */
	if (not match(dl_block, tr_RLCMAC_DATA)) {
		setverdict(fail, "Failed to match DL DATA: ", dl_block, " vs ", tr_RLCMAC_DATA);
		f_shutdown(__BFILE__, __LINE__);
	}

	if (ischosen(dl_block.data_egprs)) {
		f_rlcmac_dl_block_verify_data_egprs(dl_block.data_egprs, data, exp_bsn, exp_cs);
	} else if (ischosen(dl_block.data)) {
		f_rlcmac_dl_block_verify_data_gprs(dl_block.data, data, exp_bsn, exp_cs);
	} else {
		/* Should not happen, but the caller may theoretically give us a template for CTRL */
		setverdict(fail, "DL block is neither GPRS nor EGPRS data block: ", dl_block);
		f_shutdown(__BFILE__, __LINE__);
	}
}

private function f_dl_block_ack_fn(in RlcmacDlBlock dl_block, uint32_t dl_fn)
runs on RAW_PCU_Test_CT return uint32_t {
	var boolean rrbp_valid;
	var MacRrbp rrbp;

	/* The argument must be either a GPRS or EGPRS data block */
	if (ischosen(dl_block.data_egprs)) {
		rrbp_valid := true; /* always valid */
		rrbp := dl_block.data_egprs.mac_hdr.rrbp;
	} else if (ischosen(dl_block.data)) {
		rrbp_valid := dl_block.data.mac_hdr.mac_hdr.rrbp_valid;
		rrbp := dl_block.data.mac_hdr.mac_hdr.rrbp;
	} else {
		/* Should not happen, but the caller may theoretically give us a CTRL block */
		setverdict(fail, "DL block is neither GPRS nor EGPRS data block: ", dl_block);
		f_shutdown(__BFILE__, __LINE__);
	}

	/* Make sure that the given block really needs to be ACKnowledged */
	if (not rrbp_valid) {
		setverdict(fail, "DL block shall not be ACKnowledged, field RRBP is not valid");
		f_shutdown(__BFILE__, __LINE__);
	}

	return f_rrbp_ack_fn(dl_fn, rrbp);
}

testcase TC_pcuif_suspend() runs on RAW_PCU_Test_CT {
	var octetstring ra_id := enc_RoutingAreaIdentification(mp_gb_cfg.cell_id.ra_id);
	var GprsTlli tlli := 'FFFFFFFF'O;
	timer T;

	/* Initialize NS/BSSGP side */
	f_init_bssgp();

	/* Initialize the PCU interface abstraction */
	f_init_raw(testcasename());

	/* Establish BSSGP connection to the PCU */
	f_bssgp_establish();

	BTS.send(ts_PCUIF_SUSP_REQ(0, tlli, ra_id, 0));

	T.start(2.0);
	alt {
	[] BSSGP_SIG[0].receive(tr_BSSGP_SUSPEND(tlli, mp_gb_cfg.cell_id.ra_id)) {
		setverdict(pass);
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for BSSGP SUSPEND");
		}
	}

	f_shutdown(__BFILE__, __LINE__, final := true);
}

/* Test of correct Timing Advance at the time of TBF establishment
 * (derived from timing offset of the Access Burst). */
testcase TC_ta_rach_imm_ass() runs on RAW_PCU_Test_CT {
	var GsmRrMessage rr_msg;
	var boolean ok;

	/* Initialize the PCU interface abstraction */
	f_init_raw(testcasename());

	/* We cannot send too many TBF requests in a short time because
	 * at some point the PCU will fail to allocate a new TBF. */
	for (var TimingAdvance ta := 0; ta < 64; ta := ta + 16) {
		/* Establish an Uplink TBF (send RACH.ind with current TA) */
		ok := f_establish_tbf(rr_msg, bts_nr := 0, ta := ta);
		if (not ok) {
			setverdict(fail, "Failed to establish an Uplink TBF");
			break;
		}

		/* Make sure Timing Advance IE matches out expectations */
		if (rr_msg.payload.imm_ass.timing_advance != ta) {
			setverdict(fail, "Timing Advance mismatch: ",
				   rr_msg.payload.imm_ass.timing_advance,
				   " vs expected ", ta);
			break;
		}
	}

	f_shutdown(__BFILE__, __LINE__, final := true);
}

/* Verify Timing Advance value(s) indicated during the packet Downlink assignment
 * procedure as per 3GPP TS 44.018, section 3.5.3. There seems to be a bug in the
 * IUT that causes it to send an unreasonable Timing Advance value > 0 despite
 * no active TBF exists at the moment of establishment (idle mode). */
testcase TC_ta_idle_dl_tbf_ass() runs on RAW_PCU_Test_CT {
	var OCT4 tlli := f_rnd_octstring(4);
	var GsmRrMessage rr_imm_ass;

	/* Initialize NS/BSSGP side */
	f_init_bssgp();

	/* Initialize the PCU interface abstraction */
	f_init_raw(testcasename());

	/* Establish BSSGP connection to the PCU */
	f_bssgp_establish();
	f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);

	/* SGSN sends some DL data, PCU will initiate Packet Downlink
	 * Assignment on CCCH (PCH). We don't care about the payload. */
	BSSGP[0].send(ts_BSSGP_DL_UD(tlli, f_rnd_octstring(10)));
	f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass); // TODO: match by TLLI!

	/* Make sure that Timing Advance is 0 (the actual value is not known yet).
	 * As per 3GPP S 44.018, section 3.5.3.1.2, the network *shall* initiate
	 * the procedures defined in 3GPP TS 44.060 or use the polling mechanism. */
	if (not match(rr_imm_ass, tr_IMM_TBF_ASS(ta := 0))) {
		setverdict(fail, "Timing Advance value doesn't match");
	}

	f_shutdown(__BFILE__, __LINE__, final := true);
}

/* Verify that the PCU generates valid PTCCH/D messages
 * while neither Uplink nor Downlink TBF is established. */
testcase TC_ta_ptcch_idle() runs on RAW_PCU_Test_CT {
	var PTCCHDownlinkMsg ptcch_msg;
	var PCUIF_Message pcu_msg;
	timer T;

	/* Initialize the PCU interface abstraction */
	f_init_raw(testcasename());

	/* Sent an RTS.req for PTCCH/D */
	BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
				  sapi := PCU_IF_SAPI_PTCCH, fn := 0,
				  arfcn := 871, block_nr := 0));
	T.start(5.0);
	alt {
	[] BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
					 sapi := PCU_IF_SAPI_PTCCH)) -> value pcu_msg {
		log("Rx DATA.req message: ", pcu_msg);
		setverdict(pass);
		}
	[] BTS.receive(PCUIF_Message:?) { repeat; }
	[] T.timeout {
		setverdict(fail, "Timeout waiting for a PTCCH/D block");
		f_shutdown(__BFILE__, __LINE__);
		}
	}

	ptcch_msg := dec_PTCCHDownlinkMsg(pcu_msg.u.data_req.data);
	log("Decoded PTCCH/D message: ", ptcch_msg);

	/* Make sure the message is encoded correctly
	 * TODO: do we expect all TA values to be equal '1111111'B? */
	if (not match(ptcch_msg, tr_PTCCHDownlinkMsg)) {
		setverdict(fail, "Malformed PTCCH/D message");
	}

	f_shutdown(__BFILE__, __LINE__, final := true);
}

/* Test of correct Timing Advance during an active Uplink TBF.
 *
 * Unlike the circuit-switched domain, Uplink transmissions on PDCH time-slots
 * are not continuous and there can be long time gaps between them. This happens
 * due to a bursty nature of packet data. The actual Timing Advance of a MS may
 * significantly change between such rare Uplink transmissions, so GPRS introduces
 * additional mechanisms to control Timing Advance, and thus reduce interference
 * between neighboring TDMA time-slots.
 *
 * At the moment of Uplink TBF establishment, initial Timing Advance is measured
 * from ToA (Timing of Arrival) of an Access Burst. This is covered by another
 * test case - TC_ta_rach_imm_ass. In response to that Access Burst the network
 * sends Immediate Assignment on AGCH, which _may_ contain Timing Advance Index
 * among with the initial Timing Advance value. And here PTCCH comes to play.
 *
 * PTCCH is a unidirectional channel on which the network can instruct a sub-set
 * of 16 MS (whether TBFs are active or not) to adjust their Timing Advance
 * continuously. To ensure continuous measurements of the signal propagation
 * delay, the MSs shall transmit Access Bursts on Uplink (PTCCH/U) on sub-slots
 * defined by an assigned Timing Advance Index (see 3GPP TS 45.002).
 *
 * The purpose of this test case is to verify the assignment of Timing Advance
 * Index, and the process of Timing Advance notification on PTCCH/D. The MTC
 * first establishes several Uplink TBFs, but does not transmit any Uplink
 * blocks on them. During 4 TDMA multi-frame periods the MTC is sending RACH
 * indications to the PCU, checking the correctness of two received PTCCH/D
 * messages (period of PTCCH/D is two multi-frames).
 */

/* List of ToA values for Access Bursts to be sent on PTCCH/U,
 * each ToA (Timing of Arrival) value is in units of 1/4 of
 * a symbol (i.e. 1 symbol is 4 QTA units). */
type record length(16) of int16_t PTCCH_TAI_ToA_MAP;
const PTCCH_TAI_ToA_MAP ptcch_toa_map_def := {
	0, 0, 0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0,
	0, 0, 0, 0
};

private altstep as_ta_ptcch(uint8_t bts_nr := 0, uint8_t trx_nr := 0, uint8_t ts_nr := 7,
			    in PTCCH_TAI_ToA_MAP toa_map := ptcch_toa_map_def)
runs on RAW_PCU_Test_CT {
	var RAW_PCU_Event event;
	var integer ss;

	/* Send Access Bursts on PTCCH/U for every TA Index */
	[] BTS.receive(tr_RAW_PCU_EV(TDMA_EV_PTCCH_UL_BURST)) -> value event {
		ss := f_tdma_ptcch_fn2ss(event.data.tdma_fn);
		if (ss < 0) { /* Shall not happen */
			f_shutdown(__BFILE__, __LINE__);
		}

		log("Sending an Access Burst on PTCCH/U",
		    ", sub-slot=", ss, " (TAI)",
		    ", fn=", event.data.tdma_fn,
		    ", ToA=", toa_map[ss], " (QTA)");
		/* TODO: do we care about RA and burst format? */
		BTS.send(ts_PCUIF_RACH_IND(bts_nr, trx_nr, ts_nr,
					   ra := oct2int('3A'O),
					   is_11bit := 0,
					   burst_type := BURST_TYPE_0,
					   fn := event.data.tdma_fn,
					   arfcn := 871,
					   qta := toa_map[ss],
					   sapi := PCU_IF_SAPI_PTCCH));
		repeat;
		}
}

private function f_TC_ta_ptcch_ul_multi_tbf(in PTCCH_TAI_ToA_MAP ptcch_toa_map,
					    template PTCCHDownlinkMsg t_ta_msg)
runs on RAW_PCU_Test_CT {
	var PTCCHDownlinkMsg ta_msg;
	var PCUIF_Message pcu_msg;
	timer T;

	/* First, send an RTS.req for the upcoming PTCCH/D block */
	BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
				  sapi := PCU_IF_SAPI_PTCCH, fn := 0,
				  arfcn := 871, block_nr := 0));
	T.start(2.0);
	alt {
	/* Keep sending of Access Bursts during two multi-frames (period of PTCCH/D)
	 * with increasing ToA (Timing of Arrival) values: 0, 7, 14, 28, 35... */
	[] as_ta_ptcch(bts_nr := 0, trx_nr := 0, ts_nr := 7, toa_map := ptcch_toa_map);
	/* In the end of 2nd multi-frame we should receive a PTCCH/D block */
	[] BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
					 sapi := PCU_IF_SAPI_PTCCH)) -> value pcu_msg {
		ta_msg := dec_PTCCHDownlinkMsg(pcu_msg.u.data_req.data);
		log("Rx PTCCH/D message: ", ta_msg);

		/* Make sure Timing Advance values match our expectations */
		if (not match(ta_msg, t_ta_msg)) {
			setverdict(fail, "PTCCH/D message does not match: ", t_ta_msg);
		}
		}
	[] BTS.receive { repeat; }
	[] T.timeout {
		setverdict(fail, "Timeout waiting for a PTCCH/D block");
		}
	}
}

testcase TC_ta_ptcch_ul_multi_tbf() runs on RAW_PCU_Test_CT {
	var template PacketUlAssign t_ul_tbf_ass;
	var PacketUlAssign ul_tbf_ass[7];
	var GsmRrMessage rr_msg[7];
	var boolean ok;

	/* Initialize the PCU interface abstraction */
	f_init_raw(testcasename());

	/* Enable forwarding of PTCCH/U TDMA events to us */
	BTS.send(ts_RAW_PCU_CMD(TDMA_CMD_ENABLE_PTCCH_UL_FWD));

	/* Establish 7 Uplink TBFs (USF flag is 3 bits long, '111'B is reserved) */
	for (var integer i := 0; i < 7; i := i + 1) {
		ok := f_establish_tbf(rr_msg[i], ta := 0);
		if (not ok) {
			setverdict(fail, "Failed to establish an Uplink TBF #", i);
			break;
		}

		/* Make sure we received an UL TBF Assignment */
		if (match(rr_msg[i], tr_IMM_TBF_ASS(dl := false, rest := tr_IaRestOctets_ULAss(?)))) {
			ul_tbf_ass[i] := rr_msg[i].payload.imm_ass.rest_octets.hh.pa.uldl.ass.ul;
			log("Rx Uplink TBF assignment for #", i, ": ", ul_tbf_ass[i]);
		} else {
			setverdict(fail, "Failed to match UL TBF Assignment for #", i);
			break;
		}

		/* We expect incremental TFI/USF assignment (dynamic allocation) */
		t_ul_tbf_ass := tr_PacketUlDynAssign(tfi := i, usf := i);
		if (not match(ul_tbf_ass[i], t_ul_tbf_ass)) {
			setverdict(fail, "Failed to match Packet Uplink Assignment for #", i);
			break;
		}

		/* We also expect Timing Advance Index to be a part of the assignment */
		if (ul_tbf_ass[i].dynamic.ta_index != i) {
			setverdict(fail, "Failed to match Timing Advance Index for #", i);
			/* Keep going, the current OsmoPCU does not assign TA Index */
		}
	}

	/* Prepare a list of ToA values for Access Bursts to be sent on PTCCH/U */
	var PTCCH_TAI_ToA_MAP toa_map := ptcch_toa_map_def;
	for (var integer i := 0; i < 7; i := i + 1) {
		/* ToA in units of 1/4 of a symbol */
		toa_map[i] := (i + 1) * 7 * 4;
	}

	/* Now we have all 7 TBFs established in one-phase access mode,
	 * however we will not be sending any data on them. Instead, we
	 * will be sending RACH.ind on PTCCH/U during 4 multi-frame
	 * periods (TAI 0..8), and then will check two PTCCH/D blocks.
	 *
	 * Why not 4 TBFs at once? Because Uplink is delayed by 3 TDMA
	 * time-slots, so at the moment of scheduling a PTCCH/D block
	 * the PCU has odd number of PTCCH/U Access Bursts received. */
	f_TC_ta_ptcch_ul_multi_tbf(toa_map, tr_PTCCHDownlinkMsg(
		tai0_ta :=  7, tai1_ta := 14, tai2_ta := 21,
		/* Other values are not known (yet) */
		tai3_ta := ?));
	f_TC_ta_ptcch_ul_multi_tbf(toa_map, tr_PTCCHDownlinkMsg(
		tai0_ta :=  7, tai1_ta := 14, tai2_ta := 21,
		tai3_ta := 28, tai4_ta := 35, tai5_ta := 42,
		/* Other values are out of our interest */
		tai6_ta := ?));

	f_shutdown(__BFILE__, __LINE__, final := true);
}

/* Default link quality adaptation (Coding Scheme) ranges (inclusive).
 * OsmoPCU (VTY): cs link-quality-ranges cs1 6 cs2 5 8 cs3 7 13 cs4 12
 *
 * NOTE: the ranges are intentionally overlapping because OsmoPCU
 * does not change CS/MCS on the range borders (5-6, 7-8, 12-13). */
private template integer CS1_lqual_dB_range := (-infinity .. 6);
private template integer CS2_lqual_dB_range := (5 .. 8);
private template integer CS3_lqual_dB_range := (7 .. 13);
private template integer CS4_lqual_dB_range := (12 .. infinity);

testcase TC_cs_lqual_ul_tbf() runs on RAW_PCU_Test_CT {
	var GsmRrMessage rr_imm_ass;
	var PacketUlAssign ul_tbf_ass;
	var RlcmacDlBlock dl_block;
	var PCUIF_Message pcu_msg;
	var octetstring data;
	var boolean ok;
	var uint32_t unused_fn;

	/* Initialize the PCU interface abstraction */
	f_init_raw(testcasename());

	f_pcuvty_set_allowed_cs_mcs();
	f_pcuvty_set_link_quality_ranges();

	/* Establish an Uplink TBF */
	ok := f_establish_tbf(rr_imm_ass);
	if (not ok) {
		setverdict(fail, "Failed to establish TBF");
		f_shutdown(__BFILE__, __LINE__);
	}

	/* Make sure we've got an Uplink TBF assignment */
	f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);

	var template (value) RlcmacUlBlock ul_data := t_RLCMAC_UL_DATA(
		tfi := ul_tbf_ass.dynamic.tfi_assignment,
		cv := 15, /* 16 UL blocks to be sent (to be overridden in loop) */
		bsn := 0, /* TODO: what should be here? */
		blocks := { /* To be generated in loop */ });

	/* HACK: patch missing TLLI; otherwise OsmoPCU rejects DATA.req */
	ul_data.data.tlli := '00000001'O;

	/* The actual / old link quality values. We need to keep track of the old
	 * (basically previous) link quality value, because OsmoPCU actually
	 * changes the coding scheme if not only the actual, but also the old
	 * value leaves the current link quality range (window). */
	var integer lqual := 0;
	var integer lqual_old;

	/* 16 UL blocks (0 .. 15 dB, step = 1 dB) */
	for (var integer i := 0; i < 16; i := i + 1) {
		/* Prepare a new UL block (CV, random payload) */
		ul_data.data.mac_hdr.countdown := (15 - i);
		ul_data.data.blocks := { valueof(t_RLCMAC_LLCBLOCK(f_rnd_octstring(10))) };

		/* Update the old / actual link quality */
		lqual_old := lqual;
		lqual := i;

		/* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
		log("Sending DATA.ind with link quality (dB): ", lqual);
		f_tx_rlcmac_ul_block(ul_data, lqual * 10);

		/* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
		f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);

		log("Rx Packet Uplink ACK / NACK with Channel Coding Command: ",
		    dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd);

		/* Match the received Channel Coding Command. Since we are increasing
		 * the link quality value on each iteration and not decreasing, there
		 * is no need to check the both old and current link quality values. */
		var template ChCodingCommand ch_coding;
		select (lqual_old) {
		case (CS1_lqual_dB_range) { ch_coding := CH_CODING_CS1; }
		case (CS2_lqual_dB_range) { ch_coding := CH_CODING_CS2; }
		case (CS3_lqual_dB_range) { ch_coding := CH_CODING_CS3; }
		case (CS4_lqual_dB_range) { ch_coding := CH_CODING_CS4; }
		}

		if (not match(dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd, ch_coding)) {
			setverdict(fail, "Channel Coding does not match our expectations: ", ch_coding);
		}
	}

	f_shutdown(__BFILE__, __LINE__, final := true);
}

/* Test the max UL CS set by VTY works fine */
testcase TC_cs_initial_ul() runs on RAW_PCU_Test_CT {
	var GsmRrMessage rr_imm_ass;
	var PacketUlAssign ul_tbf_ass;
	var RlcmacDlBlock dl_block;
	var boolean ok;
	var integer lqual_cb;
	var ChCodingCommand last_ch_coding;
	var uint32_t unused_fn;

	/* Initialize the PCU interface abstraction */
	f_init_raw(testcasename());

	/* Set initial UL CS to 3 */
	g_cs_initial_ul := 3;
	f_pcuvty_set_allowed_cs_mcs();
	f_pcuvty_set_link_quality_ranges();

	/* Take lqual (dB->cB) so that we stay in that CS */
	lqual_cb := g_cs_lqual_ranges[2].low * 10;

	/* Establish an Uplink TBF */
	ok := f_establish_tbf(rr_imm_ass);
	if (not ok) {
		setverdict(fail, "Failed to establish TBF");
		f_shutdown(__BFILE__, __LINE__);
	}

	/* Make sure we've got an Uplink TBF assignment */
	f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);

	var template (value) RlcmacUlBlock ul_data := t_RLCMAC_UL_DATA(
		tfi := ul_tbf_ass.dynamic.tfi_assignment,
		cv := 3, /* 8 UL blocks to be sent (to be overridden in loop) */
		bsn := 0, /* TODO: what should be here? */
		blocks := { /* To be generated in loop */ });

	/* HACK: patch missing TLLI; otherwise OsmoPCU rejects DATA.req */
	ul_data.data.tlli := '00000001'O;

	/* 3 UL blocks, check we are in same initial CS: */
	for (var integer i := 0; i < 3; i := i + 1) {
		/* Prepare a new UL block (CV, random payload) */
		ul_data.data.mac_hdr.countdown := (7 - i);
		ul_data.data.blocks := { valueof(t_RLCMAC_LLCBLOCK(f_rnd_octstring(10))) };

		/* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
		f_tx_rlcmac_ul_block(ul_data, lqual_cb);

		/* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
		f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
		last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
	}

	if (last_ch_coding != CH_CODING_CS3) {
		setverdict(fail, "Channel Coding does not match our expectations (CS-3): ", last_ch_coding);
	}

	/* Remaining UL blocks are used to make sure regardless of initial
	/* lqual, we can go lower at any time */

	/* 5 UL blocks, check we are in same initial CS: */
	for (var integer i := 3; i < 8; i := i + 1) {
		/* Prepare a new UL block (CV, random payload) */
		ul_data.data.mac_hdr.countdown := (7 - i);
		ul_data.data.blocks := { valueof(t_RLCMAC_LLCBLOCK(f_rnd_octstring(10))) };

		/* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
		f_tx_rlcmac_ul_block(ul_data, 0); /* 0 dB, make sure we downgrade CS */

		/* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
		f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);

		last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
	}

	if (last_ch_coding != CH_CODING_CS1) {
		setverdict(fail, "Channel Coding does not match our expectations (CS-1): ", last_ch_coding);
	}

	f_shutdown(__BFILE__, __LINE__, final := true);
}

/* Test the max UL CS set by VTY works fine */
testcase TC_cs_max_ul() runs on RAW_PCU_Test_CT {
	var GsmRrMessage rr_imm_ass;
	var PacketUlAssign ul_tbf_ass;
	var RlcmacDlBlock dl_block;
	var boolean ok;
	var ChCodingCommand last_ch_coding;
	var uint32_t unused_fn;

	/* Initialize the PCU interface abstraction */
	f_init_raw(testcasename());

	/* Set maximum allowed UL CS to 3 */
	g_cs_max_ul := 3;
	f_pcuvty_set_allowed_cs_mcs();
	f_pcuvty_set_link_quality_ranges();

	/* Establish an Uplink TBF */
	ok := f_establish_tbf(rr_imm_ass);
	if (not ok) {
		setverdict(fail, "Failed to establish TBF");
		f_shutdown(__BFILE__, __LINE__);
	}

	/* Make sure we've got an Uplink TBF assignment */
	f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);

	var template (value) RlcmacUlBlock ul_data := t_RLCMAC_UL_DATA(
		tfi := ul_tbf_ass.dynamic.tfi_assignment,
		cv := 15, /* 16 UL blocks to be sent (to be overridden in loop) */
		bsn := 0, /* TODO: what should be here? */
		blocks := { /* To be generated in loop */ });

	/* HACK: patch missing TLLI; otherwise OsmoPCU rejects DATA.req */
	ul_data.data.tlli := '00000001'O;

	/* 16 UL blocks */
	for (var integer i := 0; i < 16; i := i + 1) {
		/* Prepare a new UL block (CV, random payload) */
		ul_data.data.mac_hdr.countdown := (15 - i);
		ul_data.data.blocks := { valueof(t_RLCMAC_LLCBLOCK(f_rnd_octstring(10))) };

		/* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
		f_tx_rlcmac_ul_block(ul_data, 40*10); /* 40 dB */

		/* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
		f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);

		last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
	}

	if (last_ch_coding != CH_CODING_CS3) {
		setverdict(fail, "Channel Coding does not match our expectations (CS-3): ", last_ch_coding);
	}

	f_shutdown(__BFILE__, __LINE__, final := true);
}

/* Verify PCU drops TBF after some time of inactivity. */
testcase TC_t3169() runs on RAW_PCU_Test_CT {
	var PCUIF_info_ind info_ind;
	var GsmRrMessage rr_imm_ass;
	var PacketUlAssign ul_tbf_ass;
	var RlcmacDlBlock dl_block;
	var PCUIF_Message pcu_msg;
	var octetstring data;
	var boolean ok;
	var uint32_t unused_fn;
	var OCT4 tlli := '00000001'O;

	/* Initialize NS/BSSGP side */
	f_init_bssgp();

	info_ind := valueof(ts_PCUIF_INFO_default);
	/* Set timer to 1 sec (default 5) to speedup test: */
	info_ind.t3169 := 1;

	/* Initialize the PCU interface abstraction */
	f_init_raw(testcasename(), info_ind);

	/* Establish BSSGP connection to the PCU */
	f_bssgp_establish();
	f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);

	/* Establish an Uplink TBF */
	ok := f_establish_tbf(rr_imm_ass);
	if (not ok) {
		setverdict(fail, "Failed to establish TBF");
		f_shutdown(__BFILE__, __LINE__);
	}

	/* Make sure we've got an Uplink TBF assignment */
	f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);

	/* Send one UL block and make sure it is ACKED fine */
	f_tx_rlcmac_ul_n_blocks(ul_tbf_ass, 1);
	f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
	/* UL block should be received in SGSN */
	BSSGP[0].receive(tr_BSSGP_UL_UD(tlli, mp_gb_cfg.cell_id));

	/* Wait until T3169 fires (plus 1 extra sec to make sure) */
	f_sleep(int2float(info_ind.t3169) + 1.0);

	/* Send an UL block once again, the TBF should be gone by now so no ACK */
	f_tx_rlcmac_ul_n_blocks(ul_tbf_ass, 1);
	f_rx_rlcmac_dl_block_exp_dummy(dl_block);

	f_shutdown(__BFILE__, __LINE__, final := true);
}

/* Verify that a Downlink TBF can be assigned using PACCH shortly after the
 * release of prev DL TBF due to MS staying in PDCH for a while (T3192, in PCU
 * T3193) after DL TBF release */
testcase TC_t3193() runs on RAW_PCU_Test_CT {
	var GsmRrMessage rr_imm_ass;
	var PacketDlAssign dl_tbf_ass;
	var RlcmacDlBlock dl_block;
	var octetstring data := f_rnd_octstring(10);
	var boolean ok;
	var uint32_t sched_fn;
	var uint32_t dl_fn;
	var OCT4 tlli := '00000001'O;
	var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);

	/* Initialize NS/BSSGP side */
	f_init_bssgp();

	/* Initialize the PCU interface abstraction */
	f_init_raw(testcasename());

	/* Establish BSSGP connection to the PCU */
	f_bssgp_establish();
	f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);

	/* SGSN sends some DL data, PCU will page on CCCH (PCH) */
	BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));
	f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass);

	/* Make sure we've got a Downlink TBF assignment */
	f_imm_ass_verify_dl_tbf_ass(rr_imm_ass, dl_tbf_ass);

	/* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
	f_sleep(X2002);
	f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);

	/* ACK the DL block */
	f_acknackdesc_ack_block(ack_nack_desc, dl_block, '1'B);
	f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(f_rlcmac_dl_block_get_tfi(dl_block), ack_nack_desc),
			     0, f_dl_block_ack_fn(dl_block, dl_fn));
	/* we are done with the DL-TBF here so far, let's clean up our local state: */
	ack_nack_desc := valueof(t_AckNackDescription_init)

	/* Now that final DL block is ACKED and TBF is released, T3193 in PCU
	   (T3192 in MS) was started and until it fires the MS will be abailable
	   on PDCH in case new data arrives from SGSN. Let's verify it: */
	BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));
	f_rx_rlcmac_dl_block_exp_pkt_ass(dl_block, sched_fn);
	f_tx_rlcmac_ul_block(ts_RLCMAC_CTRL_ACK(tlli), 0, sched_fn);

	/* Now that we confirmed the new assignment in the dl-tbf, lets receive the data and ack it */
	f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
	f_acknackdesc_ack_block(ack_nack_desc, dl_block, '1'B);
	f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(f_rlcmac_dl_block_get_tfi(dl_block), ack_nack_desc),
			     0, f_dl_block_ack_fn(dl_block, dl_fn));

	f_shutdown(__BFILE__, __LINE__, final := true);
}

/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
 * answered, so TBFs for uplink and later for downlink are created.
 */
private function f_TC_mo_ping_pong(template (omit) MSRadioAccessCapabilityV ms_racap := omit, template (present) CodingScheme exp_cs_mcs := ?) runs on RAW_PCU_Test_CT {
	var GsmRrMessage rr_imm_ass;
	var PacketUlAssign ul_tbf_ass;
	var PacketDlAssign dl_tbf_ass;
	var RlcmacDlBlock dl_block;
	var PCUIF_Message pcu_msg;
	var octetstring data := f_rnd_octstring(10);
	var boolean ok;
	var uint32_t sched_fn;
	var uint32_t dl_fn;
	var OCT4 tlli := '00000001'O;
	var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);

	/* Initialize NS/BSSGP side */
	f_init_bssgp();

	/* Initialize the PCU interface abstraction */
	f_init_raw(testcasename());

	/* Establish BSSGP connection to the PCU */
	f_bssgp_establish();
	f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);

	/* Establish an Uplink TBF */
	ok := f_establish_tbf(rr_imm_ass);
	if (not ok) {
		setverdict(fail, "Failed to establish TBF");
		f_shutdown(__BFILE__, __LINE__);
	}

	/* Make sure we've got an Uplink TBF assignment */
	f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);

	if (not istemplatekind(ms_racap, "omit")) {
		/* Send PACKET RESOURCE REQUEST to upgrade to EGPRS
		 * (see 3GPP TS 04.60 "7.1.3.1 Initiation of the Packet resource request procedure")
		 */
		f_tx_rlcmac_ul_block(ts_RLC_UL_CTRL_ACK(valueof(ts_RlcMacUlCtrl_PKT_RES_REQ(tlli, ms_racap))), 0);
		f_rx_rlcmac_dl_block_exp_pkt_ul_ass(dl_block, sched_fn);
		if (dl_block.ctrl.payload.u.ul_assignment.identity.tlli.tlli != tlli) {
			setverdict(fail, "Wrong TLLI ", dl_block.ctrl.payload.u.ul_assignment.identity.tlli, " received vs exp ", tlli);
			f_shutdown(__BFILE__, __LINE__);
		}
	}

	/* Send one UL block and make sure it is ACKED fine */
	f_tx_rlcmac_ul_n_blocks(ul_tbf_ass, 1);
	f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
	/* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
	f_tx_rlcmac_ul_block(ts_RLCMAC_CTRL_ACK(tlli), 0, sched_fn);

	/* UL block should be received in SGSN */
	BSSGP[0].receive(tr_BSSGP_UL_UD(tlli, mp_gb_cfg.cell_id));

	/* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
	BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));
	f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass);

	/* Make sure we've got a Downlink TBF assignment */
	f_imm_ass_verify_dl_tbf_ass(rr_imm_ass, dl_tbf_ass);

	/* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
	f_sleep(X2002);
	f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, exp_cs_mcs);

	/* ACK the DL block */
	f_acknackdesc_ack_block(ack_nack_desc, dl_block, '1'B);
	f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(f_rlcmac_dl_block_get_tfi(dl_block), ack_nack_desc),
			     0, f_dl_block_ack_fn(dl_block, dl_fn));

	f_shutdown(__BFILE__, __LINE__, final := true);
}

/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
 * answered, so TBFs for uplink and later for downlink are created.
 */
testcase TC_mo_ping_pong() runs on RAW_PCU_Test_CT {
	var CodingScheme exp_cs_mcs := CS_1;
	f_TC_mo_ping_pong(omit, exp_cs_mcs);
}


testcase TC_mo_ping_pong_with_ul_racap() runs on RAW_PCU_Test_CT {
	var MultislotCap_GPRS mscap_gprs := {
		gprsmultislotclass := '00011'B,
		gprsextendeddynalloccap := '0'B
	};
	var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
	var CodingScheme exp_cs_mcs := CS_2;

	f_TC_mo_ping_pong(ms_racap, exp_cs_mcs);
}

/* Test scenario where SGSN wants to send some data against MS and it is
 * answered by the MS on PDCH, so TBFs for downlink and later for uplink are created.
 */
private function f_TC_mt_ping_pong(template (omit) MSRadioAccessCapabilityV_BSSGP ms_racap := omit, template (present) CodingScheme exp_cs_mcs := ?) runs on RAW_PCU_Test_CT {
	var GsmRrMessage rr_imm_ass;
	var PacketUlAssign ul_tbf_ass;
	var PacketDlAssign dl_tbf_ass;
	var RlcmacDlBlock dl_block;
	var PCUIF_Message pcu_msg;
	var octetstring data := f_rnd_octstring(10);
	var boolean ok;
	var uint32_t sched_fn;
	var uint32_t dl_fn;
	var OCT4 tlli := '00000001'O;
	var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);

	/* Initialize NS/BSSGP side */
	f_init_bssgp();

	/* Initialize the PCU interface abstraction */
	f_init_raw(testcasename());

	/* Establish BSSGP connection to the PCU */
	f_bssgp_establish();
	f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);

	/* SGSN sends some DL data, PCU will page on CCCH (PCH) */
	BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data, ms_racap));
	f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass);

	/* Make sure we've got a Downlink TBF assignment */
	f_imm_ass_verify_dl_tbf_ass(rr_imm_ass, dl_tbf_ass);

	/* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
	f_sleep(X2002);
	f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, exp_cs_mcs);

	/* ACK the DL block */
	f_acknackdesc_ack_block(ack_nack_desc, dl_block, '1'B);
	f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(f_rlcmac_dl_block_get_tfi(dl_block), ack_nack_desc),
			     0, f_dl_block_ack_fn(dl_block, dl_fn));

	/* Now MS wants to answer the DL data, Establish an Uplink TBF */
	ok := f_establish_tbf(rr_imm_ass);
	if (not ok) {
		setverdict(fail, "Failed to establish TBF");
		f_shutdown(__BFILE__, __LINE__);
	}

	/* Make sure we've got an Uplink TBF assignment */
	f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);

	/* Send one UL block and make sure it is ACKED fine */
	f_tx_rlcmac_ul_n_blocks(ul_tbf_ass, 1);
	f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
	/* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
	f_tx_rlcmac_ul_block(ts_RLCMAC_CTRL_ACK(tlli), 0, sched_fn);

	/* UL block should be received in SGSN */
	BSSGP[0].receive(tr_BSSGP_UL_UD(tlli, mp_gb_cfg.cell_id));

	f_shutdown(__BFILE__, __LINE__, final := true);
}

testcase TC_mt_ping_pong() runs on RAW_PCU_Test_CT {
	var CodingScheme exp_cs_mcs := CS_1;
	f_TC_mt_ping_pong(omit, exp_cs_mcs);
}

/* TC_mt_ping_pong, but DL-UNITDATA contains RA Access capability with (M)CS
/* information about the MS */
testcase TC_mt_ping_pong_with_dl_racap() runs on RAW_PCU_Test_CT {
	var MultislotCap_GPRS_BSSGP mscap_gprs := {
		gprsmultislotclass := '00011'B,
		gprsextendeddynalloccap := '0'B
	} ;
	var MSRadioAccessCapabilityV_BSSGP ms_racap := { valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, mscap_gprs, omit)) };
	var CodingScheme exp_cs_mcs := CS_2;
	f_TC_mt_ping_pong(ms_racap, exp_cs_mcs);
}

/* Verify that if PCU doesn't get an ACK for first DL block after IMM ASS, it
 * will retry by retransmitting both the IMM ASS + DL block after poll (ack)
 * timeout occurs (specified by sent RRBP on DL block). */
testcase TC_imm_ass_dl_block_retrans() runs on RAW_PCU_Test_CT {
	var GsmRrMessage rr_imm_ass;
	var PacketDlAssign dl_tbf_ass;
	var RlcmacDlBlock dl_block;
	var octetstring data := f_rnd_octstring(10);
	var boolean ok;
	var uint32_t dl_fn;
	var OCT4 tlli := '00000001'O;
	var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);

	/* Initialize NS/BSSGP side */
	f_init_bssgp();

	/* Initialize the PCU interface abstraction */
	f_init_raw(testcasename());

	/* Establish BSSGP connection to the PCU */
	f_bssgp_establish();
	f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);

	/* SGSN sends some DL data, PCU will page on CCCH (PCH) */
	BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));
	f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass);

	/* Make sure we've got a Downlink TBF assignment */
	f_imm_ass_verify_dl_tbf_ass(rr_imm_ass, dl_tbf_ass);

	/* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
	f_sleep(X2002);
	f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);

	/* Now we don't ack the dl block (emulate MS failed receiveing IMM ASS
	 * or GPRS DL, or DL ACK was lost for some reason). As a result, PCU
	 * should retrigger IMM ASS + GPRS DL procedure after poll timeout. */
	f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass);

	/* Make sure we've got a Downlink TBF assignment */
	f_imm_ass_verify_dl_tbf_ass(rr_imm_ass, dl_tbf_ass);

	/* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
	f_sleep(X2002);
	f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);

	/* ACK the DL block */
	f_acknackdesc_ack_block(ack_nack_desc, dl_block, '1'B);
	f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(f_rlcmac_dl_block_get_tfi(dl_block), ack_nack_desc),
			     0, f_dl_block_ack_fn(dl_block, dl_fn));

	f_shutdown(__BFILE__, __LINE__, final := true);
}

/* Verify scheduling of multiple Downlink data blocks during one RRBP. */
testcase TC_dl_flow_more_blocks() runs on RAW_PCU_Test_CT {
	var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
	var octetstring data := f_rnd_octstring(16);
	var OCT4 tlli := f_rnd_octstring(4);
	var PacketDlAssign dl_tbf_ass;
	var GsmRrMessage rr_imm_ass;
	var RlcmacDlBlock dl_block;
	var uint32_t ack_fn;
	var uint32_t fn;
	timer T := 5.0;

	/* Initialize NS/BSSGP side */
	f_init_bssgp();

	/* Initialize the PCU interface abstraction */
	f_init_raw(testcasename());

	/* Establish BSSGP connection to the PCU */
	f_bssgp_establish();
	f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);

	/* SGSN sends some DL data, PCU will page on CCCH (PCH) */
	BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));
	f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass);

	/* Make sure we've got a Downlink TBF assignment with DL TFI */
	f_imm_ass_verify_dl_tbf_ass(rr_imm_ass, dl_tbf_ass);
	if (not ispresent(dl_tbf_ass.group1)) {
		setverdict(fail, "Immediate Assignment contains no DL TFI");
		f_shutdown(__BFILE__, __LINE__);
	}

	/* Get DL TFI from received Downlink TBF assignment */
	var uint5_t tfi := dl_tbf_ass.group1.tfi_assignment;

	/* Wait timer X2002 and DL block is available after CCCH IMM ASS */
	f_sleep(X2002);

	/* Expect the first (GPRS DL) block with bsn=0 and rrbp_valid=1 */
	f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, 0);
	f_acknackdesc_ack_block(ack_nack_desc, dl_block);

	/* TDMA frame number on which we are supposed to send the ACK */
	ack_fn := f_dl_block_ack_fn(dl_block, fn);

	/* SGSN sends more blocks during the indicated RRBP */
	for (var integer bsn := 1; bsn < 63; bsn := bsn + 1) {
		data := f_rnd_octstring(16); /* Random LLC data */
		BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));

		f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, bsn);

		/* Make sure this block has the same TFI as was assigned
		 * FIXME: this is only valid for GPRS, not EGPRS. */
		if (dl_block.data.mac_hdr.hdr_ext.tfi != tfi) {
			setverdict(fail, "Rx DL data block with unexpected TFI: ",
				   dl_block.data.mac_hdr.hdr_ext.tfi);
			f_shutdown(__BFILE__, __LINE__);
		}

		/* Keep Ack/Nack description updated */
		f_acknackdesc_ack_block(ack_nack_desc, dl_block);

		/* Break if this is the end of RRBP */
		if (fn == ack_fn) {
			ack_nack_desc.final_ack := '1'B;
			break;
		}
	}

	/* This is the end of RRBP, send Packet Downlink Ack/Nack */
	f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(tfi, ack_nack_desc), fn := fn);

	/* Make sure that the next block (after the Ack) is dummy */
	f_rx_rlcmac_dl_block_exp_dummy(dl_block);

	f_shutdown(__BFILE__, __LINE__, final := true);
}

private function f_pkt_paging_match_imsi(in PacketPagingReq req, hexstring imsi)
runs on RAW_PCU_Test_CT {
	var MobileIdentityLV_Paging mi_lv := req.repeated_pageinfo.cs.mobile_identity;
	var MobileIdentityV mi := dec_MobileIdentityV(mi_lv.mobile_id);

	if (mi_lv.len != 8) { /* 8 octets: type of ID (3 bits) + even/odd flag (1 bit) + 15 BCD-encoded digits (60 bits) */
		setverdict(fail, "Mobile Identity length mismatch: ",
			   "expected: 8, got: ", mi_lv.len);
		f_shutdown(__BFILE__, __LINE__);
	}

	/* Make sure MI contains IMSI before referencing it */
	if (mi.typeOfIdentity != '001'B) {
		setverdict(fail, "Mobile Identity must be of type IMSI ('001'B), ",
			   "got: ", mi.typeOfIdentity);
		f_shutdown(__BFILE__, __LINE__);
	} else if (mi.oddEvenInd_identity.imsi.digits != imsi) {
		setverdict(fail, "Mobile Identity contains unexpected IMSI, ",
			   "expected: ", imsi, " got: ", mi.oddEvenInd_identity.imsi.digits);
		f_shutdown(__BFILE__, __LINE__);
	}
}

private function f_pkt_paging_match_tmsi(in PacketPagingReq req, template GsmTmsi tmsi)
runs on RAW_PCU_Test_CT {
	if (not match(req.repeated_pageinfo.cs.tmsi, tmsi)) {
		setverdict(fail, "Mobile Identity (TMSI/P-TMSI) mismatch: ",
			   "expected: ", tmsi, "got: ", req.repeated_pageinfo.cs.tmsi);
		f_shutdown(__BFILE__, __LINE__);
	}
}

/* Test CS paging over the BTS<->PCU socket.
 * When a (class B or C, not A) MS has an active TBF (or is on the PDCH), the MS can not react on CS paging over CCCH.
 * Paging should be send on the PACCH.
 *
 * 1. Send a Paging Request over PCU socket.
 * 2. Send a Ready-To-Send message over PCU socket
 * 3. Expect a Paging Frame
 */
testcase TC_paging_cs_from_bts() runs on RAW_PCU_Test_CT {
	var GsmRrMessage rr_imm_ass;
	var PacketUlAssign ul_tbf_ass;
	var RlcmacDlBlock dl_block;
	var boolean ok;
	var OCT4 tlli := '00000001'O;
	var MobileIdentityLV mi;
	var octetstring mi_enc_lv;
	var hexstring imsi := f_gen_imsi(42);

	/* Initialize NS/BSSGP side */
	f_init_bssgp();

	/* Initialize the PCU interface abstraction */
	f_init_raw(testcasename());

	/* Establish BSSGP connection to the PCU */
	f_bssgp_establish();
	f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);

	/* Establish an Uplink TBF */
	ok := f_establish_tbf(rr_imm_ass);
	if (not ok) {
		setverdict(fail, "Failed to establish TBF");
		f_shutdown(__BFILE__, __LINE__);
	}

	/* Make sure we've got an Uplink TBF assignment */
	f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);

	/* build mobile Identity */
	mi := valueof(ts_MI_IMSI_LV(imsi));
	mi_enc_lv := enc_MobileIdentityLV(mi);
	/* Send paging request */
	BTS.send(ts_PCUIF_PAG_REQ(bts_nr := 0, id_lv := mi_enc_lv, chan_needed := 0,
				sapi :=PCU_IF_SAPI_PDTCH));

	/* Receive it on BTS side towards MS */
	f_rx_rlcmac_dl_block_exp_pkt_pag_req(dl_block);

	/* Make sure that Packet Paging Request contains the same IMSI */
	f_pkt_paging_match_imsi(dl_block.ctrl.payload.u.paging, imsi);

	f_shutdown(__BFILE__, __LINE__, final := true);
}

/* Test CS paging over Gb (SGSN->PCU->BTS[PDCH]).
 */
private function f_tc_paging_cs_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
runs on RAW_PCU_Test_CT {
	var GsmRrMessage rr_imm_ass;
	var PacketUlAssign ul_tbf_ass;
	var RlcmacDlBlock dl_block;
	var boolean ok;
	var OCT4 tlli := '00000001'O;
	var hexstring imsi := f_gen_imsi(42);
	var GsmTmsi tmsi;

	/* Initialize NS/BSSGP side */
	f_init_bssgp();

	/* Initialize the PCU interface abstraction */
	f_init_raw(testcasename());

	/* Establish BSSGP connection to the PCU */
	f_bssgp_establish();
	f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);

	/* Establish an Uplink TBF */
	ok := f_establish_tbf(rr_imm_ass);
	if (not ok) {
		setverdict(fail, "Failed to establish TBF");
		f_shutdown(__BFILE__, __LINE__);
	}

	/* Make sure we've got an Uplink TBF assignment */
	f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);

	/* Send paging request with or without TMSI */
	if (use_ptmsi) {
		tmsi := oct2int(f_rnd_octstring(4)); /* Random P-TMSI */
		BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, tmsi));
	} else {
		BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, imsi));
	}

	/* Receive it on BTS side towards MS */
	f_rx_rlcmac_dl_block_exp_pkt_pag_req(dl_block);

	/* Make sure that Packet Paging Request contains the same P-TMSI/IMSI */
	if (use_ptmsi) {
		f_pkt_paging_match_tmsi(dl_block.ctrl.payload.u.paging, tmsi);
	} else {
		f_pkt_paging_match_imsi(dl_block.ctrl.payload.u.paging, imsi);
	}

	f_shutdown(__BFILE__, __LINE__, final := true);
}

testcase TC_paging_cs_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
	f_tc_paging_cs_from_sgsn(0, true);
}

testcase TC_paging_cs_from_sgsn_sign() runs on RAW_PCU_Test_CT {
	f_tc_paging_cs_from_sgsn(0);
}

testcase TC_paging_cs_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
	f_tc_paging_cs_from_sgsn(mp_gb_cfg.bvci);
}

/* Test PS paging over Gb (SGSN->PCU->BTS[CCCH]).
 */
private function f_tc_paging_ps_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
runs on RAW_PCU_Test_CT {
	var OCT4 tlli := '00000001'O;
	var integer imsi_suff_tx := 423;
	var hexstring imsi := f_gen_imsi(imsi_suff_tx);

	/* Initialize NS/BSSGP side */
	f_init_bssgp();

	/* Initialize the PCU interface abstraction */
	f_init_raw(testcasename());

	/* Establish BSSGP connection to the PCU */
	f_bssgp_establish();
	f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);

	/* Send BSSGP PAGING-PS (with or without TMSI), wait for RR Paging Request Type 1.
	 * Make sure that both paging group (IMSI suffix) and Mobile Identity match. */
	if (use_ptmsi) {
		var OCT4 tmsi := f_rnd_octstring(4); /* Random P-TMSI */
		BSSGP[0].send(ts_BSSGP_PS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
		f_pcuif_rx_pch_pag_req1(t_MI_TMSI(tmsi), imsi_suff_tx);
	} else {
		BSSGP[0].send(ts_BSSGP_PS_PAGING_IMSI(bvci, imsi));
		f_pcuif_rx_pch_pag_req1(tr_MI_IMSI(imsi), imsi_suff_tx);
	}

	f_shutdown(__BFILE__, __LINE__, final := true);
}

testcase TC_paging_ps_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
	f_tc_paging_ps_from_sgsn(0, true);
}

testcase TC_paging_ps_from_sgsn_sign() runs on RAW_PCU_Test_CT {
	f_tc_paging_ps_from_sgsn(0);
}

testcase TC_paging_ps_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
	f_tc_paging_ps_from_sgsn(mp_gb_cfg.bvci);
}

private function f_TC_egprs_pkt_chan_req(in EGPRSPktChRequest req,
					 template GsmRrMessage t_imm_ass := ?,
					 PCUIF_BurstType bt := BURST_TYPE_1)
runs on RAW_PCU_Test_CT {
	var GsmRrMessage rr_msg;
	var uint16_t ra11;
	var boolean ok;

	ra11 := enc_EGPRSPktChRequest2uint(req);
	log("Sending EGPRS Packet Channel Request (", ra11, "): ", req);

	ok := f_establish_tbf(rr_msg, ra := ra11, is_11bit := 1, burst_type := bt);
	if (not ok) {
		setverdict(fail, "Failed to establush an Uplink TBF");
		f_shutdown(__BFILE__, __LINE__);
	}

	if (not match(rr_msg, t_imm_ass)) {
		setverdict(fail, "Immediate Assignment does not match");
		f_shutdown(__BFILE__, __LINE__);
	}

	setverdict(pass);
}

testcase TC_egprs_pkt_chan_req_signalling() runs on RAW_PCU_Test_CT {
	var template GsmRrMessage imm_ass;
	var template IaRestOctets rest;
	var template EgprsUlAss ul_ass;

	/* Initialize the PCU interface abstraction */
	f_init_raw(testcasename());

	var EGPRSPktChRequest req := {
		/* NOTE: other fields are set in the loop */
		signalling := { tag := '110011'B }
	};

	for (var integer i := 0; i < 6; i := i + 1) {
		var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
		req.signalling.random_bits := ext_ra;

		/* For signalling, do we expect Multiblock UL TBF Assignment? */
		ul_ass  := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
		rest    := tr_IaRestOctets_EGPRSULAss(ul_ass);
		imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);

		f_TC_egprs_pkt_chan_req(req, imm_ass);
	}

	f_shutdown(__BFILE__, __LINE__, final := true);
}

testcase TC_egprs_pkt_chan_req_one_phase() runs on RAW_PCU_Test_CT {
	var template GsmRrMessage imm_ass;
	var template IaRestOctets rest;
	var template EgprsUlAss ul_ass;

	/* Initialize the PCU interface abstraction */
	f_init_raw(testcasename());

	var EGPRSPktChRequest req := {
		/* NOTE: other fields are set in the loop */
		one_phase := { tag := '0'B }
	};

	for (var integer i := 0; i < 6; i := i + 1) {
		var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
		var BIT5 mslot_class := int2bit(f_rnd_int(32), 5);
		var BIT2 priority := substr(ext_ra, 0, 2);
		var BIT3 rand := substr(ext_ra, 2, 3);

		req.one_phase.multislot_class := mslot_class;
		req.one_phase.priority := priority;
		req.one_phase.random_bits := rand;

		/* For one phase access, do we expect Dynamic UL TBF Assignment? */
		ul_ass  := tr_EgprsUlAssDynamic(ext_ra := ext_ra);
		rest    := tr_IaRestOctets_EGPRSULAss(ul_ass);
		imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);

		f_TC_egprs_pkt_chan_req(req, imm_ass);
	}

	f_shutdown(__BFILE__, __LINE__, final := true);
}

testcase TC_egprs_pkt_chan_req_two_phase() runs on RAW_PCU_Test_CT {
	var template GsmRrMessage imm_ass;
	var template IaRestOctets rest;
	var template EgprsUlAss ul_ass;

	/* Initialize the PCU interface abstraction */
	f_init_raw(testcasename());

	var EGPRSPktChRequest req := {
		/* NOTE: other fields are set in the loop */
		two_phase := { tag := '110000'B }
	};

	for (var integer i := 0; i < 6; i := i + 1) {
		var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
		var BIT2 priority := substr(ext_ra, 0, 2);
		var BIT3 rand := substr(ext_ra, 2, 3);

		req.two_phase.priority := priority;
		req.two_phase.random_bits := rand;

		/* For two phase access, do we expect Multiblock UL TBF Assignment? */
		ul_ass  := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
		rest    := tr_IaRestOctets_EGPRSULAss(ul_ass);
		imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);

		f_TC_egprs_pkt_chan_req(req, imm_ass);
	}

	f_shutdown(__BFILE__, __LINE__, final := true);
}

control {
	execute( TC_pcuif_suspend() );
	execute( TC_ta_ptcch_idle() );
	execute( TC_ta_rach_imm_ass() );
	execute( TC_ta_idle_dl_tbf_ass() );
	execute( TC_ta_ptcch_ul_multi_tbf() );
	execute( TC_cs_lqual_ul_tbf() );
	execute( TC_cs_initial_ul() );
	execute( TC_cs_max_ul() );
	execute( TC_t3169() );
	execute( TC_t3193() );
	execute( TC_mo_ping_pong() );
	execute( TC_mo_ping_pong_with_ul_racap() );
	execute( TC_mt_ping_pong() );
	execute( TC_mt_ping_pong_with_dl_racap() );
	execute( TC_imm_ass_dl_block_retrans() );
	execute( TC_dl_flow_more_blocks() );
	execute( TC_paging_cs_from_bts() );
	execute( TC_paging_cs_from_sgsn_sign_ptmsi() );
	execute( TC_paging_cs_from_sgsn_sign() );
	execute( TC_paging_cs_from_sgsn_ptp() );
	execute( TC_paging_ps_from_sgsn_sign_ptmsi() );
	execute( TC_paging_ps_from_sgsn_sign() );
	execute( TC_paging_ps_from_sgsn_ptp() );

	/* EGPRS specific test cases */
	execute( TC_egprs_pkt_chan_req_signalling() );
	execute( TC_egprs_pkt_chan_req_one_phase() );
	execute( TC_egprs_pkt_chan_req_two_phase() );
}






}
