module GPRS_Components {
/*
 * Osmocom PCU test suite in TTCN-3, components for GPRS handlng
 * (C) 2018-2019 Harald Welte <laforge@gnumonks.org>
 * (C) 2019 Vadim Yanitskiy <axilirator@gmail.com>
 * (C) 2020 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
 * 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
 */

import from General_Types all;
import from Osmocom_Types all;
import from GSM_Types all;
import from GSM_RR_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 PCUIF_Types all;
import from PCUIF_Components all;
import from Native_Functions all;

modulepar {
	/* ARFCN of 1st TRX. Subsequent TRX are allocated incrementing ARFCNs. Nth TRX => base_arfcn + N-1 */
	GsmArfcn mp_base_arfcn := 871;
};

type record TsTrxBtsNum {
	uint3_t		ts_nr,
	uint3_t		trx_nr,
	uint8_t		bts_nr,
	uint8_t		blk_nr
};

/* Useful to store poll FN + BTS+TRX+TS requested by network */
type record PollFnCtx {
	TsTrxBtsNum tstrxbts,
	uint32_t fn
};

template (value) TsTrxBtsNum ts_TsTrxBtsNum(uint3_t ts_nr := 7,
					    uint3_t trx_nr := 0,
					    uint8_t bts_nr := 0,
					    uint8_t blk_nr := 0) := {
	ts_nr := ts_nr,
	trx_nr := trx_nr,
	bts_nr := bts_nr,
	blk_nr := blk_nr
};
template TsTrxBtsNum tr_TsTrxBtsNum(template uint3_t ts_nr := ?,
				    template uint3_t trx_nr := ?,
				    template uint8_t bts_nr := ?,
				    template uint8_t blk_nr := ?) := {
	ts_nr := ts_nr,
	trx_nr := trx_nr,
	bts_nr := bts_nr,
	blk_nr := blk_nr
};

type union PacketDlAssignChan {
	PacketDlAssign		ccch,
	PacketDlAssignment	pacch
};

type record DlTbf {
	GsmRrMessage		rr_imm_ass optional,
	PacketDlAssignChan	ass optional,
	uint5_t			tfi,
	GsmArfcn		arfcn optional,
	BIT8                    ts_mask,
	AckNackDescription	acknack_desc
};

type union PacketUlAssignChan {
	PacketUlAssign		ccch,
	EgprsUlAss		ccch_egprs,
	PacketUlAssignment	pacch
};

type record UlTbf {
	GsmRrMessage		rr_imm_ass optional,
	PacketUlAssignChan	ass optional,
	uint5_t			tfi,
	GsmArfcn		arfcn optional,
	BIT8                    ts_mask,
	uint3_t			usf[8],
	boolean			is_egprs,
	uint14_t		bsn,
	CodingScheme		tx_cs_mcs
};

type record GprsMS {
	hexstring	imsi,
	GprsTlli	tlli,
	uint16_t	ra,
	uint8_t		ra_is_11bit,
	PCUIF_BurstType	burst_type,
	TimingAdvance	ta,
	int16_t		lqual_cb,
	UlTbf		ul_tbf optional, /* TODO: Only 1 UL tbf supported for now */
	DlTbf		dl_tbf optional /* TODO: Only 1 DL tbf supported for now */
};
type record of GprsMS GprsMSList;

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

const uint3_t USF_UNUSED := 7; /* used to indicate PRACH */

template (value) GprsMS t_GprsMS_def := {
        imsi := f_gen_imsi(42),
        tlli := f_gen_tlli(),
        ra := bit2int(chan_req_def),
        ra_is_11bit := 0,
        burst_type := BURST_TYPE_0,
        ta := 0,
        lqual_cb := 0,
        ul_tbf := omit,
        dl_tbf := omit
};

template (value) DlTbf t_DlTbf_def := {
	rr_imm_ass := omit,
	ass := omit,
	tfi := 0,
	arfcn := omit,
	ts_mask := '00000000'B,
	acknack_desc := t_AckNackDescription_init
};

template (value) UlTbf t_UlTbf_def := {
	rr_imm_ass := omit,
	ass := omit,
	tfi := 0,
	arfcn := omit,
	ts_mask := '00000000'B,
	usf := { USF_UNUSED, USF_UNUSED, USF_UNUSED, USF_UNUSED, USF_UNUSED, USF_UNUSED, USF_UNUSED, USF_UNUSED },
	is_egprs := false,
	bsn := 0,
	tx_cs_mcs := CS_1
};

type component MS_BTS_IFACE_CT {
	/* Virtual BTS component */
	var RAW_PCU_BTS_CT vc_BTS;
	/* Connection to the BTS component (one for now) */
	port RAW_PCU_MSG_PT BTS;

	/* Mobile station(s) involved in a testing scenario */
	var GprsMSList g_ms := { };

	/* Value at which Countdown Procedure starts. Announced by network (GPRS Cell Options as per TS 04.60 Chapter 12.24) */
	var uint4_t g_bs_cv_max := 4;
}

/* Generate a list of GprsMS (unique IMSI/TLLI, cyclic RA) of the given size */
function f_init_gprs_ms(integer num_ms := 1, template (value) GprsMS t_ms := t_GprsMS_def)
runs on MS_BTS_IFACE_CT {
	for (var integer i := 0; i < num_ms; i := i + 1 ) {
		var GprsMS ms := valueof(t_ms);

		/* We assume that num_ms is not a large number */
		ms.imsi := f_gen_imsi(i + 1);
		ms.tlli := int2oct(i + 1, 4);

		/* Ensure different RA for siblings */
		if (ms.ra == bit2int(chan_req_def)) {
			/* 01111 { 0xx | x0x | xx0 } */
			f_ms_use_ra(ms, ms.ra + (i mod 7));
		} else if (ms.ra == bit2int(chan_req_sb)) {
			/* 01110xxx */
			f_ms_use_ra(ms, ms.ra + (i mod 8));
		}

		/* Append to the global list */
		g_ms := g_ms & { ms };
	}
}


function f_shutdown(charstring file, integer line,
		    boolean final := false)
runs on MS_BTS_IFACE_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;
}

