module GBProxy_Tests {

/* Osmocom GBProxy test suite in TTCN-3
 * (C) 2020 sysmocom - s.f.m.c. GmbH
 * All rights reserved.
 *
 * Author: Daniel Willmann <dwillmann@sysmocom.de>

 * 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 Native_Functions all;
import from NS_Types all;
import from NS_Emulation all;
import from BSSGP_Types all;
import from BSSGP_Emulation all;
import from SCCPasp_Types all;
import from Osmocom_Gb_Types all;

import from MobileL3_CommonIE_Types all;
import from MobileL3_GMM_SM_Types all;
import from MobileL3_Types all;
import from L3_Templates all;
import from L3_Common all;

import from TELNETasp_PortType all;
import from Osmocom_VTY_Functions all;

import from LLC_Types all;
import from LLC_Templates all;

import from GSM_RR_Types all;

/* mcc_mnc is 24.008 10.5.5.15 encoded. 262 42 */
const BcdMccMnc c_mcc_mnc := '262F42'H;

modulepar {
	/* IP/port on which we run our internal GSUP/HLR emulation */
	NSConfigurations mp_nsconfig_sgsn := {
		{
			nsei := 101,
			role_sgsn := true,
			handle_sns := false,
			nsvc := {
				{
					provider := {
						ip := {
							address_family := AF_INET,
							local_udp_port := 7777,
							local_ip := "127.0.0.1",
							remote_udp_port := 23000,
							remote_ip := "127.0.0.1"
						}
					},
					nsvci := 101
				}
			}
		}
	};
	NSConfigurations mp_nsconfig_pcu := {
		{
			nsei := 96,
			role_sgsn := false,
			handle_sns := false,
			nsvc := {
				{
					provider := {
						ip := {
							address_family := AF_INET,
							local_udp_port := 21010,
							local_ip := "127.0.0.1",
							remote_udp_port := 23000,
							remote_ip := "127.0.0.1"
						}
					},
					nsvci := 97
				}
			}
		},
		{
			nsei := 97,
			role_sgsn := false,
			handle_sns := false,
			nsvc := {
				{
					provider := {
						ip := {
							address_family := AF_INET,
							local_udp_port := 21011,
							local_ip := "127.0.0.1",
							remote_udp_port := 23000,
							remote_ip := "127.0.0.1"
						}
					},
					nsvci := 98
				}
			}
		},
		{
			nsei := 98,
			role_sgsn := false,
			handle_sns := false,
			nsvc := {
				{
					provider := {
						ip := {
							address_family := AF_INET,
							local_udp_port := 21012,
							local_ip := "127.0.0.1",
							remote_udp_port := 23000,
							remote_ip := "127.0.0.1"
						}
					},
					nsvci := 99
				}
			}
		}
	};
	BssgpConfigs mp_gbconfigs := {
		{
			nsei := 96,
			sgsn_role := false,
			bvc := {
				{
					bvci := 196,
					cell_id := {
						ra_id := {
							lai := {
								mcc_mnc := c_mcc_mnc,
								lac := 13135
							},
							rac := 0
						},
						cell_id := 20960
					},
					depth := BSSGP_DECODE_DEPTH_BSSGP,
					create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
				}
			}
		}, {
			nsei := 97,
			sgsn_role := false,
			bvc := {
				{
					bvci := 210,
					cell_id := {
						ra_id := {
							lai := {
								mcc_mnc := c_mcc_mnc,
								lac := 13200
							},
							rac := 0
						},
						cell_id := 20961
					},
					depth := BSSGP_DECODE_DEPTH_BSSGP,
					create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
				}
			}
		}, {
			nsei := 98,
			sgsn_role := false,
			bvc := {
				{
					bvci := 220,
					cell_id := {
						ra_id := {
							lai := {
								mcc_mnc := c_mcc_mnc,
								lac := 13300
							},
							rac := 0
						},
						cell_id := 20962
					},
					depth := BSSGP_DECODE_DEPTH_BSSGP,
					create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
				}
			}
		}
	}
};

type record GbInstance {
	NS_CT vc_NS,
	BSSGP_CT vc_BSSGP,
	BSSGP_BVC_CTs vc_BSSGP_BVC,
	BssgpConfig cfg
};
type record of BSSGP_BVC_CT BSSGP_BVC_CTs

const integer NUM_PCU := 3;
type record of GbInstance GbInstances;
type record of BssgpConfig BssgpConfigs;
type record of NSConfiguration NSConfigurations;
type record of BssgpCellId BssgpCellIds;

const integer NUM_SGSN := 1;

type component test_CT {
	var GbInstances g_pcu;
	var GbInstances g_sgsn;

	port BSSGP_CT_PROC_PT PROC;

	port BSSGP_BVC_MGMT_PT SGSN_MGMT;
	port BSSGP_BVC_MGMT_PT PCU_MGMT;

	port TELNETasp_PT GBPVTY;

	var boolean g_initialized := false;
	var boolean g_use_echo := false;
};

type component BSSGP_ConnHdlr {
	/* array of per-BVC ports on the PCU side */
	port BSSGP_PT PCU[NUM_PCU];
	port BSSGP_PT PCU_SIG[NUM_PCU];
	port BSSGP_PROC_PT PCU_PROC[NUM_PCU];
	/* component reference to the component to which we're currently connected */
	var BSSGP_BVC_CT pcu_ct[NUM_PCU];

	/* array of per-BVC ports on the SGSN side */
	port BSSGP_PT SGSN[NUM_SGSN];
	port BSSGP_PT SGSN_SIG[NUM_SGSN];
	port BSSGP_PROC_PT SGSN_PROC[NUM_SGSN];
	/* component reference to the component to which we're currently connected */
	var BSSGP_BVC_CT sgsn_ct[NUM_PCU];

	var BSSGP_ConnHdlrPars g_pars;
	timer g_Tguard;
	var LLC_Entities llc;
}

type record SGSN_ConnHdlrNetworkPars {
	boolean expect_ptmsi,
	boolean expect_auth,
	boolean expect_ciph
};

type record BSSGP_ConnHdlrPars {
	/* IMEI of the simulated ME */
	hexstring imei,
	/* IMSI of the simulated MS */
	hexstring imsi,
	/* MSISDN of the simulated MS (probably unused) */
	hexstring msisdn,
	/* P-TMSI allocated to the simulated MS */
	OCT4 p_tmsi optional,
	OCT3 p_tmsi_sig optional,
	/* TLLI of the simulated MS */
	OCT4 tlli,
	OCT4 tlli_old optional,
	RoutingAreaIdentificationV ra optional,
	GbInstances pcu,
	GbInstances sgsn,
	float t_guard
};

private function f_cellid_to_RAI(in BssgpCellId cell_id) return RoutingAreaIdentificationV {
	/* mcc_mnc is encoded as of 24.008 10.5.5.15 */
	var BcdMccMnc mcc_mnc := cell_id.ra_id.lai.mcc_mnc;

        var RoutingAreaIdentificationV ret := {
                mccDigit1 := mcc_mnc[0],
                mccDigit2 := mcc_mnc[1],
                mccDigit3 := mcc_mnc[2],
                mncDigit3 := mcc_mnc[3],
                mncDigit1 := mcc_mnc[4],
                mncDigit2 := mcc_mnc[5],
                lac := int2oct(cell_id.ra_id.lai.lac, 16),
                rac := int2oct(cell_id.ra_id.rac, 8)
        }
        return ret;
};

private function f_init_gb_pcu(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
	var charstring ns_id := id & "-NS(PCU[" & int2str(offset) & "])";
	var charstring bssgp_id := id & "-BSSGP(PCU[" & int2str(offset) & "])";
	gb.vc_NS := NS_CT.create(ns_id);
	gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
	/* connect lower end of BSSGP emulation with NS upper port */
	connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);

