module PCU_Tests {

/* Osmocom PCU test suite in TTCN-3
 * (C) 2018-2019 Harald Welte <laforge@gnumonks.org>
 * 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_Gb_Types all;
import from BSSGP_Types all;
import from BSSGP_Emulation all;
import from NS_Types all;
import from NS_Emulation all;
import from LLC_Types all;
import from LLC_Templates all;
import from RLCMAC_Types all;
import from RLCMAC_CSN1_Types all;
import from LAPDm_RAW_PT all;
import from GPRS_Context all;
import from GPRS_TBF all;
import from L1CTL_PortType all;
import from MobileL3_Types all;
import from MobileL3_CommonIE_Types all;
import from L3_Templates all;

modulepar {
	BssgpConfig mp_gb_cfg := {
		nsei := 1234,
		bvci := 1234,
		cell_id := {
			ra_id := {
				lai := {
					mcc_mnc := '262F42'H, lac := 13135
				},
				rac := 0
			},
			cell_id := 20960
		},
		sgsn_role := true,
		depth := BSSGP_DECODE_DEPTH_BSSGP
	};

	NSConfiguration mp_nsconfig := {
		local_udp_port := 23000,
		local_ip := "127.0.0.1",
		remote_udp_port := 21000,
		remote_ip := "127.0.0.1",
		nsvci := 0,
		nsei := 2342,
		role_sgsn := true,
		handle_sns := true
	};
}

type component dummy_CT extends BSSGP_Client_CT {
	var lapdm_CT lapdm_component;
	port LAPDm_PT L1;

	var NS_CT ns_component;
	var BSSGP_CT bssgp_component;

	var MmContext g_mmctx := {
		tlli := 'FFFFFFFF'O,
		n_u := 0
	};

	var boolean g_initialized := false;
}

function f_init() runs on dummy_CT {
	if (g_initialized == true) {
		return;
	}
	g_initialized := true;
	/* create a new NS component */
	ns_component := NS_CT.create;
	bssgp_component := BSSGP_CT.create;
	/* connect our BSSGP port to the BSSGP Emulation */
	connect(self:BSSGP[0], bssgp_component:BSSGP_SP);
	connect(self:BSSGP_SIG[0], bssgp_component:BSSGP_SP_SIG);
	connect(self:BSSGP_PROC[0], bssgp_component:BSSGP_PROC);
	/* connect lower-end of BSSGP with BSSGP_CODEC_PORT (maps to NS_PT*/
	connect(bssgp_component:BSCP, ns_component:NS_SP);
	/* connect lower-end of NS emulation to NS_CODEC_PORT (on top of IPl4) */
	map(ns_component:NSCP, system:NS_CODEC_PORT);
	ns_component.start(NSStart(mp_nsconfig));
	bssgp_component.start(BssgpStart(mp_gb_cfg));

	lapdm_component := lapdm_CT.create;
	connect(self:L1, lapdm_component:LAPDM_SP);
	map(lapdm_component:L1CTL, system:L1CTL);
	lapdm_component.start(LAPDmStart());

	f_bssgp_client_register(g_mmctx.imsi, g_mmctx.tlli, mp_gb_cfg.cell_id);
	f_bssgp_establish();
}

function f_exit() runs on dummy_CT {
	lapdm_component.stop;
	ns_component.stop;
	bssgp_component.stop;
}

function f_bssgp_dec_and_log(in octetstring inp) {
	log("BSSGP Input: ", inp);
	var PDU_BSSGP dec := dec_PDU_BSSGP(inp);
	log("BSSGP Decoded: ", dec);
}