function f_arfcn2trxnr(GsmArfcn arfcn) runs on MS_BTS_IFACE_CT return uint3_t {
	if (arfcn < mp_base_arfcn) {
		setverdict(fail, "Unable to find TRX NR for arfcn ", arfcn);
		f_shutdown(__BFILE__, __LINE__);
	}
	return arfcn - mp_base_arfcn;
}

function f_trxnr2arfcn(uint3_t trx_nr) return GsmArfcn {
	return mp_base_arfcn + trx_nr;
}

function f_ultbf_new_from_rr_imm_ass(in GsmRrMessage rr_imm_ass)
runs on MS_BTS_IFACE_CT return UlTbf {
	var UlTbf ul_tbf := valueof(t_UlTbf_def);
	var uint3_t tn_allocated := rr_imm_ass.payload.imm_ass.pkt_chan_desc.tn;

	ul_tbf.rr_imm_ass := rr_imm_ass;
	if (rr_imm_ass.payload.imm_ass.pkt_chan_desc.presence == '0'B and
	    rr_imm_ass.payload.imm_ass.pkt_chan_desc.zero.hopping == '0'B) {
		ul_tbf.arfcn := rr_imm_ass.payload.imm_ass.pkt_chan_desc.zero.arfcn;
	}
	ul_tbf.ts_mask[tn_allocated] := '1'B;

	/* 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.ccch := rr_imm_ass.payload.imm_ass.rest_octets.hh.pa.uldl.ass.ul;
		log("Rx Uplink TBF GPRS assignment: ", ul_tbf.ass.ccch);
		ul_tbf.is_egprs := false;
		if (match(ul_tbf.ass.ccch, tr_PacketUlDynAssign)) {
			ul_tbf.tfi := ul_tbf.ass.ccch.dynamic.tfi_assignment;
			ul_tbf.tx_cs_mcs := f_rlcmac_block_ChCodingCommand2cs_mcs(ul_tbf.ass.ccch.dynamic.ch_coding_cmd);
			ul_tbf.usf[tn_allocated] := ul_tbf.ass.ccch.dynamic.usf;
		} else if (match(ul_tbf.ass.ccch, tr_PacketUlSglAssign)) {
			/* Nothing to do here  yet */
		}
	} else if (match(rr_imm_ass, tr_IMM_TBF_ASS(dl := false, rest := tr_IaRestOctets_EGPRSULAss(?)))) {
		ul_tbf.ass.ccch_egprs := rr_imm_ass.payload.imm_ass.rest_octets.lh.egprs_ul;
		log("Rx Uplink TBF EGPRS assignment: ", ul_tbf.ass.ccch_egprs);
		ul_tbf.is_egprs := true;
		if (match(ul_tbf.ass.ccch_egprs, tr_EgprsUlAssDynamic)) {
			ul_tbf.tfi := ul_tbf.ass.ccch_egprs.dynamic.tfi_assignment;
			ul_tbf.tx_cs_mcs := f_rlcmac_block_EgprsChCodingCommand2cs_mcs(ul_tbf.ass.ccch_egprs.dynamic.egprs_ch_coding_cmd);
			ul_tbf.usf[tn_allocated] := ul_tbf.ass.ccch_egprs.dynamic.usf;
		} else if (match(ul_tbf.ass.ccch_egprs, tr_EgprsUlAssMultiblock)) {
			/* Nothing to do here yet */
		}
	} else {
		setverdict(fail, "Failed to match UL TBF Assignment: ", rr_imm_ass);
		f_shutdown(__BFILE__, __LINE__);
	}

	setverdict(pass);
	return ul_tbf;
}