	gb.vc_NS.start(NSStart(mp_nsconfig_pcu[offset], ns_id));
	gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));

	for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
		connect(self:PROC, gb.vc_BSSGP:PROC);
		gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
		disconnect(self:PROC, gb.vc_BSSGP:PROC);
		connect(self:PCU_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
	}
}

private function f_init_gb_sgsn(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
	var charstring ns_id := id & "-NS(SGSN[" & int2str(offset) & "])";
	var charstring bssgp_id := id & "-BSSGP(SGSN[" & int2str(offset) & "])";
	gb.vc_NS := NS_CT.create(ns_id);
	gb.vc_BSSGP := BSSGP_CT.create(bssgp_id);
	/* connect lower end of BSSGP emulation with NS upper port */
	connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);

	gb.vc_NS.start(NSStart(mp_nsconfig_sgsn[offset], ns_id));
	gb.vc_BSSGP.start(BssgpStart(gb.cfg, bssgp_id));

	for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i + 1) {
		connect(self:PROC, gb.vc_BSSGP:PROC);
		gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
		disconnect(self:PROC, gb.vc_BSSGP:PROC);
		connect(self:SGSN_MGMT, gb.vc_BSSGP_BVC[i]:MGMT);
	}
}


private function f_init_vty() runs on test_CT {
	map(self:GBPVTY, system:GBPVTY);
	f_vty_set_prompts(GBPVTY);
	f_vty_transceive(GBPVTY, "enable");
}

