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;

/* 48.016 section 6.1.4.2: The default maximum information field size of 1600 octets shall be supported on the Gb interface */
const integer max_fr_info_size := 1600;

modulepar {
	/* SGSN NS configuration */
	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
				}
			}
		}
	};
	/* BSS NSEI start at 2000 + x
	 * NSVCI start from value of NSEI + 100
	 * UDP port is NSVCI * 10 */
	NSConfigurations mp_nsconfig_pcu := {
		{
			nsei := 2001,
			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 := 2101
				}
			}
		},
		{
			nsei := 2002,
			role_sgsn := false,
			handle_sns := false,
			nsvc := {
				{
					provider := {
						ip := {
							address_family := AF_INET,
							local_udp_port := 21020,
							local_ip := "127.0.0.1",
							remote_udp_port := 23000,
							remote_ip := "127.0.0.1"
						}
					},
					nsvci := 2102
				}
			}
		},
		{
			nsei := 2003,
			role_sgsn := false,
			handle_sns := false,
			nsvc := {
				{
					provider := {
						ip := {
							address_family := AF_INET,
							local_udp_port := 21030,
							local_ip := "127.0.0.1",
							remote_udp_port := 23000,
							remote_ip := "127.0.0.1"
						}
					},
					nsvci := 2103
				}
			}
		}
	};
	/* BVCI are NSEI*10 + x
	 * The first NSE only has one BVC, the second one 2 and so on
	 * The Cell ID is BVCI + 10000
	 * LAC/RAC are configured in such a way that:
	 * LAC 13135 is present once in NSE(2001), twice in NSE(2002) and once in NSE(2003)
	 * LAC 13300 is present twice in NSE(2003)
	 * RAI 13135-1 is present in NSE(2002) and NSE(2003)
	 * RAI 13300-0 is present twice in NSE(2003)
	 */
	BssgpConfigs mp_gbconfigs := {
		{
			nsei := 2001,
			sgsn_role := false,
			bvc := {
				{
					bvci := 20011,
					cell_id := {
						ra_id := {
							lai := {
								mcc_mnc := c_mcc_mnc,
								lac := 13135
							},
							rac := 0
						},
						cell_id := 30011
					},
					depth := BSSGP_DECODE_DEPTH_BSSGP,
					create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
				}
			}
		}, {
			nsei := 2002,
			sgsn_role := false,
			bvc := {
				{
					bvci := 20021,
					cell_id := {
						ra_id := {
							lai := {
								mcc_mnc := c_mcc_mnc,
								lac := 13135
							},
							rac := 1
						},
						cell_id := 30021
					},
					depth := BSSGP_DECODE_DEPTH_BSSGP,
					create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
				},
				{
					bvci := 20022,
					cell_id := {
						ra_id := {
							lai := {
								mcc_mnc := c_mcc_mnc,
								lac := 13135
							},
							rac := 2
						},
						cell_id := 30022
					},
					depth := BSSGP_DECODE_DEPTH_BSSGP,
					create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
				}
			}
		}, {
			nsei := 2003,
			sgsn_role := false,
			bvc := {
				{
					bvci := 20031,
					cell_id := {
						ra_id := {
							lai := {
								mcc_mnc := c_mcc_mnc,
								lac := 13135
							},
							rac := 1
						},
						cell_id := 30031
					},
					depth := BSSGP_DECODE_DEPTH_BSSGP,
					create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
				},
				{
					bvci := 20032,
					cell_id := {
						ra_id := {
							lai := {
								mcc_mnc := c_mcc_mnc,
								lac := 13300
							},
							rac := 0
						},
						cell_id := 30032
					},
					depth := BSSGP_DECODE_DEPTH_BSSGP,
					create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
				},
				{
					bvci := 20033,
					cell_id := {
						ra_id := {
							lai := {
								mcc_mnc := c_mcc_mnc,
								lac := 13300
							},
							rac := 0
						},
						cell_id := 30033
					},
					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;

	var ro_integer g_roi := {};
};

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];
	/* BSSGP BVC configuration of the component to which we're currently connected */
	var BssgpBvcConfig pcu_bvc_cfg[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;

	var ro_integer g_roi := {};
}

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_fix_create_cb(inout BssgpConfig cfg)
{
	for (var integer i := 0; i < lengthof(cfg.bvc); i := i + 1) {
		if (not isbound(cfg.bvc[i].create_cb)) {
			cfg.bvc[i].create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
		}
	}
}

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);
	}
	connect(self:PCU_MGMT, gb.vc_BSSGP: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);
	}
	connect(self:SGSN_MGMT, gb.vc_BSSGP: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];
		/* make sure all have a proper crate_cb, which cannot be specified in config file */
		f_fix_create_cb(g_pcu[i].cfg);
		/* concatenate all the PCU-side BVCs for the SGSN side */
		g_sgsn[0].cfg.bvc := g_sgsn[0].cfg.bvc & g_pcu[i].cfg.bvc;
	}

	f_init_vty();
	for (i := 0; i < lengthof(mp_nsconfig_sgsn); i := i+1) {
		f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_sgsn[i].cfg.nsei) & " force-unconfigured");
	}
	for (i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
		f_vty_transceive(GBPVTY, "nsvc nsei " & int2str(g_pcu[i].cfg.nsei) & " force-unconfigured");
		f_vty_transceive(GBPVTY, "delete-gbproxy-peer " & int2str(g_pcu[i].cfg.nsei) & " only-bvc");
	}

	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 := 15.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(BssgpResetIndication:?) {
		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, integer nse_idx, integer bvc_idx)
runs on BSSGP_ConnHdlr {
	var BSSGP_BVC_CT bvc_ct := g_pars.pcu[nse_idx].vc_BSSGP_BVC[bvc_idx]
	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;
	pcu_bvc_cfg[port_idx] := g_pars.pcu[nse_idx].cfg.bvc[bvc_idx];
}

/* 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(port_idx := i, nse_idx := i, bvc_idx := 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, boolean use_sig := false) runs on BSSGP_ConnHdlr {
	var PDU_BSSGP rx;
	timer T := 1.0;

	if (use_sig) {
		PCU_SIG[pcu_idx].send(tx);
	} else {
		PCU[pcu_idx].send(tx);
	}

	T.start;
	alt {
	[use_sig] SGSN_SIG[sgsn_idx].receive(exp_rx) {
		setverdict(pass);
		}
	[not use_sig] 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;
		}
	[] SGSN_SIG[sgsn_idx].receive(PDU_BSSGP:?) -> value rx {
		setverdict(fail, "Unexpected SIG BSSGP on SGSN side: ", rx);
		mtc.stop;
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for BSSGP on SGSN side: ", exp_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, boolean use_sig := false) runs on BSSGP_ConnHdlr {
	var PDU_BSSGP rx;
	timer T := 1.0;

	if (use_sig) {
		SGSN_SIG[sgsn_idx].send(tx);
	} else {
		SGSN[sgsn_idx].send(tx);
	}

	T.start;
	alt {
	[use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
		setverdict(pass);
		}
	[not use_sig] 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;
		}
	[] PCU_SIG[pcu_idx].receive(PDU_BSSGP:?) -> value rx {
		setverdict(fail, "Unexpected SIG BSSGP on PCU side: ", rx);
		mtc.stop;
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for BSSGP on PCU side: ", exp_rx);
		mtc.stop;
		}
	}
}

/***********************************************************************
 * GlobaLTest_CT: Using the per-NSE GLOBAL ports on PCU + SGSN side
 ***********************************************************************/