function f_ultbf_new_from_ass_pacch(RlcmacDlBlock dl_block)
runs on MS_BTS_IFACE_CT return UlTbf {
	var UlTbf ul_tbf := valueof(t_UlTbf_def);
	var boolean freq_par_present := false;
	var FrequencyParameters freq_par;

	ul_tbf.ass.pacch := dl_block.ctrl.payload.u.ul_assignment;
	ul_tbf.tx_cs_mcs := f_rlcmac_dl_block_get_assigned_ul_cs_mcs(dl_block);
	ul_tbf.tfi := f_rlcmac_dl_block_get_tfi(dl_block);
	/* TODO: handle GlobalTfiOrTlli	 tfi_or_tlli from pkt_ul_ass */

	/* TODO: support single block allocation */
	if (match(dl_block, tr_RLCMAC_UL_PACKET_ASS_GPRS(?, tr_PktUlAssGprsDynamic(tr_DynamicAllocation(?))))) {
		ul_tbf.tfi := dl_block.ctrl.payload.u.ul_assignment.gprs.dyn_block_alloc.ul_tfi_assignment;
		freq_par_present := dl_block.ctrl.payload.u.ul_assignment.gprs.freq_par_present == '1'B;
		if (freq_par_present) {
			freq_par := dl_block.ctrl.payload.u.ul_assignment.gprs.freq_par;
		}
		ul_tbf.is_egprs := false;
		for (var integer i := 0; i < 8; i := i + 1) {
			if (dl_block.ctrl.payload.u.ul_assignment.gprs.dyn_block_alloc.ts_allocation.ts[i].presence == '1'B) {
				ul_tbf.ts_mask[i] := '1'B;
				ul_tbf.usf[i] := dl_block.ctrl.payload.u.ul_assignment.gprs.dyn_block_alloc.ts_allocation.ts[i].usf_tn;
			}
		}
	} else if (match(dl_block, tr_RLCMAC_UL_PACKET_ASS_EGPRS(?, tr_PktUlAssEgprsDynamic(tr_DynamicAllocation(?))))) {
		ul_tbf.tfi := dl_block.ctrl.payload.u.ul_assignment.egprs.dyn_block_alloc.ul_tfi_assignment;
		freq_par_present := dl_block.ctrl.payload.u.ul_assignment.egprs.freq_par_present == '1'B;
		if (freq_par_present) {
			freq_par := dl_block.ctrl.payload.u.ul_assignment.egprs.freq_par;
		}
		ul_tbf.is_egprs := true;
		for (var integer i := 0; i < 8; i := i + 1) {
			if (dl_block.ctrl.payload.u.ul_assignment.egprs.dyn_block_alloc.ts_allocation.ts[i].presence == '1'B) {
				ul_tbf.ts_mask[i] := '1'B;
				ul_tbf.usf[i] := dl_block.ctrl.payload.u.ul_assignment.egprs.dyn_block_alloc.ts_allocation.ts[i].usf_tn;
			}
		}
	}

	/* FIXME: freq_par and arfcn are optional. in that case we need to
	 * infer/reuse from current dl_tbf or ul_tbf */
	if (freq_par_present and freq_par.presence == '00'B) {
		ul_tbf.arfcn := freq_par.arfcn;
	}

	return ul_tbf;
}

function f_dltbf_new_from_rr_imm_ass(in GsmRrMessage rr_imm_ass, template PacketDlAssign dl_ass := tr_PacketDlAssign(?))
runs on MS_BTS_IFACE_CT return DlTbf {
	var DlTbf dl_tbf := valueof(t_DlTbf_def);

	dl_tbf.rr_imm_ass := rr_imm_ass;
	if (rr_imm_ass.payload.imm_ass.pkt_chan_desc.presence == '0'B and
	    rr_imm_ass.payload.imm_ass.pkt_chan_desc.zero.hopping == '0'B) {
		dl_tbf.arfcn := rr_imm_ass.payload.imm_ass.pkt_chan_desc.zero.arfcn;
	}
	dl_tbf.ts_mask[rr_imm_ass.payload.imm_ass.pkt_chan_desc.tn] := '1'B;

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

	/* TODO: match TLLI */
	if (dl_tbf.ass.ccch.group1_present == '1'B) {
		dl_tbf.tfi := dl_tbf.ass.ccch.group1.tfi_assignment;
	} else {
		setverdict(fail, "Immediate Assignment contains no DL TFI");
		f_shutdown(__BFILE__, __LINE__);
	}

	setverdict(pass);
	return dl_tbf;
}