type record of integer ro_integer;

private function ro_integer_contains(ro_integer r, integer x) return boolean {
	for (var integer j := 0; j < lengthof(r); j := j+1) {
		if (r[j] == x) {
			return true;
		}
	}
	return false;
}

function f_init() runs on test_CT {
	var ro_integer bvci_unblocked := {};
	var BssgpStatusIndication bsi;
	var integer i;

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

	g_sgsn[0].cfg := {
		nsei := mp_nsconfig_sgsn[0].nsei,
		sgsn_role := true,
		bvc := { }
	}
	for (i := 0; i < lengthof(mp_gbconfigs); i := i+1) {
		g_pcu[i].cfg := mp_gbconfigs[i];
		/* concatenate all the PCU-side BVCs for the SGSN side */
		g_sgsn[0].cfg.bvc := g_sgsn[0].cfg.bvc & mp_gbconfigs[i].bvc;
	}

	f_init_vty();
	for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
		f_init_gb_sgsn(g_sgsn[i], "GbProxy_Test", i);
	}
	f_sleep(4.0);
	for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
		f_init_gb_pcu(g_pcu[i], "GbProxy_Test", i);
	}

	/* wait until all BVC are unblocked on both sides */
	timer T := 5.0;
	T.start;
	alt {
	[] SGSN_MGMT.receive(BssgpStatusIndication:{*, ?, BVC_S_UNBLOCKED}) -> value bsi {
		bvci_unblocked := bvci_unblocked & { bsi.bvci };
		if (lengthof(bvci_unblocked) != lengthof(g_sgsn[0].cfg.bvc)) {
			repeat;
			}
		}
	[] SGSN_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
		repeat;
		}
	[] SGSN_MGMT.receive {
		setverdict(fail, "Received unexpected message on SGSN_MGMT");
		mtc.stop;
		}

	[] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, BVC_S_UNBLOCKED}) -> value bsi {
		repeat;
		}
	[] PCU_MGMT.receive(BssgpStatusIndication:{*, ?, ?}) {
		repeat;
		}
	[] PCU_MGMT.receive(BssgpResetIndication:{0}) {
		repeat;
		}
	[] PCU_MGMT.receive {
		setverdict(fail, "Received unexpected message on PCU_MGMT");
		mtc.stop;
		}

	[] T.timeout {
		setverdict(fail, "Timeout waiting for unblock of all BVCs");
		mtc.stop;
		}
	}

	/* iterate over list and check all BVCI */
	for (i := 0; i < lengthof(g_sgsn[0].cfg.bvc); i := i+1) {
		var BssgpBvci bvci := g_sgsn[0].cfg.bvc[i].bvci;
		if (not ro_integer_contains(bvci_unblocked, bvci)) {
			setverdict(fail, "BVCI=", bvci, " was not unblocked during start-up");
			mtc.stop;
		}
	}
}

function f_cleanup() runs on test_CT {
	self.stop;
}

type function void_fn(charstring id) runs on BSSGP_ConnHdlr;

/* helper function to create, connect and start a BSSGP_ConnHdlr component */
function f_start_handler(void_fn fn, charstring id, GbInstances pcu, GbInstances sgsn, integer imsi_suffix,
			 float t_guard := 30.0)
runs on test_CT return BSSGP_ConnHdlr {
	var BSSGP_ConnHdlr vc_conn;

	var BSSGP_ConnHdlrPars pars := {
		imei := f_gen_imei(imsi_suffix),
		imsi := f_gen_imsi(imsi_suffix),
		msisdn := f_gen_msisdn(imsi_suffix),
		p_tmsi := omit,
		p_tmsi_sig := omit,
		tlli := f_gprs_tlli_random(),
		tlli_old := omit,
		ra := omit,
		pcu := g_pcu,
		sgsn := g_sgsn,
		t_guard := t_guard
	};

	vc_conn := BSSGP_ConnHdlr.create(id);

	vc_conn.start(f_handler_init(fn, id, pars));
	return vc_conn;
}