type component GlobalTest_CT extends test_CT {
	port BSSGP_PT G_PCU[NUM_PCU];
	port BSSGP_PT G_SGSN[NUM_SGSN];
};

private function f_global_init() runs on GlobalTest_CT {
	var integer i;
	for (i := 0; i < lengthof(g_sgsn); i := i+1) {
		connect(self:G_SGSN[i], g_sgsn[i].vc_BSSGP:GLOBAL);
	}
	for (i := 0; i < lengthof(g_pcu); i := i+1) {
		connect(self:G_PCU[i], g_pcu[i].vc_BSSGP:GLOBAL);
	}
}

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

	G_PCU[pcu_idx].send(tx);
	T.start;
	alt {
	[] G_SGSN[sgsn_idx].receive(exp_rx) {
		setverdict(pass);
		}
	[] G_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_global_sgsn2pcu(template (value) PDU_BSSGP tx, template (present) PDU_BSSGP exp_rx,
				  integer sgsn_idx := 0, integer pcu_idx := 0) runs on GlobalTest_CT {
	var PDU_BSSGP rx;
	timer T := 1.0;

	G_SGSN[sgsn_idx].send(tx);
	T.start;
	alt {
	[] G_PCU[pcu_idx].receive(exp_rx) {
		setverdict(pass);
		}
	[] G_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 < max_fr_info_size-4; i := i+4) {
		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);

		log("UL-UNITDATA(payload_size=", i);
		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 < max_fr_info_size-4; i := i+4) {
		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));

		log("DL-UNITDATA(payload_size=", i);
		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, 4);
	vc_conn.done;
	/* TODO: start multiple handlers (UEs) on various cells on same and other NSEs */

	f_cleanup();
}

private function f_TC_radio_status(charstring id) runs on BSSGP_ConnHdlr {
	var integer i;
	var BssgpRadioCause cause := BSSGP_RADIO_CAUSE_CONTACT_LOST;
	for (i := 0; i < 10; i := i+1) {
		var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RADIO_STATUS(g_pars.tlli, cause);
		/* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
		var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RADIO_STATUS(g_pars.tlli, cause)

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

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

	f_cleanup();
}

private function f_TC_suspend() runs on GlobalTest_CT {
	var integer i;

	/* TODO: Generate RA ID for each ConnHdlr */
	var RoutingAreaIdentification	ra_id := g_pcu[0].cfg.bvc[0].cell_id.ra_id;
	for (i := 0; i < 10; i := i+1) {
		var OCT4 tlli := f_gprs_tlli_random();
		var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_SUSPEND(tlli, ra_id);
		/* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
		var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_SUSPEND(tlli, ra_id);

		f_global_pcu2sgsn(pdu_tx, pdu_rx);

		pdu_tx := ts_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(i, 1));
		/* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
		pdu_rx := tr_BSSGP_SUSPEND_ACK(tlli, ra_id, int2oct(i, 1));

		f_global_sgsn2pcu(pdu_tx, pdu_rx);

		/* These messages are simple passed through so just also test sending NACK */
		pdu_tx := ts_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
		/* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
		pdu_rx := tr_BSSGP_SUSPEND_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);

		f_global_sgsn2pcu(pdu_tx, pdu_rx);
	}
	setverdict(pass);
}
testcase TC_suspend() runs on GlobalTest_CT
{
	f_init();
	f_global_init();
	f_TC_suspend();
	f_cleanup();
}

private function f_TC_resume() runs on GlobalTest_CT {
	var integer i;

	/* TODO: Generate RA ID for each ConnHdlr */
	var RoutingAreaIdentification	ra_id := g_pcu[0].cfg.bvc[0].cell_id.ra_id;
	for (i := 0; i < 10; i := i+1) {
		var OCT4 tlli := f_gprs_tlli_random();
		var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));
		/* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
		var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_RESUME(tlli, ra_id, int2oct(i, 1));

		f_global_pcu2sgsn(pdu_tx, pdu_rx);

		pdu_tx := ts_BSSGP_RESUME_ACK(tlli, ra_id);
		/* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
		pdu_rx := tr_BSSGP_RESUME_ACK(tlli, ra_id);

		f_global_sgsn2pcu(pdu_tx, pdu_rx);

		/* These messages are simple passed through so just also test sending NACK */
		pdu_tx := ts_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);
		/* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
		pdu_rx := tr_BSSGP_RESUME_NACK(tlli, ra_id, BSSGP_CAUSE_UNKNOWN_MS);

		f_global_sgsn2pcu(pdu_tx, pdu_rx);
	}
	setverdict(pass);
}
testcase TC_resume() runs on GlobalTest_CT
{
	f_init();
	f_global_init();
	f_TC_resume();
	f_cleanup();
}

/* test the load-sharing between multiple NS-VC on the BSS side */
private function f_TC_dl_ud_unidir(charstring id) runs on BSSGP_ConnHdlr {
	var integer i;

	for (i := 0; i < 10; 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));
		SGSN[0].send(pdu_tx);
	}
	setverdict(pass);
}
testcase TC_load_sharing_dl() runs on test_CT_NS
{
	const integer num_ue := 10;
	var BSSGP_ConnHdlr vc_conn[num_ue];
	f_init();

	/* all BVC are now fully brought up.  We disconnect BSSGP from NS on the BSS
	 * side so we get the raw NsUnitdataIndication and hence observe different
	 * NSVCI */
	disconnect(g_pcu[0].vc_NS:NS_SP, g_pcu[0].vc_BSSGP:BSCP);
	connect(g_pcu[0].vc_NS:NS_SP, self:NS);

	/* there may still be some NS-VCs coming up? After all, the BVC-RESET succeeds after the first
	 * of the NS-VC is ALIVE/UNBLOCKED */
	f_sleep(3.0);

	/* start parallel components generating DL-UNITDATA from the SGSN side */
	for (var integer i:= 0; i < num_ue; i := i+1) {
		vc_conn[i] := f_start_handler(refers(f_TC_dl_ud_unidir), testcasename(), g_pcu, g_sgsn, 5+i);
	}

	/* now start counting all the messages that were queued before */
	/* TODO: We have a hard-coded assumption of 4 NS-VC in one NSE/NS-VCG here! */
	var ro_integer rx_count := { 0, 0, 0, 0 };
	timer T := 2.0;
	T.start;
	alt {
	[] as_NsUdiCount(0, rx_count);
	[] as_NsUdiCount(1, rx_count);
	[] as_NsUdiCount(2, rx_count);
	[] as_NsUdiCount(3, rx_count);
	[] NS.receive(NsUnitdataIndication:{0,?,?,*,*}) { repeat; } /* signaling BVC */
	[] NS.receive(NsStatusIndication:?) { repeat; }
	[] NS.receive {
		setverdict(fail, "Rx unexpected NS");
		mtc.stop;
		}
	[] T.timeout {
		}
	}
	for (var integer i := 0; i < lengthof(rx_count); i := i+1) {
		log("Rx on NSVCI ", mp_nsconfig_pcu[0].nsvc[i].nsvci, ": ", rx_count[i]);
		if (rx_count[i] == 0) {
			setverdict(fail, "Data not shared over all NSVC");
		}
	}
	setverdict(pass);
}
private altstep as_NsUdiCount(integer nsvc_idx, inout ro_integer roi) runs on test_CT_NS {
	var NsUnitdataIndication udi;
	var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[0];
	[] NS.receive(NsUnitdataIndication:{bvcc.bvci, g_pcu[0].cfg.nsei, mp_nsconfig_pcu[0].nsvc[nsvc_idx].nsvci, *, *}) -> value udi {
		roi[nsvc_idx] := roi[nsvc_idx] + 1;
		repeat;
		}
}
type component test_CT_NS extends test_CT {
	port NS_PT NS;
};