function f_dltbf_new_from_ass_pacch(RlcmacDlBlock dl_block)
runs on MS_BTS_IFACE_CT return DlTbf {
	var DlTbf dl_tbf := valueof(t_DlTbf_def);
	var boolean freq_par_present := false;
	var FrequencyParameters freq_par;

	dl_tbf.ass.pacch := dl_block.ctrl.payload.u.dl_assignment;
	dl_tbf.tfi := f_rlcmac_dl_block_get_tfi(dl_block);
	/* TODO: handle GlobalTfiOrTlli	 tfi_or_tlli from pkt_dl_ass */

	if (match(dl_block, tr_RLCMAC_DL_PACKET_ASS(?))) {
		dl_tbf.tfi := dl_block.ctrl.payload.u.dl_assignment.dl_tfi_assignment;
		freq_par_present := dl_block.ctrl.payload.u.dl_assignment.freq_par_present == '1'B;
		if (freq_par_present) {
			freq_par := dl_block.ctrl.payload.u.dl_assignment.freq_par;
		}
		dl_tbf.ts_mask := dl_block.ctrl.payload.u.dl_assignment.timeslot_alloc; /* TODO: is this the correct order ? */
		/* TODO: check egprs in dl_assignment.rel_additions (PktDlAssR99Additions) */
	}

	/* FIXME: freq_par and arfcn are optional. in that case we need to
	 * infer/reuse from current dl_tbf or ul_tbf */
	if (freq_par_present and freq_par.presence == '00'B) {
		dl_tbf.arfcn := freq_par.arfcn;
	}
	return dl_tbf;
}

function f_ms_tx_TsTrxBtsNum(inout GprsMS ms)
runs on MS_BTS_IFACE_CT return TsTrxBtsNum {
	var uint3_t ts_nr := f_ultbf_next_ts(ms.ul_tbf);

	var uint3_t trx_nr;
	if (ispresent(ms.ul_tbf.arfcn)) {
		trx_nr := f_arfcn2trxnr(ms.ul_tbf.arfcn);
	} else {
		/* FIXME: implement search by hsn+maio+ma when freq hopping is enabled */
		setverdict(fail, "Asked for trx_nr but arfcn not available in ms.ul_tbf!");
		f_shutdown(__BFILE__, __LINE__);
	}
	return valueof(ts_TsTrxBtsNum(ts_nr, trx_nr));
}

function f_dltbf_num_slots(DlTbf dl_tbf)
runs on MS_BTS_IFACE_CT return integer  {
	var integer n := 0;
	for (var integer i := 0; i < lengthof(dl_tbf.ts_mask); i := i + 1) {
		if (dl_tbf.ts_mask[i] == '1'B) {
			n := n + 1;
		}
	}
	return n;
}

function f_ultbf_inc_bsn(inout UlTbf ul_tbf)
runs on MS_BTS_IFACE_CT {
	ul_tbf.bsn := ul_tbf.bsn + 1;
	ul_tbf.bsn := ul_tbf.bsn mod 128; /* FIXME: EGPRS SNS: 2048 */
}

function f_ultbf_next_ts(UlTbf ul_tbf)
runs on MS_BTS_IFACE_CT return uint3_t {
	/* FIXME: in the future we probably want to store last used internally
	/* and continue from there */
	for (var integer i := 0; i < lengthof(ul_tbf.ts_mask); i := i + 1) {
		if (ul_tbf.ts_mask[i] == '1'B) {
			return i;
		}
	}
	setverdict(fail, "No TS available for tx!");
	f_shutdown(__BFILE__, __LINE__);
	return 0;
}

function f_ultbf_num_slots(UlTbf ul_tbf)
runs on MS_BTS_IFACE_CT return integer  {
	var integer n := 0;
	for (var integer i := 0; i < lengthof(ul_tbf.ts_mask); i := i + 1) {
		if (ul_tbf.ts_mask[i] == '1'B) {
			n := n + 1;
		}
	}
	return n;
}

function f_ms_use_ra(inout GprsMS ms, uint16_t ra, uint8_t ra_is_11bit := 0)
runs on MS_BTS_IFACE_CT {
	ms.ra_is_11bit := ra_is_11bit;
	ms.ra := ra;
	if (ra_is_11bit == 0) {
		ms.burst_type := BURST_TYPE_0;
	} else {
		ms.burst_type := BURST_TYPE_1;
	}
}

function f_ms_rx_pkt_ass_pacch(inout GprsMS ms, out uint32_t poll_fn,
			       template RlcmacDlBlock t_pkt_ass := ?,
			       template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum)