/* Connect the PCU-side per-BVC ports (PCU/PCU_SIG/PCU_PROC) array slot 'port_idx' to specified per-BVC component */
private function f_connect_to_pcu_bvc(integer port_idx, BSSGP_BVC_CT bvc_ct) runs on BSSGP_ConnHdlr {
	if (PCU[port_idx].checkstate("Connected")) {
		/* unregister + disconnect from old BVC */
		f_client_unregister(g_pars.imsi, PCU_PROC[port_idx]);
		disconnect(self:PCU[port_idx], pcu_ct[port_idx]:BSSGP_SP);
		disconnect(self:PCU_SIG[port_idx], pcu_ct[port_idx]:BSSGP_SP_SIG);
		disconnect(self:PCU_PROC[port_idx], pcu_ct[port_idx]:BSSGP_PROC);
	}
	/* connect to new BVC and register us */
	connect(self:PCU[port_idx], bvc_ct:BSSGP_SP);
	connect(self:PCU_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
	connect(self:PCU_PROC[port_idx], bvc_ct:BSSGP_PROC);
	f_client_register(g_pars.imsi, g_pars.tlli, PCU_PROC[port_idx]);
	pcu_ct[port_idx] := bvc_ct;
}

/* Connect the SGSN-side per-BVC ports (SGSN/SGSN_SIG/SGSN_PROC) array slot 'port_idx' to specified per-BVC component */
private function f_connect_to_sgsn_bvc(integer port_idx, BSSGP_BVC_CT bvc_ct) runs on BSSGP_ConnHdlr {
	if (SGSN[port_idx].checkstate("Connected")) {
		/* unregister + disconnect from old BVC */
		f_client_unregister(g_pars.imsi, SGSN_PROC[port_idx]);
		disconnect(self:SGSN[port_idx], sgsn_ct[port_idx]:BSSGP_SP);
		disconnect(self:SGSN_SIG[port_idx], sgsn_ct[port_idx]:BSSGP_SP_SIG);
		disconnect(self:SGSN_PROC[port_idx], sgsn_ct[port_idx]:BSSGP_PROC);
	}
	/* connect to new BVC and register us */
	connect(self:SGSN[port_idx], bvc_ct:BSSGP_SP);
	connect(self:SGSN_SIG[port_idx], bvc_ct:BSSGP_SP_SIG);
	connect(self:SGSN_PROC[port_idx], bvc_ct:BSSGP_PROC);
	f_client_register(g_pars.imsi, g_pars.tlli, SGSN_PROC[port_idx]);
	sgsn_ct[port_idx] := bvc_ct;
}

private altstep as_Tguard() runs on BSSGP_ConnHdlr {
	[] g_Tguard.timeout {
		setverdict(fail, "Tguard timeout");
		mtc.stop;
	}
}

/* first function called in every ConnHdlr */
private function f_handler_init(void_fn fn, charstring id, BSSGP_ConnHdlrPars pars)
runs on BSSGP_ConnHdlr {
	var integer i;
	/* do some common stuff like setting up g_pars */
	g_pars := pars;

	llc := f_llc_create(false);

	/* default connections on PCU side: First BVC of each NSE/PCU */
	for (i := 0; i < lengthof(g_pars.pcu); i := i+1) {
		f_connect_to_pcu_bvc(i, g_pars.pcu[i].vc_BSSGP_BVC[0]);
	}

	/* default connections on SGSN side: First BVC of each NSE/SGSN */
	for (i := 0; i < lengthof(g_pars.sgsn); i := i+1) {
		f_connect_to_sgsn_bvc(i, g_pars.sgsn[i].vc_BSSGP_BVC[0]);
	}

	g_Tguard.start(pars.t_guard);
	activate(as_Tguard());

	/* call the user-supplied test case function */
	fn.apply(id);
}

private function f_client_register(hexstring imsi, OCT4 tlli, BSSGP_PROC_PT PT)
runs on BSSGP_ConnHdlr {
	PT.call(BSSGP_register_client:{imsi, tlli}) {
		[] PT.getreply(BSSGP_register_client:{imsi, tlli}) {};
	}
}

private function f_client_unregister(hexstring imsi, BSSGP_PROC_PT PT)
runs on BSSGP_ConnHdlr {
	PT.call(BSSGP_unregister_client:{imsi}) {
		[] PT.getreply(BSSGP_unregister_client:{imsi}) {};
	}
}

/* Send 'tx' on PTP-BVCI from PCU; expect 'rx' on SGSN */
friend function f_pcu2sgsn(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
			   integer pcu_idx := 0, integer sgsn_idx := 0) runs on BSSGP_ConnHdlr {
	var PDU_BSSGP rx;
	timer T := 1.0;

	PCU[pcu_idx].send(tx);
	T.start;
	alt {
	[] SGSN[sgsn_idx].receive(exp_rx) {
		setverdict(pass);
		}
	[] SGSN[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
		setverdict(fail, "Unexpected BSSGP on SGSN side: ", rx);
		mtc.stop;
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", rx);
		mtc.stop;
		}
	}
}

/* Send 'tx' on PTP-BVCI from SGSN; expect 'rx' on PCU */
friend function f_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
			   integer sgsn_idx:= 0, integer pcu_idx := 0) runs on BSSGP_ConnHdlr {
	var PDU_BSSGP rx;
	timer T := 1.0;

	SGSN[sgsn_idx].send(tx);
	T.start;
	alt {
	[] PCU[pcu_idx].receive(exp_rx) {
		setverdict(pass);
		}
	[] PCU[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
		setverdict(fail, "Unexpected BSSGP on PCU side: ", rx);
		mtc.stop;
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", rx);
		mtc.stop;
		}
	}
}

