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_pcuif_tx_rach_rx_imm_ass(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_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)
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__);
	}
}

}