/***********************************************************************
 * PAGING PS procedure
 ***********************************************************************/

private function f_send_paging_ps(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
				boolean use_sig := false)
runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
	var template (value) PDU_BSSGP pdu_tx;
	var template (present) PDU_BSSGP pdu_rx;
	/* we always specify '0' as BVCI in the templates below, as we override it with
	 * 'p4' later anyway */
	pdu_rx := tr_BSSGP_PS_PAGING(0);
	pdu_rx.pDU_BSSGP_PAGING_PS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
	if (ispresent(g_pars.p_tmsi)) {
		pdu_tx := ts_BSSGP_PS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
		pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
	} else {
		pdu_tx := ts_BSSGP_PS_PAGING_IMSI(0, g_pars.imsi);
		pdu_rx.pDU_BSSGP_PAGING_PS.pTMSI := omit;
	}
	pdu_tx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
	pdu_rx.pDU_BSSGP_PAGING_PS.paging_Field4 := p4;
	if (use_sig == false) {
		SGSN[sgsn_idx].send(pdu_tx);
	} else {
		SGSN_SIG[sgsn_idx].send(pdu_tx);
	}
	return pdu_rx;
}

/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
 * specified PCU index */
private function f_send_paging_ps_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
					      boolean use_sig := false,integer pcu_idx := 0)
runs on BSSGP_ConnHdlr {
	var template (present) PDU_BSSGP exp_rx;
	var boolean test_done := false;
	/* doesn't really make sense: Sending to a single BVCI means the message ends up
	 * at that BVC (cell) only, and paging all over the BSS area is not possible */
	exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
	/* Expect paging to propagate to the one BSS addressed by the BVCI only */
	timer T := 2.0;
	T.start;
	alt {
	[not use_sig and not test_done] PCU[pcu_idx].receive(exp_rx) {
		setverdict(pass);
		test_done := true;
		repeat;
		}
	[not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
		setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
		}
	[use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
		setverdict(pass);
		test_done := true;
		repeat;
		}
	[use_sig] PCU[pcu_idx].receive(exp_rx) {
		setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
		}
	[] any from PCU.receive(exp_rx) {
		setverdict(fail, "Paging received on unexpected BVC");
		}
	[] any from PCU_SIG.receive(exp_rx) {
		setverdict(fail, "Paging received on unexpected BVC");
		}
	[] any from PCU.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
		setverdict(fail, "Different Paging than expected received PTP BVC");
		}
	[] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
		setverdict(fail, "Different Paging than expected on SIGNALING BVC");
		}
	[not test_done] T.timeout {
		setverdict(fail, "Timeout waiting for paging");
	}
	[test_done] T.timeout;
	}
}

/* send a PS-PAGING but don't expect it to show up on any PTP or SIG BVC */
private function f_send_paging_ps_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
					      boolean use_sig := false)
runs on BSSGP_ConnHdlr {
	var template (present) PDU_BSSGP exp_rx;
	exp_rx := f_send_paging_ps(p4, sgsn_idx, use_sig);
	/* Expect paging to propagate to no BSS */
	timer T := 2.0;
	T.start;
	alt {
	[] any from PCU.receive(exp_rx) {
		setverdict(fail, "Paging received on unexpected BVC");
		}
	[] any from PCU_SIG.receive(exp_rx) {
		setverdict(fail, "Paging received on unexpected BVC");
		}
	[] any from PCU.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
		setverdict(fail, "Different Paging received on PTP BVC");
		}
	[] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
		setverdict(fail, "Different Paging received on SIGNALING BVC");
		}
	[] T.timeout {
		setverdict(pass);
		}
	}
}

private function f_TC_paging_ps_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
{
	/* doesn't really make sense: Sending to a single BVCI means the message ends up
	 * at that BVC (cell) only, and paging all over the BSS area is not possible */
	f_send_paging_ps_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
}
testcase TC_paging_ps_ptp_bss() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();

	vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bss), testcasename(), g_pcu, g_sgsn, 9);
	vc_conn.done;

	f_cleanup();
}

/* PS-PAGING on PTP-BVC for Location Area */
private function f_TC_paging_ps_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
{
	var template (present) PDU_BSSGP exp_rx;
	/* doesn't really make sense: Sending to a single BVCI means the message ends up
	 * at that BVC (cell) only, and paging all over the BSS area is not possible */
	f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
}
testcase TC_paging_ps_ptp_lac() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();

	vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_lac), testcasename(), g_pcu, g_sgsn, 10);
	vc_conn.done;

	f_cleanup();
}

/* PS-PAGING on PTP-BVC for unknown Location Area */
private function f_TC_paging_ps_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
{
	var GSM_Types.LocationAreaIdentification unknown_la := {
		mcc_mnc := '567F99'H,
		lac := 33333
	};
	/* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
	f_send_paging_ps_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
}
testcase TC_paging_ps_ptp_lac_unknown() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();

	vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
	vc_conn.done;

	f_cleanup();
}

/* PS-PAGING on PTP-BVC for Routeing Area */
private function f_TC_paging_ps_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
{
	/* doesn't really make sense: Sending to a single BVCI means the message ends up
	 * at that BVC (cell) only, and paging all over the BSS area is not possible */
	f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
}
testcase TC_paging_ps_ptp_rac() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();

	vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_rac), testcasename(), g_pcu, g_sgsn, 11);
	vc_conn.done;

	f_cleanup();
}