/* TODO:
   * Detach without Attach
   * SM procedures without attach / RAU
   * ATTACH / RAU
   ** with / without authentication
   ** with / without P-TMSI allocation
   * re-transmissions of LLC frames
   * PDP Context activation
   ** with different GGSN config in SGSN VTY
   ** with different PDP context type (v4/v6/v46)
   ** timeout from GGSN
   ** multiple / secondary PDP context
 */

private function f_TC_BVC_bringup(charstring id) runs on BSSGP_ConnHdlr {
	f_sleep(5.0);
	setverdict(pass);
}

testcase TC_BVC_bringup() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();

	vc_conn := f_start_handler(refers(f_TC_BVC_bringup), testcasename(), g_pcu, g_sgsn, 51);
	vc_conn.done;

	f_cleanup();
}

friend function f_bssgp_suspend(integer ran_idx := 0) runs on BSSGP_ConnHdlr return OCT1 {
	var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
	timer T := 5.0;
	var PDU_BSSGP rx_pdu;
	PCU_SIG[ran_idx].send(ts_BSSGP_SUSPEND(g_pars.tlli, bvcc.cell_id.ra_id));
	T.start;
	alt {
	[] PCU_SIG[ran_idx].receive(tr_BSSGP_SUSPEND_ACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) -> value rx_pdu {
		return rx_pdu.pDU_BSSGP_SUSPEND_ACK.suspend_Reference_Number.suspend_Reference_Number_value;
		}
	[] PCU_SIG[ran_idx].receive(tr_BSSGP_SUSPEND_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) -> value rx_pdu {
		setverdict(fail, "SUSPEND-NACK in response to SUSPEND for TLLI ", g_pars.tlli);
		mtc.stop;
		}
	[] T.timeout {
		setverdict(fail, "No SUSPEND-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
		mtc.stop;
		}
	}
	return '00'O;
}

friend function f_bssgp_resume(OCT1 susp_ref, integer ran_idx := 0) runs on BSSGP_ConnHdlr {
	var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
	timer T := 5.0;
	PCU_SIG[ran_idx].send(ts_BSSGP_RESUME(g_pars.tlli, bvcc.cell_id.ra_id, susp_ref));
	T.start;
	alt {
	[] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_ACK(g_pars.tlli, bvcc.cell_id.ra_id));
	[] PCU_SIG[ran_idx].receive(tr_BSSGP_RESUME_NACK(g_pars.tlli, bvcc.cell_id.ra_id, ?)) {
		setverdict(fail, "RESUME-NACK in response to RESUME for TLLI ", g_pars.tlli);
		mtc.stop;
		}
	[] T.timeout {
		setverdict(fail, "No RESUME-ACK in response to SUSPEND for TLLI ", g_pars.tlli);
		mtc.stop;
		}
	}
}