testcase TC_selftest_bssgp() runs on dummy_CT {
	const octetstring c_bvc_reset_pcu := '2204820000078108088832f44000c80051e0'O;
	const octetstring c_bvc_reset_q := '2204820000078100'O;
	const octetstring c_status_pcu := '4107810515882204820000078103'O;
	const octetstring c_reset_ack_q := '2304820000'O;
	const octetstring c_reset_ack_pcu := '23048200c4'O;
	const octetstring c_unblock_pcu := '24048200c4'O;
	const octetstring c_unblock_ack_q := '25048200c4'O;
	const octetstring c_fc_bvc_pcu := '261e8101058200fa038200c8018200fa1c8200c806820000'O;
	const octetstring c_fc_bvc_ack_q := '271e8101'O;
	const octetstring c_gmm_mo_att_req := '01bb146ddd000004088832f44000c80051e000800e003b01c001080103e5e000110a0005f4fb146ddd32f44000c8001d1b53432b37159ef9090070000dd9c6321200e00019b32c642401c0002017057bf0ec'O;
	const octetstring c_gmm_mt_ac_req := '00bb146ddd0050001682ffff0a8204030e9c41c001081200102198c72477ea104895e8b959acc58b108182f4d045'O;
	const octetstring c_gmm_mo_ac_resp := '01bb146ddd000004088832f44000c80051e000800e000e01c00508130122fa361f5fdd623d'O;
	const octetstring c_gmm_mt_att_acc := '00bb146ddd0050001682ffff0a8204030e9841c005080201340432f44000c8001805f4fb146ddd0967d0'O;
	const octetstring c_gmm_mt_det_req := '00bb146ddd0050001682ffff0a8204030e8941c00908050215f0b6'O;
	const octetstring c_gmm_mo_att_cpl := '01fb146ddd000004088832f44000c80051e000800e000801c009080339d7bc'O;

	f_bssgp_dec_and_log(c_bvc_reset_pcu);
	f_bssgp_dec_and_log(c_bvc_reset_q);
	f_bssgp_dec_and_log(c_status_pcu);
	f_bssgp_dec_and_log(c_reset_ack_q);
	f_bssgp_dec_and_log(c_reset_ack_pcu);
	f_bssgp_dec_and_log(c_unblock_pcu);
	f_bssgp_dec_and_log(c_unblock_ack_q);
	f_bssgp_dec_and_log(c_fc_bvc_pcu);
	f_bssgp_dec_and_log(c_fc_bvc_ack_q);
	f_bssgp_dec_and_log(c_gmm_mo_att_req);
	f_bssgp_dec_and_log(c_gmm_mt_ac_req);
	f_bssgp_dec_and_log(c_gmm_mo_ac_resp);
	f_bssgp_dec_and_log(c_gmm_mt_att_acc);
	f_bssgp_dec_and_log(c_gmm_mt_det_req);
	f_bssgp_dec_and_log(c_gmm_mo_att_cpl);

	log(ts_BSSGP_PS_PAGING_IMSI(196, '262420123456789'H));
}

function f_ns_assert_prepr(in octetstring a, in octetstring b) {
	log("NS Input: ", a);
	log("NS Expected: ", b);

	if (a != b) {
		setverdict(fail, "Values mismatch", a, b);
		mtc.stop;
	} else {
		setverdict(pass);
	}
}

function f_ns_dec_and_log(in octetstring inp) {
	log("NS Input: ", inp);
	var PDU_NS dec := dec_PDU_NS(inp);
	log("NS Decoded: ", dec);
}

testcase TC_selftest_ns() runs on dummy_CT {
	const octetstring c_ns_reset_pcu := '000000c4271e813d'O;

	/* single byte length to two byte length */
	f_ns_assert_prepr('04058101'O, '0405000101'O);
	f_ns_assert_prepr('040589000102030405060708'O, '04050009000102030405060708'O);
	/* two byte length to two byte length */
	f_ns_assert_prepr('0405000101'O, '0405000101'O);
	/* special case: NS-UNITDATA */
	f_ns_assert_prepr('00aabbccddeeffaa29822342'O, '00aabbccddeeffaa2900022342'O);
	/* multiple TLVs */
	f_ns_assert_prepr('234281aa4382bbbb'O, '23420001aa430002bbbb'O);
	/* zero-length */
	f_ns_assert_prepr('230080'O, '23000000'O);

	f_ns_dec_and_log(c_ns_reset_pcu);
}

const octetstring gmm_auth_req := '081200102198c72477ea104895e8b959acc58b108182'O;

/* Wrap downlink GMM into LLC, encode + send it via BSSGP to PCU */
function tx_gmm(BIT1 c_r, in octetstring gmm_pdu, BIT4 sapi := c_LLC_SAPI_LLGMM) runs on dummy_CT {
	var PDU_LLC llc;

	//log("GMM Tx: ", dec_PDU_L3_SGSN_MS(gmm_pdu));

	log(c_r, g_mmctx.n_u, gmm_pdu, sapi);
	llc := valueof(ts_LLC_UI(gmm_pdu, sapi, c_r, g_mmctx.n_u));
	log(llc);
	g_mmctx.n_u := g_mmctx.n_u + 1;

	log(ts_BSSGP_DL_UD(g_mmctx.tlli, enc_PDU_LLC(llc)));

	BSSGP[0].send(ts_BSSGP_DL_UD(g_mmctx.tlli, enc_PDU_LLC(llc)));
}