runs on MS_BTS_IFACE_CT return RlcmacDlBlock {
	var RlcmacDlBlock dl_block;
	var uint32_t dl_fn;

	f_rx_rlcmac_dl_block(dl_block, dl_fn, nr := nr);
	if (not match(dl_block, t_pkt_ass)) {
		setverdict(fail, "Failed to match Packet Assignment:", t_pkt_ass);
		f_shutdown(__BFILE__, __LINE__);
	}

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

	if (match(dl_block, tr_RLCMAC_UL_PACKET_ASS)) {
	       ms.ul_tbf := f_ultbf_new_from_ass_pacch(dl_block);
	       if (ms.ul_tbf.ass.pacch.identity.tlli.tlli != ms.tlli) {
		       setverdict(fail, "Wrong TLLI ", ms.ul_tbf.ass.pacch.identity.tlli, " received vs exp ", ms.tlli);
		       f_shutdown(__BFILE__, __LINE__);
	       }
	} else if (match(dl_block, tr_RLCMAC_DL_PACKET_ASS)) {
		ms.dl_tbf := f_dltbf_new_from_ass_pacch(dl_block);
		if (ischosen(ms.dl_tbf.ass.pacch.tfi_or_tlli.tlli) and
		    ms.dl_tbf.ass.pacch.tfi_or_tlli.tlli.tlli != ms.tlli) {
			setverdict(fail, "Wrong TLLI ", ms.dl_tbf.ass.pacch.tfi_or_tlli.tlli.tlli, " received vs exp ", ms.tlli);
			f_shutdown(__BFILE__, __LINE__);
		}
	} else {
		setverdict(fail, "Should not happen:", dl_block);
		f_shutdown(__BFILE__, __LINE__);
	}

	return dl_block;
}

function f_ms_establish_ul_tbf(inout GprsMS ms, template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum)
runs on MS_BTS_IFACE_CT {
	var GsmRrMessage rr_imm_ass;

	rr_imm_ass := f_pcuif_tx_rach_rx_imm_ass(ms.ra, ms.ra_is_11bit, ms.burst_type, ms.ta, nr := nr);
	ms.ul_tbf := f_ultbf_new_from_rr_imm_ass(rr_imm_ass);
}

function f_ms_exp_dl_tbf_ass_ccch(inout GprsMS ms, template PCUIF_Sapi sapi := PCU_IF_SAPI_AGCH,
				  template GsmRrMessage t_imm_ass := tr_IMM_TBF_ASS(true, ?, ?),
				  template (present) TsTrxBtsNum nr := tr_TsTrxBtsNum)
runs on MS_BTS_IFACE_CT {
	var GsmRrMessage rr_imm_ass;

	rr_imm_ass := f_pcuif_rx_imm_ass(sapi, t_imm_ass, nr := nr);
	ms.dl_tbf := f_dltbf_new_from_rr_imm_ass(rr_imm_ass, tr_PacketDlAssign(ms.tlli));
}

/* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
function f_ms_tx_data_ind(inout GprsMS ms, octetstring data, uint32_t fn := 0,
			  template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum)
runs on MS_BTS_IFACE_CT {
	f_pcuif_tx_data_ind(data, ms.lqual_cb, fn, nr := nr);
}

function f_ms_tx_ul_block(inout GprsMS ms, template (value) RlcmacUlBlock ul_data,
			  uint32_t fn := 0, template (omit) CodingScheme force_cs_mcs := omit,
			  template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum)
runs on MS_BTS_IFACE_CT return integer {
	var octetstring data;
	var integer padding_len;
	var CodingScheme cs_mcs;
	var uint32_t cs_mcs_len;

	/* Encode the payload of DATA.ind */
	data := enc_RlcmacUlBlock(valueof(ul_data));

	if (ispresent(force_cs_mcs)) {
		cs_mcs := valueof(force_cs_mcs);
	} else if (ischosen(ul_data.ctrl)) {
		cs_mcs := CS_1; /* CTRL is always CS1 */
	} else {
		/* Add padding to encode payload to minimum required CS/MCS: */
		cs_mcs := f_rlcmac_block_len_required_cs_mcs(lengthof(data), ischosen(ul_data.data_egprs));
	}

	cs_mcs_len := f_rlcmac_cs_mcs2block_len(cs_mcs);
	padding_len := cs_mcs_len - lengthof(data);
	if (padding_len < 0) {
		setverdict(fail, "Unable to encode UL block of size ", lengthof(data), " with ", cs_mcs);
		f_shutdown(__BFILE__, __LINE__);
	}
	data := f_pad_oct(data, cs_mcs_len, '00'O);

	/* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
	f_ms_tx_data_ind(ms, data, fn, nr := nr);
	return padding_len;
}

/* FIXME: Only supports sending CS-1 so far */
function f_ms_tx_ul_data_block(inout GprsMS ms, octetstring payload,
			       uint4_t cv := 15, boolean with_tlli := false, uint32_t fn := 0,
			       template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum)
