module FR_Tests {

import from General_Types all;
import from Osmocom_Types all;
import from Osmocom_Gb_Types all;

import from NS_Emulation all;
import from BSSGP_Emulation all;
import from LLC_Templates all;

modulepar {
	/* number of BVCs to bring up in one Gb instance */
	integer mp_num_bvc := 10;
	/* number of UEs to start in each PTP BVC */
	integer mp_num_ue_in_bvc := 10;
	/* NS configurations; one per NSE; each with any number of NSVC */
	NSConfigurations mp_nsconfig := {
		{
			nsei := 123,
			role_sgsn := false,
			handle_sns := false,
			nsvc := {
				{
					provider := {
						fr := {
							netdev := "hdlc1",
							dlci := 123
						}
					},
					nsvci := 123
				}
			}
		}
	};
}

type record GbInstance {
	NS_CT vc_NS,
	BSSGP_CT vc_BSSGP,
	BssgpConfig cfg
};

type record of GbInstance GbInstances;
type record of NSConfiguration NSConfigurations;
type record of BssgpCellId BssgpCellIds;


type component test_CT {
	var GbInstances g_gb;
	port BSSGP_CT_PROC_PT BSSGP_PROC[16];
};

/* initialize one Gb interface */
private function f_init_gb(inout GbInstance gb, charstring id, integer offset) runs on test_CT {
	var charstring id_idx := id & int2str(offset);
	gb.vc_NS := NS_CT.create(id_idx & "-NSemu");
	gb.vc_BSSGP := BSSGP_CT.create(id_idx & "-BSSGPemu");
	connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
	gb.vc_NS.start(NSStart(mp_nsconfig[offset], id_idx));
	connect(self:BSSGP_PROC[offset], gb.vc_BSSGP:PROC);
	gb.vc_BSSGP.start(BssgpStart(gb.cfg, testcasename()));
}

/* generate a BVC dynamically, using distinct number ranges for BVCI, CID, LAC, ... */
private function f_gen_bvc(integer base, integer idx) return BssgpBvcConfig {
	var BssgpBvcConfig bvc := {
		bvci := base + 100 + idx,
		cell_id := {
			ra_id := {
				lai := {
					mcc_mnc := '262F42'H,
					lac := base + 300 + idx
				},
				rac := 1
			},
			cell_id := base + 600 + idx
		},
		depth := BSSGP_DECODE_DEPTH_LLC,
		create_cb := refers(BSSGP_Emulation.DefaultCreateCallback)
	};
	return bvc;
}

/***********************************************************************
 * UE simulation component
 ***********************************************************************/

type component UE_CT extends BSSGP_Client_CT {
	var UE_Pars g_pars;
	timer g_Tguard;
	var LLC_Entities llc;
}
type record of UE_CT ro_ue;

type record UE_Pars {
	hexstring imsi,
	OCT4 tlli,
	float tguard
};

type function void_fn(charstring id) runs on UE_CT;

private altstep as_ue_tguard() runs on UE_CT {
[] g_Tguard.timeout {
	setverdict(fail, "Tguard timeout after ", g_pars.tguard);
	self.stop;
	}
}

/* first function executed in UE_CT; creates LLC context, registers with BSSGP, starts Tguard */
function f_handler_init(void_fn fn, charstring id, UE_Pars pars) runs on UE_CT {
	g_pars := pars;
	llc := f_llc_create(false);
	f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
	g_Tguard.start(g_pars.tguard);
	activate(as_ue_tguard());

	log(id, " Waiting for BVC-UNBLOCK");
	timer T := 15.0;
	T.start;
	alt {
	[] BSSGP[0].receive(BssgpStatusIndication:{*,?,BVC_S_UNBLOCKED}) { }
	[] BSSGP[0].receive { repeat; }
	[] T.timeout {
		setverdict(fail, id, " Timeout waiting for BVC-UNBLOCK");
		self.stop;
		}
	}

	log (id, " Entering main loop");
	fn.apply(id);
	log (id, "Leaving main loop");
	f_bssgp_client_unregister(g_pars.imsi);
}

/* start a single UE component; connect it to BSSGP */
function f_start_ue(void_fn fn, charstring id, GbInstance gb, integer imsi_suffix, BSSGP_BVC_CT bvc_comp, float t_guard := 40.0)
runs on test_CT return UE_CT
{
	var UE_CT ue_comp;
	var UE_Pars ue_pars := {
		imsi := f_gen_imsi(imsi_suffix),
		tlli := f_gprs_tlli_random(),
		tguard := t_guard
	};

	ue_comp := UE_CT.create(id);
	connect(ue_comp:BSSGP[0], bvc_comp:BSSGP_SP);
	connect(ue_comp:BSSGP_SIG[0], bvc_comp:BSSGP_SP_SIG);
	connect(ue_comp:BSSGP_PROC[0], bvc_comp:BSSGP_PROC);
	ue_comp.start(f_handler_init(fn, id, ue_pars));

	return ue_comp;
}


/* main test case body function; start Gb instances, start UE_CTs on top; wait for termination */
private function f_tc_body(void_fn ue_fn, integer ue_per_bvc := mp_num_ue_in_bvc,
			   float delay_between_ue := 0.005, float ue_tguard := 40.0) runs on test_CT {
	var ro_ue ues := {};

	for (var integer i := 0; i < lengthof(mp_nsconfig); i := i+1) {
		g_gb[i].cfg := {
			nsei := mp_nsconfig[i].nsei,
			sgsn_role := false,
			bvc := { }
		};
		/* create 'mp_num_bvc' number of BVCs */
		for (var integer j := 0; j < mp_num_bvc; j := j+1) {
			g_gb[i].cfg.bvc := g_gb[i].cfg.bvc & { f_gen_bvc(i * 1000, j) };
		}
		log("Initializing Gb interface ", i, ": NSEI=", g_gb[i].cfg.nsei);
		f_init_gb(g_gb[i], "gb", i);
	}

	for (var integer i := 0; i < lengthof(mp_nsconfig); i := i+1) {
		for (var integer j := 0; j < mp_num_bvc; j := j+1) {
			var BSSGP_BVC_CT bvc_comp := f_bssgp_get_bvci_ct(g_gb[i].cfg.bvc[j].bvci, BSSGP_PROC[i]);
			for (var integer k := 0; k < ue_per_bvc; k := k+1) {
				var charstring id := "gb" & int2str(i) & "-bvc" & int2str(g_gb[i].cfg.bvc[j].bvci) & "-UEsim" & int2str(k);
				var UE_CT ue;
				ue := f_start_ue(ue_fn, id, g_gb[i], i*10000+j*100+k, bvc_comp,
ue_tguard);
				ues := ues & { ue };
				/* a bit of staggering to ensure the timers above don't run all at the same time */
				f_sleep(delay_between_ue);
				/* FIXME: as the BSSGP emulation is already running, we must not
				 * take too long to start the UE components.  If we do, the
				 * BVC_S_UNBLOCKED notification will arrive before the components
				 * all are running, meaning we never get that one :( */
			}
		}
	}

	/* wait for all UE components to terminate */
	for (var integer i := 0; i < lengthof(ues); i := i + 1) {
		ues[i].done;
	}
	setverdict(pass);
}

private function f_ul_ud(charstring id) runs on UE_CT
{
	for (var integer num_pkts := 0; num_pkts < 50; num_pkts := num_pkts + 1) {
		var integer ran_index := 0;
		//BSSGP[ran_index].send(ts_BSSGP_UL_UD(g_pars.tlli, g_pars.bssgp_cell_id[ran_index], llc_enc));
		BSSGP[ran_index].send(ts_LLC_UI(f_rnd_octstring(512), '0000'B, '1'B, 0))
		f_sleep(0.5);
		/* 512 bytes + 32 bytes HDR every 0.5s (1088/s) means about 8704/s per UE */
		/* at 100 UE that ends up about 870 kBps */
	}
}
/* Generate uplink-unitdata traffic */
testcase TC_ul_ud() runs on test_CT
{
	f_tc_body(refers(f_ul_ud));
}


/* test bring-up of all BVCs */
private function f_pass(charstring id) runs on UE_CT
{
	setverdict(pass);
}
testcase TC_bvc_bringup() runs on test_CT
{
	f_tc_body(refers(f_pass), ue_per_bvc := 1, ue_tguard := 20.0);
}


control {
	execute( TC_bvc_bringup() );
	execute( TC_ul_ud() );
}

}