/* PS-PAGING on PTP-BVC for unknown Routeing Area */
private function f_TC_paging_ps_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
{
	var RoutingAreaIdentification unknown_ra := {
		lai := {
			mcc_mnc := '567F99'H,
			lac := 33333
		},
		rac := 254
	};
	/* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
	f_send_paging_ps_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
}
testcase TC_paging_ps_ptp_rac_unknown() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();

	vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
	vc_conn.done;

	f_cleanup();
}

/* PS-PAGING on PTP-BVC for BVCI (one cell) */
private function f_TC_paging_ps_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
{
	/* this should be the normal case for MS in READY MM state after a lower layer failure */
	f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
}
testcase TC_paging_ps_ptp_bvci() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();

	vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bvci), testcasename(), g_pcu, g_sgsn, 12);
	vc_conn.done;

	f_cleanup();
}

/* PS-PAGING on PTP-BVC for unknown BVCI */
private function f_TC_paging_ps_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
{
	/* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
	f_send_paging_ps_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
}
testcase TC_paging_ps_ptp_bvci_unknown() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();

	vc_conn := f_start_handler(refers(f_TC_paging_ps_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
	vc_conn.done;

	f_cleanup();
}

/* altstep for expecting BSSGP PDU on signaling BVC of given pcu_idx + storing in 'roi' */
private altstep as_paging_sig_pcu(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
runs on BSSGP_ConnHdlr {
[] PCU_SIG[pcu_idx].receive(exp_rx) {
	if (ro_integer_contains(roi, pcu_idx)) {
		setverdict(fail, "Received multiple paging on same SIG BVC");
	}
	roi := roi & { pcu_idx };
	repeat;
	}
[] PCU[pcu_idx].receive(exp_rx) {
	setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
	}
[] PCU_SIG[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
	setverdict(fail, "Different Paging than expected received SIGNALING BVC");
	}
[] PCU[pcu_idx].receive(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}) {
	setverdict(fail, "Different Paging than expected received PTP BVC");
	}
}

type record of default ro_default;

/* send PS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
private function f_send_paging_ps_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
					    ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
{
	var template (present) PDU_BSSGP exp_rx;
	exp_rx := f_send_paging_ps(p4, 0, true);

	/* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
	var ro_default defaults := {};
	for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
		var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
		defaults := defaults & { d };
	}
	f_sleep(2.0);
	for (var integer i := 0; i < lengthof(defaults); i := i+1) {
		deactivate(defaults[i]);
	}
	log("Paging received on PCU ", g_roi);

	for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
		var boolean rx_on_i := ro_integer_contains(g_roi, i);
		var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
		if (exp_on_i and not rx_on_i) {
			setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
		}
		if (not exp_on_i and rx_on_i) {
			setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
		}
	}
	setverdict(pass);
}

/* PS-PAGING on SIG-BVC for BSS Area */
private function f_TC_paging_ps_sig_bss(charstring id) runs on BSSGP_ConnHdlr
{
	/* we expect the paging to arrive on all three NSE */
	f_send_paging_ps_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
}
testcase TC_paging_ps_sig_bss() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();

	vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
	vc_conn.done;

	f_cleanup();
}

/* PS-PAGING on SIG-BVC for Location Area */
private function f_TC_paging_ps_sig_lac(charstring id) runs on BSSGP_ConnHdlr
{
	/* The first LAC (13135) is shared by all three NSEs */
	f_send_paging_ps_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
	/* Reset state */
	g_roi := {};
	/* Make LAC (13300) available on pcu index 2 */
	f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
	f_send_paging_ps_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[2].cell_id.ra_id.lai), 0, {2});
}
testcase TC_paging_ps_sig_lac() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();

	vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
	vc_conn.done;

	f_cleanup();
}

/* PS-PAGING on SIG-BVC for unknown Location Area */
private function f_TC_paging_ps_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
{
	var GSM_Types.LocationAreaIdentification unknown_la := {
		mcc_mnc := '567F99'H,
		lac := 33333
	};
	f_send_paging_ps_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
}
testcase TC_paging_ps_sig_lac_unknown() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();

	vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
	vc_conn.done;

	f_cleanup();
}

/* PS-PAGING on SIG-BVC for Routeing Area */
private function f_TC_paging_ps_sig_rac(charstring id) runs on BSSGP_ConnHdlr
{
	/* Only PCU index 0 has a matching BVC with the RA ID */
	f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, {0});
	g_roi := {};
	/* PCU index 1 and 2 have a matching BVC with the RA ID */
	f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
	g_roi := {};
	/* PCU index 2 has two matching BVCs with the RA ID */
	f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
	f_send_paging_ps_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {2});
}
testcase TC_paging_ps_sig_rac() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();

	vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
	vc_conn.done;

	f_cleanup();
}

/* PS-PAGING on SIG-BVC for unknown Routeing Area */
private function f_TC_paging_ps_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
{
	var RoutingAreaIdentification unknown_ra := {
		lai := {
			mcc_mnc := '567F99'H,
			lac := 33333
		},
		rac := 254
	};
	f_send_paging_ps_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
}
testcase TC_paging_ps_sig_rac_unknown() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();

	vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
	vc_conn.done;

	f_cleanup();
}

/* PS-PAGING on SIG-BVC for BVCI (one cell) */
private function f_TC_paging_ps_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
{
	f_send_paging_ps_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
}
testcase TC_paging_ps_sig_bvci() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();

	vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
	vc_conn.done;

	f_cleanup();
}

/* PS-PAGING on SIG-BVC for unknown BVCI */
private function f_TC_paging_ps_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
{
	f_send_paging_ps_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
}
testcase TC_paging_ps_sig_bvci_unknown() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();

	vc_conn := f_start_handler(refers(f_TC_paging_ps_sig_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
	vc_conn.done;

	f_cleanup();
}



/***********************************************************************
 * PAGING CS procedure
 ***********************************************************************/

private function f_send_paging_cs(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
				  boolean use_sig := false)
runs on BSSGP_ConnHdlr return template (present) PDU_BSSGP {
	var template (value) PDU_BSSGP pdu_tx;
	var template (present) PDU_BSSGP pdu_rx;
	/* we always specify '0' as BVCI in the templates below, as we override it with
	 * 'p4' later anyway */
	pdu_rx := tr_BSSGP_CS_PAGING(0);
	pdu_rx.pDU_BSSGP_PAGING_CS.iMSI := tr_BSSGP_IMSI(g_pars.imsi);
	if (ispresent(g_pars.p_tmsi)) {
		pdu_tx := ts_BSSGP_CS_PAGING_PTMSI(0, g_pars.imsi, oct2int(g_pars.p_tmsi));
		pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := tr_BSSGP_TMSI(oct2int(g_pars.p_tmsi));
	} else {
		pdu_tx := ts_BSSGP_CS_PAGING_IMSI(0, g_pars.imsi);
		pdu_rx.pDU_BSSGP_PAGING_CS.tMSI := omit;
	}
	pdu_tx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
	pdu_rx.pDU_BSSGP_PAGING_CS.paging_Field4 := p4;
	if (use_sig == false) {
		SGSN[sgsn_idx].send(pdu_tx);
	} else {
		SGSN_SIG[sgsn_idx].send(pdu_tx);
	}
	return pdu_rx;
}

/* send paging defined by 'p4' on given SGSN-side index (ptp or signaling) and expect one paging to arrive on
 * specified PCU index */
private function f_send_paging_cs_exp_one_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
					      boolean use_sig := false,integer pcu_idx := 0)