runs on MS_BTS_IFACE_CT return integer {
	var template (value) RlcmacUlBlock ul_data;
	ul_data := t_RLCMAC_UL_DATA(tfi := ms.ul_tbf.tfi,
				    cv := cv,
				    bsn := ms.ul_tbf.bsn,
				    blocks := {t_RLCMAC_LLCBLOCK(payload)});
	if (with_tlli) {
		ul_data.data.mac_hdr.tlli_ind := true;
		ul_data.data.tlli := ms.tlli;
	}
	f_ultbf_inc_bsn(ms.ul_tbf);
	return f_ms_tx_ul_block(ms, ul_data, fn, nr := nr);
}

/* Send random payload for last "num_blocks" blocks in Ul TBF (ending with CV=0). */
function f_ms_tx_ul_data_block_multi(inout GprsMS ms, integer num_blocks := 1, boolean with_tlli := false,
				     template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum)
runs on MS_BTS_IFACE_CT return octetstring {
	var octetstring total_payload := ''O;

	for (var integer i := 0; i < num_blocks; i := i + 1) {
		var integer padding_len;
		var octetstring payload := f_rnd_octstring(10);
		/* Prepare a new UL block (CV, random payload) */
		var integer cv := num_blocks - i - 1;
		if (cv > g_bs_cv_max) {
			cv := 15;
		}
		padding_len := f_ms_tx_ul_data_block(ms, payload, cv := cv, with_tlli := with_tlli, nr := nr);
		total_payload := total_payload & payload & f_pad_oct(''O, padding_len, '00'O);
	}
	return total_payload;
}

function f_rlcmac_dl_block_get_tfi(RlcmacDlBlock dl_block)
runs on MS_BTS_IFACE_CT return uint5_t {
	if (ischosen(dl_block.data)) {
		return dl_block.data.mac_hdr.hdr_ext.tfi;
	} else if (ischosen(dl_block.data_egprs)) {
		return dl_block.data_egprs.mac_hdr.tfi;
	} else { /* Ctrl block */
		if (match(dl_block, tr_RLCMAC_UL_PACKET_ASS_GPRS(?, tr_PktUlAssGprsDynamic(tr_DynamicAllocation(?))))) {
			return dl_block.ctrl.payload.u.ul_assignment.gprs.dyn_block_alloc.ul_tfi_assignment;
		}
		if (match(dl_block, tr_RLCMAC_UL_PACKET_ASS_EGPRS(?, tr_PktUlAssEgprsDynamic(tr_DynamicAllocation(?))))) {
			return dl_block.ctrl.payload.u.ul_assignment.egprs.dyn_block_alloc.ul_tfi_assignment;
		}
		if (match(dl_block, tr_RLCMAC_DL_PACKET_ASS(?))) {
			return dl_block.ctrl.payload.u.dl_assignment.dl_tfi_assignment;
		}
	}
	setverdict(fail, "DlBlock doesn't contain a TFI:", dl_block);
	f_shutdown(__BFILE__, __LINE__);
	return 0; /* make compiler happy */
}

/* Get the Chan coding command from a dl block containing PACCH UL Assignment */
function f_rlcmac_dl_block_get_assigned_ul_cs_mcs(RlcmacDlBlock dl_block)
runs on MS_BTS_IFACE_CT return CodingScheme {
	if (match(dl_block, tr_RLCMAC_UL_PACKET_ASS_GPRS(?, tr_PktUlAssGprsDynamic(?)))) {
		return f_rlcmac_block_ChCodingCommand2cs_mcs(dl_block.ctrl.payload.u.ul_assignment.gprs.ch_coding_cmd);
	}
	if (match(dl_block, tr_RLCMAC_UL_PACKET_ASS_EGPRS(?, tr_PktUlAssEgprsDynamic(?)))) {
		return f_rlcmac_block_EgprsChCodingCommand2cs_mcs(dl_block.ctrl.payload.u.ul_assignment.egprs.chan_coding_cmd);
	}
	setverdict(fail, "DlBlock doesn't contain CS_MCS information:", dl_block);
	f_shutdown(__BFILE__, __LINE__);
	return CS_1; /* make compiler happy */
}

/* TS 44.060 sec 12.3 Ack/Nack Description */
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;
	}

	/* 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;
	}
	/* Filling hole, wraparound: */
	if (bsn - desc.starting_seq_nr > lengthof(desc.receive_block_bitmap)) {
		desc.receive_block_bitmap[lengthof(desc.receive_block_bitmap) - (desc.starting_seq_nr + (218 - bsn))] := int2bit(1, 1);
		return;
	}

	inc := bsn - desc.starting_seq_nr + 1;

	/* 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) mod 128;
	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. */
