pcu: Support sending message to PCU at specific FN

Change-Id: I81a29b4885f3fc6b753a1612d5fd369cd18f5dc6
diff --git a/pcu/PCUIF_RAW_Components.ttcn b/pcu/PCUIF_RAW_Components.ttcn
index 5516d83..4ed57e5 100644
--- a/pcu/PCUIF_RAW_Components.ttcn
+++ b/pcu/PCUIF_RAW_Components.ttcn
@@ -228,6 +228,18 @@
 	}
 }
 
+/* Get first message from queue. true if non-empty, false otherwise */
+private function f_PCUIF_MsgQueue_first(inout PCUIF_MsgQueue queue,
+					out PCUIF_Message msg) return boolean
+{
+	if (lengthof(queue) == 0) {
+		return false;
+	}
+
+	msg := queue[0];
+	return true;
+}
+
 /* Multiple base stations can be connected to the PCU. This component
  * represents one BTS with an associated TDMA clock generator. */
 type component RAW_PCU_BTS_CT {
@@ -250,6 +262,9 @@
 	var boolean cfg_ptcch_burst_fwd := false;
 }
 
+/* Queue received messages from Test Case, they will eventually be scheduled and
+ * sent according to their FN. FN value of 0 has the special meaning of "schedule
+ * as soon as possible". */
 private altstep as_BTS_CT_MsgQueue(integer bts_nr)
 runs on RAW_PCU_BTS_CT {
 	var PCUIF_Message pcu_msg;
@@ -274,11 +289,14 @@
 		}
 }
 
+/* Handle schedule events and manage actions: Send msgs over PCUIF to PCU,
+ * advertise Test Case about sent messages, etc. */
 private altstep as_BTS_CT_TDMASched(integer bts_nr)
 runs on RAW_PCU_BTS_CT {
 	var PCUIF_Message pcu_msg;
 	var RAW_PCU_Event event;
 	var integer ev_begin_fn;
+	var integer next_fn;
 
 	[] CLCK.receive(tr_RAW_PCU_EV(TDMA_EV_PDTCH_BLOCK_BEG)) -> value event {
 		/* If the RTS queue for PDTCH is not empty, send a message */
@@ -299,6 +317,17 @@
 	[lengthof(pdtch_data_queue) > 0] CLCK.receive(tr_RAW_PCU_EV(TDMA_EV_PDTCH_BLOCK_END)) -> value event {
 		/* FN matching the beginning of current block: */
 		ev_begin_fn := event.data.tdma_fn - 3;
+
+		/* Check if we reached time to serve the first DATA.ind message in the queue: */
+		f_PCUIF_MsgQueue_first(pdtch_data_queue, pcu_msg);
+		next_fn := pcu_msg.u.data_ind.fn;
+		if (next_fn != 0 and next_fn != ev_begin_fn) {
+			if (next_fn < ev_begin_fn) {
+				setverdict(fail, "We are late scheduling the block! ", next_fn, " < ", ev_begin_fn);
+				mtc.stop;
+			}
+			repeat;
+		}
 		/* Dequeue a DATA.ind message */
 		f_PCUIF_MsgQueue_dequeue(pdtch_data_queue, pcu_msg);