/* Establish BSSGP connection to PCU */
function f_bssgp_establish() runs on BSSGP_Client_CT {
	timer T:= 10.0;

	T.start
	alt {
	[] BSSGP[0].receive(t_BssgpStsInd(?, ?, BVC_S_UNBLOCKED)) { }
	[] BSSGP[0].receive { repeat; }
	[] T.timeout {
		setverdict(fail, "Timeout establishing BSSGP connection");
		mtc.stop;
		}
	}
	T.stop
	log("BSSGP successfully initialized");
}

function f_wait_paging_req_type1(hexstring expected_tmsi) runs on dummy_CT {
	var LAPDm_ph_data ph_data;
	timer T := 5.0;

	T.start;
	alt {
	[] L1.receive(LAPDm_ph_data:{sacch:=?,sapi:=0,lapdm:={bbis:=?}}) -> value ph_data {
		var octetstring payload := substr(ph_data.lapdm.bbis.payload, 1, lengthof(ph_data.lapdm.bbis.payload) - 1);
		var PDU_ML3_NW_MS pdu;

		if (dec_PDU_ML3_NW_MS_backtrack(payload, pdu) != 0) {
			repeat;
		}

		if (not ischosen(pdu.msgs.rrm)) {
			repeat;
		}

		if (match(pdu, tr_PAGING_REQ1(tr_PAGING_REQ1_MI1_TMSI(hex2oct(expected_tmsi))))) {
			setverdict(pass);
		} else {
			repeat;
		}
	}
	[] L1.receive { repeat; }
	[] T.timeout { setverdict(fail); }
	}
}

/* Send PS-PAGING via BSSGP to PCU, expect it to show up on L1/Um */
testcase TC_paging() runs on dummy_CT {
	var hexstring tmsi_hex := '01234567'H;
	var GsmTmsi tmsi := hex2int(tmsi_hex);

	g_mmctx.imsi := '262420123456789'H;
	g_mmctx.tlli := f_random_tlli();
	f_init();

	var BCCH_tune_req tune_req := { { false, 871 }, true };
	L1.send(tune_req);
	/* FIXME: wait for confirm */

	/* Send paging on signalling BVCI 0 since osmo-pcu does not support paging on PTP yet. */
	/*
	TODO: Paging by IMSI does not work yet because osmo-pcu does not copy IMSI into paging requests.
	BSSGP_SIG[0].send(ts_BSSGP_PS_PAGING_IMSI(0, g_mmctx.imsi));
	f_wait_paging_req_type1(hex2oct(g_mmctx.imsi));
	*/

	/* Page by TMSI */
	BSSGP_SIG[0].send(ts_BSSGP_PS_PAGING_PTMSI(0, g_mmctx.imsi, tmsi));
	f_wait_paging_req_type1(tmsi_hex);
}

/* Establish an UL TBF: Tune to ARFCN, send RACH, receive AGCH, enable TBF Rx */
function f_establish_ul_tbf() runs on dummy_CT {
	timer T := 5.0;
	var BCCH_tune_req tune_req := { { false, 871 }, true };
	L1.send(tune_req);
	/* FIXME: wait for confirm */

	var TBF_UL_establish_req est_req := { tbf_nr := 0, ra := hex2int('7B'H) };
	L1.send(est_req);
	T.start;
	/* FIXME: wait for confirm */
	alt {
	[] L1.receive(TBF_UL_establish_res:?) {}
	[] L1.receive { repeat; }
	[] T.timeout {
		setverdict(fail, "Timeout establishing UL TBF");
		mtc.stop;
		}
	}
	T.stop;
}

/* compute a random TLLI; FIXME: what about TLLI prefix / local/foreign/...? */
function f_random_tlli() return GprsTlli {
	var GprsTlli tlli := f_rnd_octstring(4);
	return tlli;
}