function f_pcuif_tx_data_cnf(in PCUIF_Message pcu_msg)
runs on MS_BTS_IFACE_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);
}

////////////////////////
// Low level APIs
////////////////////////

function f_pcuif_rx_imm_ass(template PCUIF_Sapi sapi := PCU_IF_SAPI_AGCH,
			    template GsmRrMessage t_imm_ass := ?,
			    template (present) TsTrxBtsNum nr := tr_TsTrxBtsNum)
runs on MS_BTS_IFACE_CT return GsmRrMessage {
	var GsmRrMessage rr_imm_ass;
	var PCUIF_Message pcu_msg;
	var octetstring data;
	timer T;

	T.start(2.0);
	alt {
	[] BTS.receive(tr_PCUIF_DATA_REQ(nr.bts_nr, nr.trx_nr, 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);

		/* Send DATA.cnf back to the IUT (only needed for PCH) */
		if (pcu_msg.u.data_req.sapi == PCU_IF_SAPI_PCH) {
			f_pcuif_tx_data_cnf(pcu_msg);
		}

		setverdict(pass);
		}
	[] BTS.receive { repeat; }
	[] T.timeout {
		setverdict(fail, "Timeout waiting for Immediate Assignment");
		f_shutdown(__BFILE__, __LINE__);
		}
	}

	return rr_imm_ass;
}

/* One phase packet access (see 3GPP TS 44.018, table 9.1.8.1) */
const BIT8 chan_req_def := '01111000'B; /* 01111 { 0xx | x0x | xx0 } */
/* Single block (two phase or RR signalling) packet access */
const BIT8 chan_req_sb  := '01110000'B; /* 01110xxx */

/* Establish an Uplink TBF by sending RACH.ind towards the PCU */
function f_pcuif_tx_rach_rx_imm_ass(uint16_t ra := bit2int(chan_req_def),
				    uint8_t is_11bit := 0,
				    PCUIF_BurstType burst_type := BURST_TYPE_0,
				    TimingAdvance ta := 0,
				    template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum)
runs on MS_BTS_IFACE_CT return GsmRrMessage {
	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(nr.bts_nr, nr.trx_nr, ts_nr := 0,
				   ra := ra, is_11bit := is_11bit,
				   burst_type := burst_type,
				   fn := fn, arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
				   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 the same TS/TRX/BTS */
	return f_pcuif_rx_imm_ass(PCU_IF_SAPI_AGCH, tr_IMM_TBF_ASS(false, ra, fn), nr);
}

/* 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,
			     template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum)
runs on MS_BTS_IFACE_CT {
	var template RAW_PCU_EventParam ev_param := {tdma_fn := ? };
	BTS.send(ts_PCUIF_DATA_IND(nr.bts_nr, nr.trx_nr, nr.ts_nr, nr.blk_nr,
				   sapi := PCU_IF_SAPI_PDTCH, data := data,
				   fn := fn, arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
				   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 */
function f_pcuif_rx_data_req(out PCUIF_Message pcu_msg,
			     template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum)
runs on MS_BTS_IFACE_CT {
	BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
				  sapi := PCU_IF_SAPI_PDTCH, fn := 0,
				  arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)), block_nr := nr.blk_nr));
	BTS.receive(tr_PCUIF_DATA_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
				      sapi := PCU_IF_SAPI_PDTCH)) -> value pcu_msg;
}

/* Expect a Paging Request Type 1 from PCU on PCUIF on specified sapi.  */
function f_pcuif_rx_pch_pag_req1(template MobileIdentityV mi1 := ?,
				 template integer pag_group := ?,
				 template (present) TsTrxBtsNum nr := tr_TsTrxBtsNum)
runs on MS_BTS_IFACE_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(nr.bts_nr, nr.trx_nr, nr.ts_nr,
				      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;
}

function f_rx_rlcmac_dl_block(out RlcmacDlBlock dl_block, out uint32_t dl_fn,
			      template (present) CodingScheme exp_cs_mcs := ?,
			      template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum)
runs on MS_BTS_IFACE_CT {
	var PCUIF_Message pcu_msg;
	f_pcuif_rx_data_req(pcu_msg, nr := nr);
	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__);
	}
}

function f_rx_rlcmac_dl_block_exp_ack_nack(out RlcmacDlBlock dl_block, out uint32_t poll_fn,
					   template RlcmacDlBlock acknack_tmpl := (tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?),
										   tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?)),
					   template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum)
runs on MS_BTS_IFACE_CT {
	var uint32_t dl_fn;

	f_rx_rlcmac_dl_block(dl_block, dl_fn, nr := nr);
	if (match(dl_block, acknack_tmpl)) {
		poll_fn := f_rrbp_ack_fn(dl_fn, dl_block.ctrl.mac_hdr.rrbp);
		return;
	}
	setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
	f_shutdown(__BFILE__, __LINE__);
}

