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

type union PacketDlAssignChan {
	PacketDlAssign		ccch,
	PacketDlAssignment	pacch
};

type record DlTbf {
	GsmRrMessage		rr_imm_ass,
	PacketDlAssignChan	ass,
	uint5_t			tfi,
	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,
	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 GprsMSArray;

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 := '00000001'O,
        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) UlTbf t_UlTbf_def := {
	rr_imm_ass := omit,
	ass := omit,
	tfi := 0,
	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;

	/* Support only 1 ms for now */
	var GprsMS g_ms[1];

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

function f_init_gprs_ms(template (value) GprsMS ms_params := t_GprsMS_def) runs on MS_BTS_IFACE_CT
{
	g_ms[0] := valueof(ms_params);
}


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

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

	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;
		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.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;
		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.usf[i] := dl_block.ctrl.payload.u.ul_assignment.egprs.dyn_block_alloc.ts_allocation.ts[i].usf_tn;
			}
		}
	}
	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;

	dl_tbf.rr_imm_ass := rr_imm_ass;
	dl_tbf.acknack_desc := valueof(t_AckNackDescription_init);

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

/* TODO: get stuff from f_rx_rlcmac_dl_block_exp_pkt_ass */
function f_dltbf_new_from_ass_pacch(RlcmacDlBlock dl_block)
runs on MS_BTS_IFACE_CT return DlTbf {
	var DlTbf dl_tbf;

	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 */
	dl_tbf.acknack_desc := valueof(t_AckNackDescription_init);
	return dl_tbf;
}

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_imm_ass_pacch(inout GprsMS ms, out uint32_t poll_fn, template RlcmacDlBlock t_imm_ass := ?)
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);
	if (not match(dl_block, t_imm_ass)) {
		setverdict(fail, "Failed to match Packet Assignment:", t_imm_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);
		/* TODO: match tlli from ms.dl_tbf.ass.pacch with ms.tlli), or error */
	} else {
		setverdict(fail, "Should not happen:", dl_block);
		f_shutdown(__BFILE__, __LINE__);
	}

	return dl_block;
}

function f_ms_establish_ul_tbf(inout GprsMS ms)
runs on MS_BTS_IFACE_CT {
	var GsmRrMessage rr_imm_ass;

	rr_imm_ass := f_establish_tbf(ms.ra, ms.ra_is_11bit, ms.burst_type, ms.ta);
	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, ?, ?))
runs on MS_BTS_IFACE_CT {
	var GsmRrMessage rr_imm_ass;

	rr_imm_ass := f_pcuif_rx_imm_ass(sapi, t_imm_ass);
	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)
runs on MS_BTS_IFACE_CT {
	f_pcuif_tx_data_ind(data, ms.lqual_cb, fn);
}

function f_ms_tx_ul_block(inout GprsMS ms, template (value) RlcmacUlBlock ul_data, uint32_t fn := 0)
runs on MS_BTS_IFACE_CT return integer {
	var octetstring data;
	var integer padding_len;
	/* Encode the payload of DATA.ind */
	data := enc_RlcmacUlBlock(valueof(ul_data));
	padding_len := 23 - lengthof(data);
	data := f_pad_oct(data, 23, '00'O); /* CS-1 */

	/* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
	f_ms_tx_data_ind(ms, data, fn);
	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)
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;
	}
	ms.ul_tbf.bsn := ms.ul_tbf.bsn + 1;
	ms.ul_tbf.bsn := ms.ul_tbf.bsn mod 128; /* FIXME: EGPRS SNS: 2048 */
	return f_ms_tx_ul_block(ms, ul_data, fn);

}

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

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

////////////////////////
// OLD APIs
////////////////////////

function f_pcuif_rx_imm_ass(template PCUIF_Sapi sapi := PCU_IF_SAPI_AGCH,
			    template GsmRrMessage t_imm_ass := ?)
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(bts_nr := 0, 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);

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

/* Establish an Uplink TBF by sending RACH.ind towards the PCU */
function f_establish_tbf(uint16_t ra := bit2int(chan_req_def),
			 uint8_t is_11bit := 0,
			 PCUIF_BurstType burst_type := BURST_TYPE_0,
			 TimingAdvance ta := 0)
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(bts_nr := 0, 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(PCU_IF_SAPI_AGCH, tr_IMM_TBF_ASS(false, ra, fn));
}

/* 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 MS_BTS_IFACE_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 */
function f_pcuif_rx_data_req(out PCUIF_Message pcu_msg)
runs on MS_BTS_IFACE_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 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 := ?)
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(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;
}

function f_rx_rlcmac_dl_block(out RlcmacDlBlock dl_block, out uint32_t dl_fn, template (present) CodingScheme exp_cs_mcs := ?)
runs on MS_BTS_IFACE_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__);
	}
}

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

	f_rx_rlcmac_dl_block(dl_block, dl_fn);
	if (match(dl_block, tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?)) or
	    match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
		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)
runs on MS_BTS_IFACE_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__);
	}
}

function f_rx_rlcmac_dl_block_exp_pkt_pag_req(out RlcmacDlBlock dl_block)
runs on MS_BTS_IFACE_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 */
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__);
	}

	/* TODO: check exp_cs */
}

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

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

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

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

function f_pkt_paging_match_tmsi(in PacketPagingReq req, template GsmTmsi tmsi)
runs on MS_BTS_IFACE_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__);
	}
}

}