/* Compute the frame number of the uplink block based on current fn + rrbp */
function f_rrbp_fn(GsmFrameNumber fn, MacRrbp rrbp) return GsmFrameNumber {
	var integer add;
	select (rrbp) {
	case (RRBP_Nplus13_mod_2715648) {
		add := 13;
		}
	case (RRBP_Nplus17_or_18_mod_2715648) {
		add := 17; /* FIXME: What about 'or 18'? */
		}
	case (RRBP_Nplus21_or_22_mod_2715648) {
		add := 21; /* FIXME: What about 'or 22'? */
		}
	case (RRBP_Nplus26_mod_2715648) {
		add := 26;
		}
	}
	return (fn + add) mod 2715648;
}


function f_bssgp_wait_ul_ud(template PDU_BSSGP exp) runs on dummy_CT {
	timer T := 5.0;
	T.start;
	alt {
	[] BSSGP[0].receive(exp) {
		log("found matching BSSGP UL-UNITDATA PDU");
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for ", exp);
		mtc.stop;
		}
	}
}


function f_ul_tbf(inout UlTbfState us) runs on dummy_CT {
	var RLCMAC_ph_data_ind dl;

	/* Establish an UL-TBF */
	f_establish_ul_tbf();

	while (true) {
		var RlcmacUlBlock blk;
		if (f_ul_tbf_get_next_block(blk, us, g_mmctx, true) == false) {
			break;
		}

		/* Send the block to L1 for transmission */
		log("L1=", blk);
		L1.send(RLCMAC_ph_data_req:{dyn:={tbf_id := 0, cs := us.tbf.initial_cs, block := blk}});
	}

	alt {
	[] L1.receive(RLCMAC_ph_data_ind:{cs:=?, ts_nr:=?, fn:=?, block:=tr_RLCMAC_ACK_NACK(0, g_mmctx.tlli)}) -> value dl {
		log("found matching ACK/NACK");
		/* send CTRL ACK in uplink */
		var GsmFrameNumber ul_fn := f_rrbp_fn(dl.fn, dl.block.ctrl.mac_hdr.rrbp);
		var RlcmacUlCtrlMsg ctrl_ack := valueof(ts_RlcMacUlCtrl_PKT_CTRL_ACK(g_mmctx.tlli));
		var RlcmacUlBlock ul_block := valueof(ts_RLC_UL_CTRL_ACK(ctrl_ack));
		L1.send(ts_PH_DATA_ABS(0, CS1, dl.ts_nr, ul_fn, {false, 871}, ul_block));
		/* wait for the final ACK */
		if (dl.block.ctrl.payload.u.ul_ack_nack.gprs.ack_nack_desc.final_ack == '0'B) {
			repeat;
		}
		}
	[] L1.receive { repeat; }
	}

	for (var integer i := 0; i < sizeof(us.tbf.llc_pdus_enc); i := i+1) {
		f_bssgp_wait_ul_ud(tr_BSSGP_UL_UD(g_mmctx.tlli, ?, us.tbf.llc_pdus_enc[i]));
	}
	setverdict(pass);

	L1.send(DCCH_release_req:{});
}

testcase TC_rach() runs on dummy_CT {
	var BssgpBvci bvci := 196;
	g_mmctx.imsi := '262420123456789'H;
	g_mmctx.tlli := f_random_tlli();

	f_init();

	f_bssgp_client_register(g_mmctx.imsi, g_mmctx.tlli, mp_gb_cfg.cell_id);

	f_bssgp_establish();
}



function f_llc_dec_and_log(in octetstring inp) {
	log("LLC Input: ", inp);
	var PDU_LLC dec := dec_PDU_LLC(inp);
	log("LLC Decoded: ", dec);
}

function f_llc_assert(in octetstring a, in octetstring b) {
	log("LLC Input: ", a);
	log("LLC Expected: ", b);

	if (a != b) {
		setverdict(fail, "LLC input ", b, " != expected ", a);
		mtc.stop;
	} else {
		setverdict(pass);
	}
}


