BTS_Tests.ttcn: introduce TC_ho_rach() for handover RACH

The idea of this test case (as can bee seen from its name) is to
verify handover RACH detection. What we basically do is:

1. Activate a logical channel on the BTS side (HO_SYNC for now);
2. Switch the MS (e.g. trxcon) to that channel without waiting
   for Immediate Assignment and sending Access Burst;
3. Send an Access Burst on that channel using RA = HO_REF;
4. Wait for RSL HANDOver DETected from the BTS;
5. Release a dedicated connection.

There is no way to verify if the Handover Reference received
from the MS matches the one that was sent to the BTS. We can
introduce a separate test case that would just send an Access
Burst with RA != HO_REF.

Change-Id: If2e8d9c9947823df62f4bcc9a7fcd20734ff7858
Depends on: (trxcon) Ia967820a536c99966ba2c60b63d2ea9edb093f46
diff --git a/bts/BTS_Tests.ttcn b/bts/BTS_Tests.ttcn
index edf056a..ed1d8e1 100644
--- a/bts/BTS_Tests.ttcn
+++ b/bts/BTS_Tests.ttcn
@@ -1493,6 +1493,75 @@
 	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
 }
 
+function f_TC_ho_rach(charstring id) runs on ConnHdlr {
+	var GsmFrameNumber fn;
+	var RSL_Message rm;
+
+	f_l1_tune(L1CTL);
+	RSL.clear;
+
+	/* Generate a random Handover Reference */
+	var integer ho_ref := oct2int(f_rnd_octstring(1));
+
+	/* Handover Reference IE (see 3GPP TS 48.058, 9.3.9) */
+	var RSL_IE ho_ref_ie := valueof(t_RSL_IE(RSL_IE_HANDO_REF,
+					RSL_IE_Body:{ handover_ref := ho_ref }));
+
+	/* Activate a channel on the BTS side (no encryption) */
+	f_rsl_chan_act(g_pars.chan_mode, more_ies := { ho_ref_ie },
+		       act_type := t_RSL_IE_ActType_HO_SYNC);
+
+	/* Switch the MS side (e.g. trxcon) to a dedicated channel without
+	 * waiting for Immediate Assignment and sending Access Burst */
+	f_L1CTL_DM_EST_REQ(L1CTL, { false, mp_trx0_arfcn }, g_pars.chan_nr, 7);
+
+	/* Send handover Access Burst */
+	fn := f_L1CTL_RACH(L1CTL, ho_ref, chan_nr := g_pars.chan_nr);
+
+	/* TODO: test mismatching Handover Reference, and missing IE */
+
+	/* Wait for handover detection */
+	timer T := 3.0;
+	T.start;
+	alt {
+	[] RSL.receive(tr_RSL_HANDO_DET(g_pars.chan_nr)) -> value rm {
+		log("Handover RACH has been detected: ", rm);
+		setverdict(pass);
+		}
+	[] RSL.receive(tr_RSL_CHAN_RQD(?, ?, ?, ?)) -> value rm {
+		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
+			log2str("RSL_CHAN_RQD was not expected: ", rm));
+		}
+	[] RSL.receive { repeat; }
+	[] T.timeout {
+		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
+			log2str("Timeout waiting for handover RACH: FN=", fn, " RA=", ho_ref));
+		}
+	}
+
+	/* Release the channel */
+	f_rsl_chan_deact();
+	f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr);
+}
+
+/* Test handover RACH detection */
+testcase TC_ho_rach() runs on test_CT {
+	var ConnHdlrPars pars;
+	var ConnHdlr vc_conn;
+
+	f_init();
+
+	for (var integer i := 0; i < sizeof(g_AllChannels); i := i + 1) {
+		pars := valueof(t_Pars(g_AllChannels[i], ts_RSL_ChanMode_SIGN));
+		log(testcasename(), ": Starting for ", g_AllChannels[i]);
+		vc_conn := f_start_handler(refers(f_TC_ho_rach), pars);
+		vc_conn.done;
+	}
+
+	/* TODO: do the above in parallel, rather than sequentially? */
+	Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
+}
+
 /***********************************************************************
  * Measurement Processing / Reporting
  ***********************************************************************/
@@ -5458,6 +5527,7 @@
 	execute( TC_rach_content() );
 	execute( TC_rach_count() );
 	execute( TC_rach_max_ta() );
+	execute( TC_ho_rach() );
 	execute( TC_rach_load_idle_thresh0() );
 	execute( TC_rach_load_idle_below_thresh() );
 	execute( TC_rach_load_count() );