runs on BSSGP_ConnHdlr {
	var template (present) PDU_BSSGP exp_rx;
	var boolean test_done := false;
	/* doesn't really make sense: Sending to a single BVCI means the message ends up
	 * at that BVC (cell) only, and paging all over the BSS area is not possible */
	exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
	/* Expect paging to propagate to the one BSS addressed by the BVCI only */
	timer T := 2.0;
	T.start;
	alt {
	[not use_sig and not test_done] PCU[pcu_idx].receive(exp_rx) {
		setverdict(pass);
		test_done := true;
		repeat;
		}
	[not use_sig] PCU_SIG[pcu_idx].receive(exp_rx) {
		setverdict(fail, "Received paging on SIGNALING BVC, expected PTP BVC");
		}
	[use_sig and not test_done] PCU_SIG[pcu_idx].receive(exp_rx) {
		setverdict(pass);
		test_done := true;
		repeat;
		}
	[use_sig] PCU[pcu_idx].receive(exp_rx) {
		setverdict(fail, "Received paging on PTP BVC, expected SIGNALING BVC");
		}
	[] any from PCU.receive(exp_rx) {
		setverdict(fail, "Paging received on unexpected BVC");
		}
	[] any from PCU_SIG.receive(exp_rx) {
		setverdict(fail, "Paging received on unexpected BVC");
		}
	[] any from PCU.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
		setverdict(fail, "Different Paging than expected received PTP BVC");
		}
	[] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
		setverdict(fail, "Different Paging than expected on SIGNALING BVC");
		}
	[not test_done] T.timeout {
		setverdict(fail, "Timeout while waiting for paging")
	}
	[test_done] T.timeout;
	}
}

/* send a CS-PAGING but don't expect it to show up on any PTP or SIG BVC */
private function f_send_paging_cs_exp_no_bss(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
					      boolean use_sig := false)
runs on BSSGP_ConnHdlr {
	var template (present) PDU_BSSGP exp_rx;
	exp_rx := f_send_paging_cs(p4, sgsn_idx, use_sig);
	/* Expect paging to propagate to no BSS */
	timer T := 2.0;
	T.start;
	alt {
	[] any from PCU.receive(exp_rx) {
		setverdict(fail, "Paging received on unexpected BVC");
		}
	[] any from PCU_SIG.receive(exp_rx) {
		setverdict(fail, "Paging received on unexpected BVC");
		}
	[] any from PCU.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
		setverdict(fail, "Different Paging received on PTP BVC");
		}
	[] any from PCU_SIG.receive(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}) {
		setverdict(fail, "Different Paging received on SIGNALING BVC");
		}
	[] T.timeout {
		setverdict(pass);
		}
	}
}

private function f_TC_paging_cs_ptp_bss(charstring id) runs on BSSGP_ConnHdlr
{
	/* doesn't really make sense: Sending to a single BVCI means the message ends up
	 * at that BVC (cell) only, and paging all over the BSS area is not possible */
	f_send_paging_cs_exp_one_bss(ts_BssgpP4BssArea, 0, false, 0);
}
testcase TC_paging_cs_ptp_bss() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();

	vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bss), testcasename(), g_pcu, g_sgsn, 17);
	vc_conn.done;

	f_cleanup();
}

/* CS-PAGING on PTP-BVC for Location Area */
private function f_TC_paging_cs_ptp_lac(charstring id) runs on BSSGP_ConnHdlr
{
	var template (present) PDU_BSSGP exp_rx;
	/* doesn't really make sense: Sending to a single BVCI means the message ends up
	 * at that BVC (cell) only, and paging all over the BSS area is not possible */
	f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, false, 0);
}
testcase TC_paging_cs_ptp_lac() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();

	vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_lac), testcasename(), g_pcu, g_sgsn, 18);
	vc_conn.done;

	f_cleanup();
}

/* CS-PAGING on PTP-BVC for unknown Location Area */
private function f_TC_paging_cs_ptp_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
{
	var GSM_Types.LocationAreaIdentification unknown_la := {
		mcc_mnc := '567F99'H,
		lac := 33333
	};
	/* as it's sent on the PTP BVC, we expect it to pass even for unknown LAC */
	f_send_paging_cs_exp_one_bss(ts_BssgpP4LAC(unknown_la), 0, false, 0);
}
testcase TC_paging_cs_ptp_lac_unknown() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();

	vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
	vc_conn.done;

	f_cleanup();
}

/* CS-PAGING on PTP-BVC for Routeing Area */
private function f_TC_paging_cs_ptp_rac(charstring id) runs on BSSGP_ConnHdlr
{
	/* doesn't really make sense: Sending to a single BVCI means the message ends up
	 * at that BVC (cell) only, and paging all over the BSS area is not possible */
	f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, false, 0);
}
testcase TC_paging_cs_ptp_rac() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();

	vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_rac), testcasename(), g_pcu, g_sgsn, 19);
	vc_conn.done;

	f_cleanup();
}

/* CS-PAGING on PTP-BVC for unknown Routeing Area */
private function f_TC_paging_cs_ptp_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
{
	var RoutingAreaIdentification unknown_ra := {
		lai := {
			mcc_mnc := '567F99'H,
			lac := 33333
		},
		rac := 254
	};
	/* as it's sent on the PTP BVC, we expect it to pass even for unknown RAC */
	f_send_paging_cs_exp_one_bss(ts_BssgpP4RAC(unknown_ra), 0, false, 0);
}
testcase TC_paging_cs_ptp_rac_unknown() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();

	vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
	vc_conn.done;

	f_cleanup();
}

/* CS-PAGING on PTP-BVC for BVCI (one cell) */
private function f_TC_paging_cs_ptp_bvci(charstring id) runs on BSSGP_ConnHdlr
{
	/* this should be the normal case for MS in READY MM state after a lower layer failure */
	f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, false, 0);
}
testcase TC_paging_cs_ptp_bvci() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();

	vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bvci), testcasename(), g_pcu, g_sgsn, 20);
	vc_conn.done;

	f_cleanup();
}