function f_rx_rlcmac_dl_block_exp_dummy(out RlcmacDlBlock dl_block,
					template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum)
runs on MS_BTS_IFACE_CT {
	var uint32_t dl_fn;

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

function f_rx_rlcmac_dl_block_exp_pkt_pag_req(out RlcmacDlBlock dl_block,
					      template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum)
runs on MS_BTS_IFACE_CT {
	var uint32_t dl_fn;

	f_rx_rlcmac_dl_block(dl_block, dl_fn, nr := nr);
	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 */
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 MS_BTS_IFACE_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__);
	}

	if (not match(data_block.cs, exp_cs)) {
		setverdict(fail, "Failed to match ", data_block.cs, " vs exp ", exp_cs);
		f_shutdown(__BFILE__, __LINE__);
	}
}

/* This function does what could probably be done with templates */
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 MS_BTS_IFACE_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__);
	}

	if (not match(data_block.mcs, exp_cs)) {
		setverdict(fail, "Failed to match ", data_block.mcs, " vs exp ", exp_cs);
		f_shutdown(__BFILE__, __LINE__);
	}
}

/* High level (task specific) helper for  matching GPRS/EGPRS data blocks */
function f_rlcmac_dl_block_exp_data(in RlcmacDlBlock dl_block,
				       template (present) octetstring data := ?,
				       template (present) uint7_t exp_bsn := ?,
				       template (present) CodingScheme exp_cs := ?)
runs on MS_BTS_IFACE_CT {
	/* 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__);
	}
}

/* High level (task specific) helper for receiving and matching GPRS/EGPRS data blocks */
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 := ?,
				       template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum)
runs on MS_BTS_IFACE_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, nr := nr);

	f_rlcmac_dl_block_exp_data(dl_block, data, exp_bsn, exp_cs);
}

function f_dl_block_ack_fn(in RlcmacDlBlock dl_block, uint32_t dl_fn)
runs on MS_BTS_IFACE_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 {
		rrbp_valid := dl_block.ctrl.mac_hdr.rrbp_valid;
		rrbp := dl_block.ctrl.mac_hdr.rrbp;
	}

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

/* Return true if a given Packet Paging Request contains the given IMSI, false otherwise */
function f_pkt_paging_match_imsi(in PacketPagingReq req, template hexstring imsi,
				 boolean cs_domain := true, boolean ps_domain := true)
runs on MS_BTS_IFACE_CT return boolean {
	if (not ispresent(req.repeated_pageinfo)) {
		setverdict(fail, "Packet Paging Request without MIs?!?");
		f_shutdown(__BFILE__, __LINE__);
	}

	for (var integer i := 0; i < lengthof(req.repeated_pageinfo); i := i + 1) {
		var PageInfo info := req.repeated_pageinfo[i].item;
		var MobileIdentityLV_Paging mi_lv;

		if (ischosen(info.cs)) { /* CS domain */
			if (not ispresent(info.cs.mobile_identity))
				{ continue; }
			if (not cs_domain)
				{ continue; }
			mi_lv := info.cs.mobile_identity;
		} else { /* PS domain */
			if (not ispresent(info.ps.mobile_identity))
				{ continue; }
			if (not ps_domain)
				{ continue; }
			mi_lv := info.ps.mobile_identity;
		}

		/* Make sure MI contains IMSI before referencing it */
		if (match(mi_lv.mobile_id, decmatch tr_MI_IMSI(imsi))) {
			return true;
		}
	}

	return false;
}

/* Return true if a given Packet Paging Request contains the given P-TMSI, false otherwise */
function f_pkt_paging_match_tmsi(in PacketPagingReq req, template GsmTmsi tmsi,
				 boolean cs_domain := true, boolean ps_domain := true)
runs on MS_BTS_IFACE_CT return boolean {
	if (not ispresent(req.repeated_pageinfo)) {
		setverdict(fail, "Packet Paging Request without MIs?!?");
		f_shutdown(__BFILE__, __LINE__);
	}

	for (var integer i := 0; i < lengthof(req.repeated_pageinfo); i := i + 1) {
		var PageInfo info := req.repeated_pageinfo[i].item;

		if (cs_domain and ischosen(info.cs)) {
			if (not ispresent(info.cs.tmsi))
				{ continue; }
			if (match(info.cs.tmsi, tmsi))
				{ return true; }
		} else if (ps_domain) {
			if (not ispresent(info.ps.ptmsi))
				{ continue; }
			if (match(info.ps.ptmsi, tmsi))
				{ return true; }
		}
	}

	return false;
}

}
