hnbgw: prepare cn pool: add multiple MSCs and SGSNs

Change-Id: Ia29565cabc072de9aa46565b57232e1eda65874f
diff --git a/hnbgw/HNBGW_Tests.ttcn b/hnbgw/HNBGW_Tests.ttcn
index e9db214..f38fc0c 100644
--- a/hnbgw/HNBGW_Tests.ttcn
+++ b/hnbgw/HNBGW_Tests.ttcn
@@ -62,6 +62,14 @@
 import from PFCP_CodecPort all;
 
 import from TCCConversion_Functions all;
+import from MobileL3_Types all;
+import from L3_Templates all;
+
+const integer NUM_MSC := 4;
+const integer NUM_SGSN := 4;
+
+const integer FIRST_MSC_IDX := 0;
+const integer FIRST_SGSN_IDX := NUM_MSC;
 
 modulepar {
 	/* IP address at which the HNodeB can be reached */
@@ -75,27 +83,98 @@
 	charstring mp_mgw_ip := "127.0.0.1";
 	integer mp_mgw_port := 2427;
 
-	RAN_Configuration mp_msc_cfg := {
-		transport := RANAP_TRANSPORT_IuCS,
-		sccp_service_type := "mtp3_itu",
-		sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" },
-		own_pc := 188,	/* 0.23.4 first MSC emulation */
-		own_ssn := 142,
-		peer_pc := 189, /* 0.23.5 osmo-hnbgw */
-		peer_ssn := 142,
-		sio := '83'O,
-		rctx := 1
-	};
-	RAN_Configuration mp_sgsn_cfg := {
-		transport := RANAP_TRANSPORT_IuCS,
-		sccp_service_type := "mtp3_itu",
-		sctp_addr := { /* local */ 23906, "127.0.0.1", /* remote */ 2905, "127.0.0.1" },
-		own_pc := 185,	/* 0.23.1 first SGSN emulation */
-		own_ssn := 142,
-		peer_pc := 189, /* 0.23.5 osmo-hnbgw */
-		peer_ssn := 142,
-		sio := '83'O,
-		rctx := 2
+	RAN_Configurations mp_cn_cfg := {
+		/* MSCs (NUM_MSC entries) */
+		{
+			transport := RANAP_TRANSPORT_IuCS,
+			sccp_service_type := "mtp3_itu",
+			sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" },
+			own_pc := 188,	/* 0.23.4 first MSC emulation */
+			own_ssn := 142,
+			peer_pc := 189, /* 0.23.5 osmo-hnbgw */
+			peer_ssn := 142,
+			sio := '83'O,
+			rctx := 1
+		},
+		{
+			transport := RANAP_TRANSPORT_IuCS,
+			sccp_service_type := "mtp3_itu",
+			sctp_addr := { 23907, "127.0.0.1", 2905, "127.0.0.1" },
+			own_pc := 2,	/* 0.0.2 second MSC emulation */
+			own_ssn := 142,
+			peer_pc := 189, /* 0.23.5 osmo-hnbgw */
+			peer_ssn := 142,
+			sio := '83'O,
+			rctx := 3
+		},
+		{
+			transport := RANAP_TRANSPORT_IuCS,
+			sccp_service_type := "mtp3_itu",
+			sctp_addr := { 23909, "127.0.0.1", 2905, "127.0.0.1" },
+			own_pc := 3,	/* 0.0.3 third MSC emulation */
+			own_ssn := 142,
+			peer_pc := 189, /* 0.23.5 osmo-hnbgw */
+			peer_ssn := 142,
+			sio := '83'O,
+			rctx := 5
+		},
+		{
+			transport := RANAP_TRANSPORT_IuCS,
+			sccp_service_type := "mtp3_itu",
+			sctp_addr := { 23911, "127.0.0.1", 2905, "127.0.0.1" },
+			own_pc := 4,	/* 0.0.4 fourth MSC emulation */
+			own_ssn := 142,
+			peer_pc := 189, /* 0.23.5 osmo-hnbgw */
+			peer_ssn := 142,
+			sio := '83'O,
+			rctx := 7
+		},
+
+		/* SGSNs (NUM_SGSN entries) */
+		{
+			transport := RANAP_TRANSPORT_IuCS,
+			sccp_service_type := "mtp3_itu",
+			sctp_addr := { /* local */ 23906, "127.0.0.1", /* remote */ 2905, "127.0.0.1" },
+			own_pc := 185,	/* 0.23.1 first SGSN emulation */
+			own_ssn := 142,
+			peer_pc := 189, /* 2237, 1.23.5 osmo-hnbgw */
+			peer_ssn := 142,
+			sio := '83'O,
+			rctx := 2
+		},
+		{
+			transport := RANAP_TRANSPORT_IuCS,
+			sccp_service_type := "mtp3_itu",
+			sctp_addr := { /* local */ 23908, "127.0.0.1", /* remote */ 2905, "127.0.0.1" },
+			own_pc := 10,	/* 0.1.2 second SGSN emulation */
+			own_ssn := 142,
+			peer_pc := 189, /* 2237, 1.23.5 osmo-hnbgw */
+			peer_ssn := 142,
+			sio := '83'O,
+			rctx := 4
+		},
+		{
+			transport := RANAP_TRANSPORT_IuCS,
+			sccp_service_type := "mtp3_itu",
+			sctp_addr := { /* local */ 23910, "127.0.0.1", /* remote */ 2905, "127.0.0.1" },
+			own_pc := 11,	/* 0.1.3 third SGSN emulation */
+			own_ssn := 142,
+			peer_pc := 189, /* 2237, 1.23.5 osmo-hnbgw */
+			peer_ssn := 142,
+			sio := '83'O,
+			rctx := 6
+		},
+		{
+			transport := RANAP_TRANSPORT_IuCS,
+			sccp_service_type := "mtp3_itu",
+			sctp_addr := { /* local */ 23912, "127.0.0.1", /* remote */ 2905, "127.0.0.1" },
+			own_pc := 12,	/* 0.1.4 fourth SGSN emulation */
+			own_ssn := 142,
+			peer_pc := 189, /* 2237, 1.23.5 osmo-hnbgw */
+			peer_ssn := 142,
+			sio := '83'O,
+			rctx := 8
+		}
 	};
 
 	boolean mp_enable_pfcp_tests := false;
@@ -179,6 +258,9 @@
 
 type record TestHdlrParams {
 	integer hnb_idx,
+	/* cn_idx indicates which CN link from g_cn[] to connect to the test component.
+	 * See also f_cn_idx(). */
+	integer cn_idx,
 	hexstring imsi,
 	boolean ps_domain,
 	MgcpParameters mgcp_pars optional,
@@ -225,9 +307,7 @@
 	var boolean g_initialized := false;
 
 	/********************* Iu side */
-	var RAN_Adapter g_msc;
-	var RAN_Adapter g_sgsn;
-	/* SGSN IuPS missing */
+	var RAN_Adapter g_cn[NUM_MSC + NUM_SGSN];
 
 	/********************* Iuh side */
 	var HnbConfig g_hnb_cfg[NUM_HNB];
@@ -326,7 +406,7 @@
 }
 
 /* global initialization function */
-function f_init(charstring id := "HNBGW", float guard_timeout := 30.0) runs on test_CT {
+function f_init(charstring id := "HNBGW", float guard_timeout := 30.0, integer nr_msc := 1, integer nr_sgsn := 1) runs on test_CT {
 
 	T_guard.start(guard_timeout);
 	activate(as_Tguard());
@@ -361,13 +441,19 @@
 		sccp_addr_local := omit,
 		sccp_addr_peer := omit
 	};
-	f_ran_adapter_init(g_msc, mp_msc_cfg, "HNBGW_Test", ranops);
-	f_ran_adapter_start(g_msc);
+	for (var integer i := 0; i < nr_msc; i := i + 1) {
+		var integer cn_idx := FIRST_MSC_IDX + i;
+		f_ran_adapter_init(g_cn[cn_idx], mp_cn_cfg[cn_idx], "HNBGW_Test", ranops);
+		f_ran_adapter_start(g_cn[cn_idx]);
+	}
 
 	/* SGSN emulation */
 	ranops.ps_domain := true;
-	f_ran_adapter_init(g_sgsn, mp_sgsn_cfg, "HNBGW_Test", ranops);
-	f_ran_adapter_start(g_sgsn);
+	for (var integer i := 0; i < nr_sgsn; i := i + 1) {
+		var integer cn_idx := FIRST_SGSN_IDX + i;
+		f_ran_adapter_init(g_cn[cn_idx], mp_cn_cfg[cn_idx], "HNBGW_Test", ranops);
+		f_ran_adapter_start(g_cn[cn_idx]);
+	}
 
 	f_init_mgcp(id);
 	f_init_vty("VirtHNBGW");
@@ -415,15 +501,10 @@
 	/* Iuh RUA part */
 	connect(vc_conn:RUA, vc_RUA[pars.hnb_idx]:CLIENT);
 
-	if (pars.ps_domain) {
-		/* SGSN side */
-		connect(vc_conn:BSSAP, g_sgsn.vc_RAN:CLIENT);
-		connect(vc_conn:BSSAP_PROC, g_sgsn.vc_RAN:PROC);
-	} else {
-		/* MSC side */
-		connect(vc_conn:BSSAP, g_msc.vc_RAN:CLIENT);
-		connect(vc_conn:BSSAP_PROC, g_msc.vc_RAN:PROC);
-	}
+	/* MSC or SGSN */
+	connect(vc_conn:BSSAP, g_cn[pars.cn_idx].vc_RAN:CLIENT);
+	connect(vc_conn:BSSAP_PROC, g_cn[pars.cn_idx].vc_RAN:PROC);
+
 	/* MGCP part */
 	connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
 	connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
@@ -799,10 +880,28 @@
  * RUA / RANAP Testing
  ***********************************************************************/
 
+/* Translate from {msc,sgsn}x{0..n} to the proper index to use in g_cn[].
+ * g_cn[] stores CN links, MSCs and SGSNs in the same array.
+ * For example, for 'sgsn 23', use g_cn[ f_cn_idx(ps_domain := true, cn_nr := 23) ].
+ *
+ * Note the naming:
+ * cn_nr is the number used in the cfg file, as in 'msc 0'.
+ * cn_idx is the array index in g_cn[].
+ */
+private function f_cn_idx(boolean ps_domain, integer cn_nr := 0) return integer
+{
+	if (ps_domain) {
+		return FIRST_SGSN_IDX + cn_nr;
+	}
+	return FIRST_MSC_IDX + cn_nr;
+}
+
 private template (value) TestHdlrParams
 t_pars(integer imsi_suffix, boolean ps_domain := false, integer hnb_idx := 0,
-       boolean expect_separate_sccp_cr := false, integer tx_sccp_cr_data_len := 0) := {
+       boolean expect_separate_sccp_cr := false, integer tx_sccp_cr_data_len := 0,
+       integer cn_nr := 0) := {
 	hnb_idx := hnb_idx,
+	cn_idx := f_cn_idx(ps_domain, cn_nr),
 	imsi := f_gen_imsi(imsi_suffix),
 	ps_domain := ps_domain,
 	hnb := omit,	/* filled in later */