/* send uplink-unitdata of a variety of different sizes; expect it to show up on SGSN */
private function f_TC_ul_unitdata(charstring id) runs on BSSGP_ConnHdlr {
	var integer ran_idx := 0;
	var BssgpBvcConfig bvcc := g_pars.pcu[ran_idx].cfg.bvc[0];
	var integer i;

	for (i := 0; i < 1024; i := i+1) {
		var octetstring payload := f_rnd_octstring(i);
		var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_UL_UD(g_pars.tlli, bvcc.cell_id, payload);
		/* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
		var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_UL_UD(g_pars.tlli, bvcc.cell_id, payload);

		f_pcu2sgsn(pdu_tx, pdu_rx);
	}
	setverdict(pass);
}

testcase TC_ul_unitdata() runs on test_CT
{
	var BSSGP_ConnHdlr vc_conn;
	f_init();

	vc_conn := f_start_handler(refers(f_TC_ul_unitdata), testcasename(), g_pcu, g_sgsn, 1);
	vc_conn.done;
	/* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */

	f_cleanup();
}

/* send downlink-unitdata of a variety of different sizes; expect it to show up on PCU */
private function f_TC_dl_unitdata(charstring id) runs on BSSGP_ConnHdlr {
	var integer i;

	for (i := 0; i < 1024; i := i+1) {
		var octetstring payload := f_rnd_octstring(i);
		var template (value) PDU_BSSGP pdu_tx :=
			ts_BSSGP_DL_UD(g_pars.tlli, payload, omit, ts_BSSGP_IMSI(g_pars.imsi));
		/* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
		var template (present) PDU_BSSGP pdu_rx :=
			tr_BSSGP_DL_UD(g_pars.tlli, payload, tr_BSSGP_IMSI(g_pars.imsi));

		f_sgsn2pcu(pdu_tx, pdu_rx);
	}
	setverdict(pass);
}

testcase TC_dl_unitdata() runs on test_CT
{
	var BSSGP_ConnHdlr vc_conn;
	f_init();

	vc_conn := f_start_handler(refers(f_TC_dl_unitdata), testcasename(), g_pcu, g_sgsn, 2);
	vc_conn.done;
	/* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */

	f_cleanup();
}

private function f_TC_ra_capability(charstring id) runs on BSSGP_ConnHdlr {
	var integer i;

	for (i := 0; i < 10; i := i+1) {
		var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP(g_pars.tlli, { ts_RaCapRec_BSSGP });
		/* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
		var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP(g_pars.tlli, { tr_RaCapRec_BSSGP })

		f_sgsn2pcu(pdu_tx, pdu_rx);
	}
	setverdict(pass);
}
testcase TC_ra_capability() runs on test_CT
{
	var BSSGP_ConnHdlr vc_conn;
	f_init();

	vc_conn := f_start_handler(refers(f_TC_ra_capability), testcasename(), g_pcu, g_sgsn, 3);
	vc_conn.done;
	/* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */

	f_cleanup();
}

private function f_TC_ra_capability_upd(charstring id) runs on BSSGP_ConnHdlr {
	var integer i;
	var OCT1 tag;
	for (i := 0; i < 10; i := i+1) {
		tag := int2oct(23 + i, 1);
		var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RA_CAP_UPD(g_pars.tlli, tag);
		/* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
		var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RA_CAP_UPD(g_pars.tlli, tag)

		f_pcu2sgsn(pdu_tx, pdu_rx);

		pdu_tx := ts_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O);
		/* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
		pdu_rx := tr_BSSGP_RA_CAP_UPD_ACK(g_pars.tlli, tag, '42'O)

		f_sgsn2pcu(pdu_tx, pdu_rx);
	}
	setverdict(pass);
}
testcase TC_ra_capability_upd() runs on test_CT
{
	var BSSGP_ConnHdlr vc_conn;
	f_init();

	vc_conn := f_start_handler(refers(f_TC_ra_capability_upd), testcasename(), g_pcu, g_sgsn, 3);
	vc_conn.done;
	/* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */

	f_cleanup();
}




control {
	execute( TC_BVC_bringup() );
	execute( TC_ul_unitdata() );
	execute( TC_dl_unitdata() );
	execute( TC_ra_capability() );
	execute( TC_ra_capability_upd() );
}


}