testcase TC_selftest_llc() runs on dummy_CT {
	const octetstring c_gmm_att_pcu := '01c001080103e5e000210a0005f4fb146ddd32f44000c8001d1b53432b37159ef9090070000dd9c6321200e00019b32c642401c00020170580460b'O;
	const octetstring c_gmm_att_pcu_nofcs := '01c001080103e5e000210a0005f4fb146ddd32f44000c8001d1b53432b37159ef9090070000dd9c6321200e00019b32c642401c000201705'O;

	f_llc_dec_and_log(c_gmm_att_pcu);

	//f_llc_assert(f_LLC_append_fcs(c_gmm_att_pcu_nofcs), c_gmm_att_pcu);

	log(valueof(ts_LLC_UI(gmm_auth_req, c_LLC_SAPI_LLGMM, LLC_CR_DL_CMD, g_mmctx.n_u)));
	log(ts_LLC_UI(gmm_auth_req, c_LLC_SAPI_LLGMM, LLC_CR_DL_CMD, g_mmctx.n_u));
}

testcase TC_selftest_rlcmac() runs on dummy_CT {
	var RlcmacDlCtrlBlock dcb;
	var RlcmacUlCtrlBlock ucb;
	const octetstring c_dl_ul_ack_nack := '40240080400000000000000077628dbba14b2b2b2b2b2b'O;
	const octetstring c_dl_data := '0f00007341c001081200102198c72477ea104895e8b959acc58b108182f4d0454300'O;
	const octetstring c_dl_data2 := '070002165dc0012b2b2b43c0012b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b00'O;
	const octetstring c_ul_ctrl_ack := '4006ec51b7772b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b'O;
	const octetstring c_ul_dl_ack_nack := '4008004000000000000000701000edc0000b2b2b2b2b2b'O;
	const octetstring c_dl_ul_assign := '482857628dbbaf0126e68800082b2b2b2b2b2b2b2b2b2b'O;

	log(c_dl_ul_ack_nack);
	dcb := dec_RlcmacDlCtrlBlock(c_dl_ul_ack_nack);
	log(dcb);
	//log(dec_RlcmacDlCtrlMsg(dcb.payload));

	f_rlcmac_dld_decenc(c_dl_data);

	f_rlcmac_dld_decenc(c_dl_data2);

	log(c_ul_ctrl_ack);
	ucb := dec_RlcmacUlCtrlBlock(c_ul_ctrl_ack);
	log(ucb);
	//log(dec_RlcmacUlCtrlMsg(ucb.payload));

	log(c_ul_dl_ack_nack);
	ucb := dec_RlcmacUlCtrlBlock(c_ul_dl_ack_nack);
	log(ucb);
	//log(dec_RlcmacUlCtrlMsg(ucb.payload));

	log(c_dl_ul_assign);
	dcb := dec_RlcmacDlCtrlBlock(c_dl_ul_assign);
	log(dcb);
	//log(dec_RlcmacDlCtrlMsg(dcb.payload));

	const octetstring c_uld_tlli_noext := '080101a61cab5201c001080103e5e000310a0005f4e61cab5232f44000c8001d1b00'O;
	f_rlcmac_uld_decenc(c_uld_tlli_noext);

	const octetstring c_uld_tlli_ext7pad := '0001041da61cab5200201705a96e102b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b00'O;
	log("ULD_decenc");
	f_rlcmac_uld_decenc(c_uld_tlli_ext7pad);
	log("UL_decenc");
	f_rlcmac_ul_decenc(c_uld_tlli_ext7pad);

	f_rlcmac_ul_decenc(c_ul_dl_ack_nack);
}

function f_rlcmac_ul_decenc(in octetstring buf) {
	log("==================================");
	log("In: ", buf);
	var RlcmacUlBlock udb := dec_RlcmacUlBlock(buf);
	log("Dec: ", udb);
	var octetstring enc := enc_RlcmacUlBlock(udb);
	log("Enc: ", enc);
	if (enc != buf) {
		setverdict(fail, "Re-encoded data doesn't equal input data");
		mtc.stop;
	}
}

function f_rlcmac_uld_decenc(in octetstring buf) {
	log("==================================");
	log("In: ", buf);
	var RlcmacUlDataBlock udb := dec_RlcmacUlDataBlock(buf);
	log("Dec: ", udb);
	var octetstring enc := enc_RlcmacUlDataBlock(udb);
	log("Enc: ", enc);
	if (enc != buf) {
		setverdict(fail, "Re-encoded data doesn't equal input data");
		mtc.stop;
	}
}

function f_rlcmac_dld_decenc(in octetstring buf) {
	log("==================================");
	log("In: ", buf);
	var RlcmacDlDataBlock udb := dec_RlcmacDlDataBlock(buf);
	log("Dec: ", udb);
	var octetstring enc := enc_RlcmacDlDataBlock(udb);
	log("Enc: ", enc);
	if (enc != buf) {
		setverdict(fail, "Re-encoded data doesn't equal input data");
		mtc.stop;
	}
}


