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 {
	integer mp_num_bvc := 10;
	integer mp_num_ue_in_bvc := 10;
	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];
};

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

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;
	}
}

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());

	fn.apply(id);
	f_bssgp_client_unregister(g_pars.imsi);
}

function f_ul_ud(charstring id) runs on UE_CT {

	log("Waiting for BVC-UNBLOCK");
	alt {
	[] BSSGP[0].receive(BssgpStatusIndication:{*,?,BVC_S_UNBLOCKED}) { }
	[] BSSGP[0].receive { repeat; }
	}

	log ("Entering main loop");
	while (true) {
		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);
	}
}

function f_start_ue(void_fn fn, charstring id, GbInstance gb, integer imsi_suffix, BSSGP_BVC_CT bvc_comp, float t_guard := 30.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;
}


testcase TC_foo() 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 < mp_num_ue_in_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(refers(f_ul_ud), id, g_gb[i], i*10000+j*100+k, bvc_comp);
				ues := ues & { ue };
				/* a bit of staggering to ensure the timers above don't run all at the same time */
				f_sleep(0.05);
			}
		}
	}

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

control {
	execute( TC_foo() );
}

}
