BTS_Tests: Add support for PCUIF protocol version 11

The PCUIF protocol version 11 uses a more distinct (direct TLLI) way
to signal PAGING COMMAND and IMMEDIATE ASSIGNMENT messages towards the PCU.

Since OsmoBTS will soon fully support v.11 of the PCUIF protocol we need
to add compatibility in the OsmoBTS TTCN3 testsuite early. We also have
to stay compatible with older versions of OsmoBTS. The BTS_Tests.default
config still sets up mp_pcuif_version to version 10, so this will be the
default until we have full version 11 support in current master and
latest.

Related: OS#5927
Change-Id: I08de02e951e10bc8b4381cc2ad32e63f2747e3c4
diff --git a/bts/BTS_Tests.ttcn b/bts/BTS_Tests.ttcn
index fddfcca..f59cc89 100644
--- a/bts/BTS_Tests.ttcn
+++ b/bts/BTS_Tests.ttcn
@@ -5812,8 +5812,17 @@
 	f_l1_tune(L1CTL);
 
 	f_TC_pcu_act_req(0, 0, 7, true);
-	/* three characters prefix: last 3 digits of IMSI as ASCII */
-	f_pcu_data_req(0, 0, 7, 0, 0, PCU_IF_SAPI_PCH, '313233'O & c_PCU_DATA);
+
+	if (mp_pcuif_version < 11) {
+		/* three characters prefix: last 3 digits of IMSI as ASCII */
+		f_pcu_data_req(0, 0, 7, 0, 0, PCU_IF_SAPI_PCH, '313233'O & c_PCU_DATA);
+	} else {
+		var PCUIF_pch_dt pch_dt;
+		pch_dt.tlli := '01020304'O;
+		pch_dt.imsi := "00101000000000123";
+		pch_dt.data := c_PCU_DATA;
+		f_pcu_data_req(0, 0, 7, 0, 0, PCU_IF_SAPI_PCH_DT, enc_PCUIF_pch_dt(pch_dt));
+	}
 
 	T.start;
 	alt {
diff --git a/library/PCUIF_CodecPort.ttcn b/library/PCUIF_CodecPort.ttcn
index f3e4810..0f850e9 100644
--- a/library/PCUIF_CodecPort.ttcn
+++ b/library/PCUIF_CodecPort.ttcn
@@ -15,6 +15,7 @@
 import from PCUIF_Types all;
 import from UD_PortType all;
 import from UD_Types all;
+import from General_Types all;
 
 type record PCUIF_send_data {
 	PCUIF_Message	data,
@@ -139,18 +140,27 @@
 }
 
 function f_PCUIF_tx_imm_ass_pch(PCUIF_CODEC_PT pt, integer conn_id, octetstring imm_ass, hexstring imsi,
-				uint8_t bts_nr := 0, boolean wait_for_cnf := true) return uint32_t {
+				uint8_t bts_nr := 0, boolean wait_for_cnf := true, OCT4 tlli := '01020304'O) return uint32_t {
 	var PCUIF_send_data sd;
 	timer T := 3.0;
-	/* append 3 last imsi digits so BTS can compute pagng group */
-	var hexstring last_digits := substr(imsi, lengthof(imsi)-3, 3);
-	var octetstring prefix := ''O;
-	log("3 last imsi digits: ", last_digits);
-	for (var integer i := 0; i < 3; i := i+1) {
-		prefix := prefix & int2oct(hex2int('30'H) + hex2int(last_digits[i]), 1);
-	}
-	pt.send(t_SD_PCUIF(conn_id,
+
+	if (mp_pcuif_version < 11) {
+		/* append 3 last imsi digits so that the BTS is able to compute paging group */
+		var hexstring last_digits := substr(imsi, lengthof(imsi)-3, 3);
+		log("3 last imsi digits: ", last_digits);
+		var octetstring prefix := ''O;
+		for (var integer i := 0; i < 3; i := i+1) {
+			prefix := prefix & int2oct(hex2int('30'H) + hex2int(last_digits[i]), 1);
+		}
+		pt.send(t_SD_PCUIF(conn_id,
 			ts_PCUIF_DATA_REQ(bts_nr, 0, 0, 0, 0, PCU_IF_SAPI_PCH, prefix & imm_ass)));
+	} else {
+		var PCUIF_pch_dt pch_dt;
+		pch_dt.tlli := tlli;
+		pch_dt.imsi := hex2str(imsi);
+		pch_dt.data := imm_ass;
+		pt.send(t_SD_PCUIF(conn_id, ts_PCUIF_DATA_REQ(bts_nr, 0, 0, 0, 0, PCU_IF_SAPI_PCH_DT, enc_PCUIF_pch_dt(pch_dt))));
+	}
 
 	/* Exit early when the caller is not interested in the confirmation message */
 	if (wait_for_cnf == false) {
@@ -159,10 +169,23 @@
 
 	T.start;
 	alt {
-	[] pt.receive(t_SD_PCUIF(conn_id,
-				tr_PCUIF_DATA_CNF(bts_nr, 0, 0, PCU_IF_SAPI_PCH))) -> value sd {
-		log("IMM.ASS was sent on fn ", sd.data.u.data_cnf.fn);
-		return sd.data.u.data_cnf.fn;
+	[] pt.receive(t_SD_PCUIF(conn_id, tr_PCUIF_DATA_CNF(bts_nr, 0, 0, PCU_IF_SAPI_PCH))) -> value sd {
+		if (mp_pcuif_version >= 11) {
+			setverdict(fail, "expecting tr_PCUIF_DATA_CNF_DT in PCUIF v.11 or later");
+			mtc.stop;
+		} else {
+			log("IMM.ASS was sent on fn ", sd.data.u.data_cnf.fn);
+			return sd.data.u.data_cnf.fn;
+		}
+		}
+	[] pt.receive(t_SD_PCUIF(conn_id, tr_PCUIF_DATA_CNF_DT(bts_nr, 0, 0, PCU_IF_SAPI_PCH_DT))) -> value sd {
+		if (mp_pcuif_version < 11) {
+			setverdict(fail, "expecting tr_PCUIF_DATA_CNF in PCUIF v.10 or earlier");
+			mtc.stop;
+		} else {
+			log("IMM.ASS was sent on fn ", sd.data.u.data_cnf_dt.fn);
+			return sd.data.u.data_cnf_dt.fn;
+		}
 		}
 	[] pt.receive { repeat; }
 	[] T.timeout {
diff --git a/library/PCUIF_Types.ttcn b/library/PCUIF_Types.ttcn
index 8f5d4eb..65d0c41 100644
--- a/library/PCUIF_Types.ttcn
+++ b/library/PCUIF_Types.ttcn
@@ -17,11 +17,11 @@
 
 modulepar {
 	/* PCUIF version supported by the IUT */
-	PCUIF_Version mp_pcuif_version := 10;
+	PCUIF_Version mp_pcuif_version := 11;
 };
 
 const charstring PCU_SOCK_DEFAULT := "/tmp/pcu_bts";
-type integer PCUIF_Version (9..10); /* supported versions */
+type integer PCUIF_Version (9..11); /* supported versions */
 
 type enumerated PCUIF_MsgType {
 	PCU_IF_MSG_DATA_REQ		('00'O),
@@ -324,6 +324,9 @@
 	variant (data) "FIELDLENGTH(23)"
 };
 
+external function enc_PCUIF_pch_dt(in PCUIF_pch_dt pdu) return octetstring
+	with { extension "prototype(convert) encode(RAW)" };
+
 type union PCUIF_MsgUnion {
 	PCUIF_data		data_req,
 	PCUIF_data		data_cnf,
@@ -374,7 +377,6 @@
 external function dec_PCUIF_Message(in octetstring stream) return PCUIF_Message
 	with { extension "prototype(convert) decode(RAW)" };
 
-
 /* Generic template for matching messages by type and/or the BTS number */
 template PCUIF_Message tr_PCUIF_MSG(template PCUIF_MsgType msg_type := ?,
 				    template uint8_t bts_nr := ?) := {