testcase TC_selftest_rr() runs on dummy_CT {
	//const octetstring c_paging_none := '06210001F02B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B'O
	const octetstring c_paging_none := '1506210001F0'O;
	const octetstring c_ia_tbf := '2d063f100fe3677bd8440000c800100b2b2b2b2b2b2b2b'O
	log(c_paging_none);
	log(dec_GsmRrMessage(c_paging_none));

	log(c_ia_tbf);
	log(dec_GsmRrMessage(c_ia_tbf));
}

function f_seq_octstr(integer len) return octetstring {
	var octetstring payload := ''O;
	for (var integer i := 0; i < len; i := i+1 ) {
		payload := payload & int2oct(i mod 256, 1);
	}
	return payload;
}

testcase TC_ul_tbf_single_llc_sizes() runs on dummy_CT {
	g_mmctx.imsi := '262420123456789'H;
	g_mmctx.tlli := f_random_tlli();
	f_init();

	for (var integer len := 1; len <= 1560; len := len+1) {
		log("Testing Uplink TBF with single LLC-PDU of ", len, " bytes");
		var octetstring payload := f_seq_octstr(len);
		var UlTbfPars ul_tbf_pars := {
			ack_mode := true,
			initial_cs := CS1,
			llc_pdus := {
				valueof(ts_LLC_UI(payload, c_LLC_SAPI_LLGMM, '0'B, g_mmctx.n_u))
			}
		}
		var UlTbfState ul_tbf_state;
		f_UlTbfState_init(ul_tbf_state, ul_tbf_pars);
		f_ul_tbf(ul_tbf_state);
		f_sleep(1.0);
	}

	f_exit();
}

testcase TC_ul_tbf() runs on dummy_CT {
	g_mmctx.imsi := '262420123456789'H;
	g_mmctx.tlli := f_random_tlli();
	f_init();

	var octetstring payload := f_seq_octstr(1023);
	var UlTbfPars ul_tbf_pars := {
		ack_mode := true,
		initial_cs := CS1,
		llc_pdus := { 
			valueof(ts_LLC_UI(payload, c_LLC_SAPI_LLGMM, '0'B, g_mmctx.n_u)),
			valueof(ts_LLC_UI(payload, c_LLC_SAPI_LLGMM, '0'B, g_mmctx.n_u+1)),
			valueof(ts_LLC_UI(payload, c_LLC_SAPI_LLGMM, '0'B, g_mmctx.n_u+2)),
			valueof(ts_LLC_UI(payload, c_LLC_SAPI_LLGMM, '0'B, g_mmctx.n_u+3)),
			valueof(ts_LLC_UI(payload, c_LLC_SAPI_LLGMM, '0'B, g_mmctx.n_u+4)),
			valueof(ts_LLC_UI(payload, c_LLC_SAPI_LLGMM, '0'B, g_mmctx.n_u+5))
		}
	};
	var UlTbfState ul_tbf_state;
	f_UlTbfState_init(ul_tbf_state, ul_tbf_pars);
	f_ul_tbf(ul_tbf_state);

	f_exit();
}

testcase TC_dl_tbf() runs on dummy_CT {
	g_mmctx.imsi := '262420123456789'H;
	g_mmctx.tlli := f_random_tlli();
	f_init();

	f_establish_dl_tbf();

	f_exit();
}

function f_wait_tbf_dl(TbfNr tbf_nr, GprsTlli tlli) runs on dummy_CT return ImmediateAssignment {
	var LAPDm_ph_data ph_data;
	var GsmRrMessage rr;
	timer T := 10.0;
	T.start;
	alt {
	[] L1.receive(LAPDm_ph_data:{sacch:=?,sapi:=0,lapdm:={bbis:=?}}) -> value ph_data {
		rr := dec_GsmRrMessage(ph_data.lapdm.bbis.payload);
		log("PCH/AGCH DL RR: ", rr);
		if (match(rr, t_RR_IMM_ASS_TBF_DL(tlli))) {
			var TbfPars tbf_pars := valueof(t_TbfParsInit);
			log("Received IMM.ASS for our TLLI!");
			tbf_pars.tfi[rr.payload.imm_ass.pkt_chan_desc.tn] :=
				rr.payload.imm_ass.rest_octets.hh.pa.uldl.ass.dl.group1.tfi_assignment;
			L1.send(TBF_DL_establish_req:{tbf_nr, tbf_pars});
		} else {
			repeat;
		}
	}
	[] L1.receive { repeat };
	[] T.timeout {
		setverdict(fail, "Timeout waiting for IMM ASS")
		mtc.stop;
		}
	}
	T.stop;
	return rr.payload.imm_ass;
}