/* CS-PAGING on PTP-BVC for unknown BVCI */
private function f_TC_paging_cs_ptp_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
{
	/* as it's sent on the PTP BVC, we expect it to pass even for unknown BVCI */
	f_send_paging_cs_exp_one_bss(ts_BssgpP4Bvci(33333), 0, false, 0);
}
testcase TC_paging_cs_ptp_bvci_unknown() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();

	vc_conn := f_start_handler(refers(f_TC_paging_cs_ptp_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
	vc_conn.done;

	f_cleanup();
}

/* send CS-PAGING on SIG BVC, expect it to arrive on given list of PCU indexes */
private function f_send_paging_cs_exp_multi(template (value) Paging_Field4 p4, integer sgsn_idx := 0,
					    ro_integer exp_on_pcu_idx) runs on BSSGP_ConnHdlr
{
	var template (present) PDU_BSSGP exp_rx;
	exp_rx := f_send_paging_cs(p4, 0, true);

	/* FIXME: make sure the relevant BVCs/BSS are connected to the ports! */
	var ro_default defaults := {};
	for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
		var default d := activate(as_paging_sig_pcu(i, exp_rx, g_roi));
		defaults := defaults & { d };
	}
	f_sleep(2.0);
	for (var integer i := 0; i < lengthof(defaults); i := i+1) {
		deactivate(defaults[i]);
	}
	log("Paging received on PCU ", g_roi);

	for (var integer i := 0; i < lengthof(mp_nsconfig_pcu); i := i+1) {
		var boolean rx_on_i := ro_integer_contains(g_roi, i);
		var boolean exp_on_i := ro_integer_contains(exp_on_pcu_idx, i);
		if (exp_on_i and not rx_on_i) {
			setverdict(fail, "PS-PAGING not received on ", mp_nsconfig_pcu[i].nsei);
		}
		if (not exp_on_i and rx_on_i) {
			setverdict(fail, "PS-PAGING not expected but received on ", mp_nsconfig_pcu[i].nsei);
		}
	}
	setverdict(pass);
}

/* CS-PAGING on SIG-BVC for BSS Area */
private function f_TC_paging_cs_sig_bss(charstring id) runs on BSSGP_ConnHdlr
{
	/* we expect the paging to arrive on all three NSE */
	f_send_paging_cs_exp_multi(ts_BssgpP4BssArea, 0, {0, 1, 2});
}
testcase TC_paging_cs_sig_bss() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();

	vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bss), testcasename(), g_pcu, g_sgsn, 13);
	vc_conn.done;

	f_cleanup();
}

/* CS-PAGING on SIG-BVC for Location Area */
private function f_TC_paging_cs_sig_lac(charstring id) runs on BSSGP_ConnHdlr
{
	/* The first LAC (13135) is shared by all three NSEs */
	f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[0].cell_id.ra_id.lai), 0, {0, 1, 2});
	/* Reset state */
	g_roi := {};
	/* Make LAC (13300) available on pcu index 2 */
	f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
	f_send_paging_cs_exp_multi(ts_BssgpP4LAC(pcu_bvc_cfg[2].cell_id.ra_id.lai), 0, {2});
}
testcase TC_paging_cs_sig_lac() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();

	vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_lac), testcasename(), g_pcu, g_sgsn, 14);
	vc_conn.done;

	f_cleanup();
}

/* CS-PAGING on SIG-BVC for unknown Location Area */
private function f_TC_paging_cs_sig_lac_unknown(charstring id) runs on BSSGP_ConnHdlr
{
	var GSM_Types.LocationAreaIdentification unknown_la := {
		mcc_mnc := '567F99'H,
		lac := 33333
	};
	f_send_paging_cs_exp_no_bss(ts_BssgpP4LAC(unknown_la), 0, true);
}
testcase TC_paging_cs_sig_lac_unknown() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();

	vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_lac_unknown), testcasename(), g_pcu, g_sgsn, 11);
	vc_conn.done;

	f_cleanup();
}

/* CS-PAGING on SIG-BVC for Routeing Area */
private function f_TC_paging_cs_sig_rac(charstring id) runs on BSSGP_ConnHdlr
{
	/* Only PCU index 0 has a matching BVC with the RA ID */
	f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[0].cell_id.ra_id), 0, {0});
	g_roi := {};
	/* PCU index 1 and 2 have a matching BVC with the RA ID */
	f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {1, 2});
	g_roi := {};
	/* PCU index 2 has two matching BVCs with the RA ID */
	f_connect_to_pcu_bvc(port_idx := 2, nse_idx := 2, bvc_idx := 1);
	f_send_paging_cs_exp_multi(ts_BssgpP4RAC(pcu_bvc_cfg[2].cell_id.ra_id), 0, {2});
}
testcase TC_paging_cs_sig_rac() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();

	vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_rac), testcasename(), g_pcu, g_sgsn, 15);
	vc_conn.done;

	f_cleanup();
}

/* CS-PAGING on SIG-BVC for unknown Routeing Area */
private function f_TC_paging_cs_sig_rac_unknown(charstring id) runs on BSSGP_ConnHdlr
{
	var RoutingAreaIdentification unknown_ra := {
		lai := {
			mcc_mnc := '567F99'H,
			lac := 33333
		},
		rac := 254
	};
	f_send_paging_cs_exp_no_bss(ts_BssgpP4RAC(unknown_ra), 0, true);
}
testcase TC_paging_cs_sig_rac_unknown() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();

	vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_rac_unknown), testcasename(), g_pcu, g_sgsn, 11);
	vc_conn.done;

	f_cleanup();
}

/* CS-PAGING on SIG-BVC for BVCI (one cell) */
private function f_TC_paging_cs_sig_bvci(charstring id) runs on BSSGP_ConnHdlr
{
	f_send_paging_cs_exp_multi(ts_BssgpP4Bvci(pcu_bvc_cfg[0].bvci), 0, {0});
}
testcase TC_paging_cs_sig_bvci() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();

	vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bvci), testcasename(), g_pcu, g_sgsn, 16);
	vc_conn.done;

	f_cleanup();
}

/* CS-PAGING on SIG-BVC for unknown BVCI */
private function f_TC_paging_cs_sig_bvci_unknown(charstring id) runs on BSSGP_ConnHdlr
{
	f_send_paging_cs_exp_no_bss(ts_BssgpP4Bvci(33333), 0, true);
}
testcase TC_paging_cs_sig_bvci_unknown() runs on test_CT {
	var BSSGP_ConnHdlr vc_conn;
	f_init();

	vc_conn := f_start_handler(refers(f_TC_paging_cs_sig_bvci_unknown), testcasename(), g_pcu, g_sgsn, 11);
	vc_conn.done;

	f_cleanup();
}

private function f_TC_flush_ll(charstring id) runs on BSSGP_ConnHdlr {
	var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;
	var integer i;
	for (i := 0; i < 10; i := i+1) {
		var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);
		/* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
		var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_FLUSH_LL(g_pars.tlli, bvci, bvci_new := bvci);

		f_sgsn2pcu(pdu_tx, pdu_rx, use_sig := true);

		pdu_tx := ts_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);
		/* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
		pdu_rx := tr_BSSGP_FLUSH_LL_ACK(g_pars.tlli, int2oct(0, 1), 23, bvci_new := bvci);

		f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);
	}
	setverdict(pass);
}
testcase TC_flush_ll() runs on test_CT
{
	var BSSGP_ConnHdlr vc_conn;
	f_init();

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

	f_cleanup();
}

private altstep as_bssgp_g_pcu_count(integer pcu_idx, template (present) PDU_BSSGP exp_rx, inout ro_integer roi)
runs on GlobalTest_CT {
[] G_PCU[pcu_idx].receive(exp_rx) from g_pcu[pcu_idx].vc_BSSGP {
	if (ro_integer_contains(roi, pcu_idx)) {
		setverdict(fail, "Received multiple on same SIG BVC");
	}
	roi := roi & { pcu_idx };
	repeat;
	}
}
/* send a INVOKE-TRACE from SGSN and expect to receive a copy on each NSE */
testcase TC_trace() runs on GlobalTest_CT
{
	var BSSGP_ConnHdlr vc_conn;
	f_init();
	f_global_init();

	var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);
	var template (present) PDU_BSSGP exp_rx := ts_BSSGP_INVOKE_TRACE('23'O, '4321'O);

	var ro_default defaults := {};
	for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
		activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
	}
	G_SGSN[0].send(pdu_tx);
	f_sleep(2.0);
	for (var integer i := 0; i < lengthof(defaults); i := i+1) {
		deactivate(defaults[i]);
	}

	for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
		if (not ro_integer_contains(g_roi, i)) {
			setverdict(fail, "Failed to receive TRACE on PCU index ", i);
		}
	}
	setverdict(pass);

	f_cleanup();
}