/* Establish an UL TBF: Tune to ARFCN, send RACH, receive AGCH, enable TBF Rx */
function f_establish_dl_tbf() runs on dummy_CT {
	timer T := 5.0;
	var BCCH_tune_req tune_req := { { false, 871 }, true };
	L1.send(tune_req);
	/* FIXME: wait for confirm */

	/* sending a GMM PDU as DL-UNITDATA should trigger Paging + DL TBF Assignment */
	tx_gmm('1'B, '01020304'O, c_LLC_SAPI_LLGMM);

	/* Expect an IMM.ASS for PDCH on the AGCH */
	f_wait_tbf_dl(0, g_mmctx.tlli);

	var RLCMAC_ph_data_ind dl;
	alt {
	[] L1.receive(RLCMAC_ph_data_ind:{cs:=?, ts_nr:=?, fn:=?, block:=tr_RLCMAC_DATA_RRBP}) -> value dl {
		var uint6_t tfi := dl.block.data.mac_hdr.hdr_ext.tfi;
		var GsmFrameNumber ul_fn := f_rrbp_fn(dl.fn, dl.block.data.mac_hdr.mac_hdr.rrbp);
		var AckNackDescription an_desc := { /* FIXME: compute this based on state */
			final_ack := '1'B,
			starting_seq_nr := 0,
			receive_block_bitmap := '0000000000000000000000000000000000000000000000000000000000000001'B
		}
		var RlcmacUlCtrlMsg ctrl_ack;
		ctrl_ack := valueof(ts_RlcMacUlCtrl_PKT_DL_ACK(tfi, an_desc));
		var RlcmacUlBlock ul_block := valueof(ts_RLC_UL_CTRL_ACK(ctrl_ack));
		L1.send(ts_PH_DATA_ABS(0, CS1, dl.ts_nr, ul_fn, {false, 871}, ul_block));
		log("Sent DL ACK: ", ul_block);
		}
	[] L1.receive { repeat; }
	}

	f_sleep(10.0);
}

/* FIXME: merge this into BSSGP_Client_CT ? */
type component bssgp_CT extends BSSGP_Client_CT {
	var NS_CT ns_component;
	var BSSGP_CT bssgp_component;
	var boolean g_initialized := false;
}

/* FIXME: merge this into BSSGP_Client_CT ? */
function f_init_bssgp() runs on bssgp_CT {
	var MmContext mmctx := {
		imsi := '262420000000001'H,
		tlli := 'FFFFFFFF'O,
		n_u := 0
	};


	if (g_initialized == true) {
		return;
	}
	g_initialized := true;

	/* create a new NS component */
	ns_component := NS_CT.create;
	bssgp_component := BSSGP_CT.create;
	/* connect our BSSGP port to the BSSGP Emulation */
	connect(self:BSSGP[0], bssgp_component:BSSGP_SP);
	connect(self:BSSGP_SIG[0], bssgp_component:BSSGP_SP_SIG);
	connect(self:BSSGP_PROC[0], bssgp_component:BSSGP_PROC);
	/* connect lower-end of BSSGP with BSSGP_CODEC_PORT (maps to NS_PT*/
	connect(bssgp_component:BSCP, ns_component:NS_SP);
	/* connect lower-end of NS emulation to NS_CODEC_PORT (on top of IPl4) */
	map(ns_component:NSCP, system:NS_CODEC_PORT);
	ns_component.start(NSStart(mp_nsconfig));
	bssgp_component.start(BssgpStart(mp_gb_cfg));

	f_bssgp_client_register(mmctx.imsi, mmctx.tlli, mp_gb_cfg.cell_id);
	f_bssgp_establish();
}



control {
	execute(TC_selftest_ns());
	execute(TC_ul_tbf_single_llc_sizes());
	execute(TC_ul_tbf());
	execute(TC_paging());
}

};