private function f_TC_llc_discarded(charstring id) runs on BSSGP_ConnHdlr {
	var BssgpBvci bvci := g_pars.pcu[0].cfg.bvc[0].bvci;

	var template (value) PDU_BSSGP pdu_tx := ts_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);
	/* we cannot use pdu_tx as there are some subtle differences in the length field :/ */
	var template (present) PDU_BSSGP pdu_rx := tr_BSSGP_LLC_DISCARDED(g_pars.tlli, 23, bvci, 2342);

	f_pcu2sgsn(pdu_tx, pdu_rx, use_sig := true);

	setverdict(pass);
}
/* Send a LLC-DISCARDED from BSS side and expect it to show up on SGSN (SIG BVC) */
testcase TC_llc_discarded() runs on test_CT
{
	var BSSGP_ConnHdlr vc_conn;
	f_init();

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

	f_cleanup();
}

/* Send an OVERLOAD from SGSN side and expect it to show up on each PCU (SIG BVC) */
testcase TC_overload() runs on GlobalTest_CT
{
	f_init();
	f_global_init();

	var template (value) PDU_BSSGP pdu_tx := ts_OVERLOAD('1'B);
	var template (present) PDU_BSSGP exp_rx := tr_OVERLOAD('1'B);

	var ro_default defaults := {};
	for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
		activate(as_bssgp_g_pcu_count(i, exp_rx, g_roi));
	}
	G_SGSN[0].send(pdu_tx);
	f_sleep(2.0);
	for (var integer i := 0; i < lengthof(defaults); i := i+1) {
		deactivate(defaults[i]);
	}

	for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
		if (not ro_integer_contains(g_roi, i)) {
			setverdict(fail, "Failed to receive OVERLOAD on PCU index ", i);
		}
	}
	setverdict(pass);

	f_cleanup();
}

private function f_block_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
{
	var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
	var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
	var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;

	SGSN_MGMT.clear;
	PCU_MGMT.clear;

	/* block the PTP BVC from the PCU side */
	PCU_MGMT.send(BssgpBlockRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to bvc_ct;
	/* expect state on both PCU and SGSN side to change */
	interleave {
	[] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from bvc_ct;
	[] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_BLOCKED));
	}
	setverdict(pass);
}
testcase TC_bvc_block_ptp() runs on test_CT
{
	f_init();
	f_sleep(1.0);
	f_block_ptp_bvc_from_pcu(0, 0);
	f_cleanup();
}

private function f_unblock_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
{
	var BSSGP_BVC_CT bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
	var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
	var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;

	SGSN_MGMT.clear;
	PCU_MGMT.clear;

	/* block the PTP BVC from the PCU side */
	PCU_MGMT.send(BssgpUnblockRequest:{}) to bvc_ct;
	/* expect state on both PCU and SGSN side to change */
	interleave {
	[] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_UNBLOCKED)) from bvc_ct;
	[] SGSN_MGMT.receive(tr_BssgpStsInd(*, bvc_cfg.bvci, BVC_S_UNBLOCKED));
	}
	setverdict(pass);
}
testcase TC_bvc_unblock_ptp() runs on test_CT
{
	f_init();
	f_sleep(1.0);
	f_block_ptp_bvc_from_pcu(0, 0);
	f_sleep(1.0);
	f_unblock_ptp_bvc_from_pcu(0, 0);
	f_cleanup();
}

private altstep as_ignore_status(BSSGP_BVC_MGMT_PT pt) {
[] pt.receive(BssgpStatusIndication:?) { repeat; }
}
private function f_get_sgsn_bvc_ct(integer sgsn_idx, BssgpBvci bvci) runs on test_CT return BSSGP_BVC_CT {
	for (var integer i := 0; i < lengthof(g_sgsn[sgsn_idx].cfg.bvc); i := i+1) {
		if (g_sgsn[sgsn_idx].cfg.bvc[i].bvci == bvci) {
			return g_sgsn[sgsn_idx].vc_BSSGP_BVC[i];
		}
	}
	return null;
}
private function f_reset_ptp_bvc_from_pcu(integer pcu_idx, integer bvc_idx) runs on test_CT
{
	var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
	var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
	var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
	var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
	var default d;

	SGSN_MGMT.clear;
	PCU_MGMT.clear;

	/* block the PTP BVC from the PCU side */
	PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to pcu_bvc_ct;
	/* expect state on both PCU and SGSN side to change */
	d := activate(as_ignore_status(SGSN_MGMT));
	interleave {
	[] PCU_MGMT.receive(tr_BssgpStsInd(nsei_pcu, bvc_cfg.bvci, BVC_S_BLOCKED)) from pcu_bvc_ct;
	[] SGSN_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from sgsn_bvc_ct;
	}
	deactivate(d);
	setverdict(pass);
}
/* Send a BVC-RESET for a PTP BVC from the BSS side: expect it to propagate */
testcase TC_bvc_reset_ptp_from_bss() runs on test_CT
{
	f_init();
	f_sleep(3.0);
	f_reset_ptp_bvc_from_pcu(0, 0);
	f_cleanup();
}

private altstep as_count_bvc_block(integer sgsn_idx, BssgpBvci bvci, inout ro_integer roi)
runs on test_CT {
	var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(sgsn_idx, bvci);
	[] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct {
		roi := roi & { bvci };
	}
}
/* reset the signaling BVC from one BSS; expect no signaling BVC reset on SGSN; but BVC-BLOCK for PTP */
testcase TC_bvc_reset_sig_from_bss() runs on test_CT {

	f_init();
	f_sleep(3.0);

	/* Start BVC-RESET procedure for BVCI=0 */
	PCU_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_pcu[0].vc_BSSGP;

	/* Activate altsteps: One for each PTP BVC within that PCUs NSE */
	var ro_default defaults := {};
	for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
		var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
		var default d := activate(as_count_bvc_block(0, bvcc.bvci, g_roi));
		defaults := defaults & { d };
	}

	timer T := 3.0;
	T.start;
	alt {
	[] SGSN_MGMT.receive(BssgpResetIndication:{0}) {
		setverdict(fail, "BSS-side Reset of BVCI=0 should not propagate");
		}
	[] T.timeout;
	}

	for (var integer i := 0; i < lengthof(defaults); i := i+1) {
		deactivate(defaults[i]);
	}

	/* check if BVC-block was received on all expected BVC */
	for (var integer i := 0; i < lengthof(g_pcu[0].cfg.bvc); i := i+1) {
		var BssgpBvcConfig bvcc := g_pcu[0].cfg.bvc[i];
		if (not ro_integer_contains(g_roi, bvcc.bvci)) {
			setverdict(fail, "Missing SGSN-side BVC-BLOCK of BVCI=", bvcc.bvci);
		}
	}

	/* check if BVC-block was not received on any unexpected BVC is not required as
	 * such a message would basically run into 'no matching clause'  */
	setverdict(pass);
	f_cleanup();
}

private function f_reset_ptp_bvc_from_sgsn(integer pcu_idx, integer bvc_idx) runs on test_CT
{
	var BSSGP_BVC_CT pcu_bvc_ct := g_pcu[pcu_idx].vc_BSSGP_BVC[bvc_idx];
	var BssgpBvcConfig bvc_cfg := g_pcu[pcu_idx].cfg.bvc[bvc_idx];
	var Nsei nsei_pcu := g_pcu[pcu_idx].cfg.nsei;
	var BSSGP_BVC_CT sgsn_bvc_ct := f_get_sgsn_bvc_ct(0, bvc_cfg.bvci);
	var default d;

	SGSN_MGMT.clear;
	PCU_MGMT.clear;

	/* block the PTP BVC from the PCU side */
	SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to sgsn_bvc_ct;
	/* expect state on both PCU and SGSN side to change */
	d := activate(as_ignore_status(PCU_MGMT));
	interleave {
	[] SGSN_MGMT.receive(tr_BssgpStsInd(?, bvc_cfg.bvci, BVC_S_BLOCKED)) from sgsn_bvc_ct;
	[] PCU_MGMT.receive(BssgpResetIndication:{bvc_cfg.bvci}) from pcu_bvc_ct;
	}
	deactivate(d);
	setverdict(pass);
}
/* Send a BVC-RESET for a PTP BVC from the SGSN side: expect it to propagate */
testcase TC_bvc_reset_ptp_from_sgsn() runs on test_CT
{
	f_init();
	f_sleep(3.0);
	f_reset_ptp_bvc_from_sgsn(0, 0);
	f_cleanup();
}

private altstep as_count_bvc0_block(integer pcu_idx, Nsei nsei, inout ro_integer roi)
runs on test_CT {
	var BSSGP_CT pcu_ct := g_pcu[pcu_idx].vc_BSSGP;
	[] PCU_MGMT.receive(BssgpResetIndication:{0}) from pcu_ct {
		roi := roi & { nsei };
	}
}
/* reset the signaling BVC from the SGSN; expect all signaling BVC on all BSS to be reset */
testcase TC_bvc_reset_sig_from_sgsn() runs on test_CT {

	f_init();
	f_sleep(3.0);

	/* Start BVC-RESET procedure for BVCI=0 */
	SGSN_MGMT.send(BssgpResetRequest:{cause:=BSSGP_CAUSE_OM_INTERVENTION}) to g_sgsn[0].vc_BSSGP;

	/* Activate altsteps: One for each PCU NSE */
	var ro_default defaults := {};
	for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
		var NSConfiguration nscfg := mp_nsconfig_pcu[i];
		var default d := activate(as_count_bvc0_block(i, nscfg.nsei, g_roi));
		defaults := defaults & { d };
	}

	f_sleep(3.0);

	for (var integer i := 0; i < lengthof(defaults); i := i+1) {
		deactivate(defaults[i]);
	}

	/* check if BVC-block was received on all expected BVC */
	for (var integer i := 0; i < lengthof(g_pcu); i := i+1) {
		var NSConfiguration nscfg := mp_nsconfig_pcu[i];
		if (not ro_integer_contains(g_roi, nscfg.nsei)) {
			setverdict(fail, "Missing PCU-side BVC-RESET of BVCI=0 on PCU index ", i);
		}
	}

	/* check if BVC-block was not received on any unexpected BVC is not required as
	 * such a message would basically run into 'no matching clause'  */

	f_cleanup();
}

control {
	execute( TC_BVC_bringup() );
	execute( TC_ul_unitdata() );
	execute( TC_dl_unitdata() );
	execute( TC_ra_capability() );
	execute( TC_ra_capability_upd() );
	execute( TC_radio_status() );
	execute( TC_suspend() );
	execute( TC_resume() );
	execute( TC_trace() );
	execute( TC_llc_discarded() );
	execute( TC_overload() );
	execute( TC_bvc_block_ptp() );
	execute( TC_bvc_unblock_ptp() );
	execute( TC_bvc_reset_ptp_from_bss() );
	execute( TC_bvc_reset_sig_from_bss() );
	execute( TC_bvc_reset_ptp_from_sgsn() );
	execute( TC_bvc_reset_sig_from_sgsn() );
	if (false) {
		/* don't enable this by default, as we don't yet have any automatic test setup for FR with 4 NS-VC */
		execute( TC_load_sharing_dl() );
	}

	/* PAGING-PS over PTP BVC */
	execute( TC_paging_ps_ptp_bss() );
	execute( TC_paging_ps_ptp_lac() );
	execute( TC_paging_ps_ptp_lac_unknown() );
	execute( TC_paging_ps_ptp_rac() );
	execute( TC_paging_ps_ptp_rac_unknown() );
	execute( TC_paging_ps_ptp_bvci() );
	execute( TC_paging_ps_ptp_bvci_unknown() );

	/* PAGING-PS over SIG BVC */
	execute( TC_paging_ps_sig_bss() );
	execute( TC_paging_ps_sig_lac() );
	execute( TC_paging_ps_sig_lac_unknown() );
	execute( TC_paging_ps_sig_rac() );
	execute( TC_paging_ps_sig_rac_unknown() );
	execute( TC_paging_ps_sig_bvci() );
	execute( TC_paging_ps_sig_bvci_unknown() );

	/* PAGING-CS over PTP BVC */
	execute( TC_paging_cs_ptp_bss() );
	execute( TC_paging_cs_ptp_lac() );
	execute( TC_paging_cs_ptp_lac_unknown() );
	execute( TC_paging_cs_ptp_rac() );
	execute( TC_paging_cs_ptp_rac_unknown() );
	execute( TC_paging_cs_ptp_bvci() );
	execute( TC_paging_cs_ptp_bvci_unknown() );

	/* PAGING-CS over SIG BVC */
	execute( TC_paging_cs_sig_bss() );
	execute( TC_paging_cs_sig_lac() );
	execute( TC_paging_cs_sig_lac_unknown() );
	execute( TC_paging_cs_sig_rac() );
	execute( TC_paging_cs_sig_rac_unknown() );
	execute( TC_paging_cs_sig_bvci() );
	execute( TC_paging_cs_sig_bvci_unknown() );


	execute( TC_flush_ll() );
}


}
