BSSGP_Emulation: Support multiple PTP-BVC within one Entity

The existing BSSGP_Emulation is built around the assumption that every
instance of BSSGP_Emulation only servers one signaling-BVC and one
PTP-BVC.  While this is true for osmo-pcu at this point (BTS-colocated
PCU), other BSS/PCU implementations differ.

In general, there can always be any number of PTP BVC (one per cell)
next to the signaling BVC (one per BSS).  Let's represent this in
BSSGP_Emulation so we can create more comprehensive tests.

Change-Id: I7e30b4c4e188518a574e082962fba457b3a97ce3
diff --git a/sgsn/SGSN_Tests.ttcn b/sgsn/SGSN_Tests.ttcn
index 8a87ee2..53ecdff 100644
--- a/sgsn/SGSN_Tests.ttcn
+++ b/sgsn/SGSN_Tests.ttcn
@@ -130,9 +130,11 @@
 	}
 };
 
+const integer NUM_BVC_PER_NSE := 1;
 type record GbInstance {
 	NS_CT vc_NS,
 	BSSGP_CT vc_BSSGP,
+	BSSGP_BVC_CT vc_BSSGP_BVC[NUM_BVC_PER_NSE],
 	BssgpConfig cfg
 };
 
@@ -154,6 +156,9 @@
 	/* only to get events from IPA underneath GSUP */
 	port IPA_CTRL_PT GSUP_IPA_EVENT;
 
+	/* only needed at start to get the per-BVC references */
+	port BSSGP_CT_PROC_PT PROC;
+
 	var GTP_Emulation_CT vc_GTP;
 
 	port TELNETasp_PT SGSNVTY;
@@ -223,7 +228,13 @@
 	connect(gb.vc_BSSGP:BSCP, gb.vc_NS:NS_SP);
 
 	gb.vc_NS.start(NSStart(mp_nsconfig[offset]));
-	gb.vc_BSSGP.start(BssgpStart(gb.cfg));
+	gb.vc_BSSGP.start(BssgpStart(gb.cfg, testcasename()));
+	/* resolve the per-BVC component references */
+	for (var integer i := 0; i < lengthof(gb.cfg.bvc); i := i+1) {
+		connect(self:PROC, gb.vc_BSSGP:PROC);
+		gb.vc_BSSGP_BVC[i] := f_bssgp_get_bvci_ct(gb.cfg.bvc[i].bvci, PROC);
+		disconnect(self:PROC, gb.vc_BSSGP:PROC);
+	}
 }
 
 private function f_init_gsup(charstring id) runs on test_CT {
@@ -297,45 +308,63 @@
 	g_initialized := true;
 	g_gb[0].cfg := {
 		nsei := 96,
-		bvci := 196,
-		cell_id := {
-			ra_id := {
-				lai := {
-					mcc_mnc := mcc_mnc, lac := 13135},
-					rac := 0
-				},
-			cell_id := 20960
-		},
 		sgsn_role := false,
-		depth := BSSGP_DECODE_DEPTH_L3
+		bvc := {
+			{
+				bvci := 196,
+				cell_id := {
+					ra_id := {
+						lai := {
+							mcc_mnc := mcc_mnc,
+							lac := 13135
+						},
+						rac := 0
+					},
+					cell_id := 20960
+				},
+				depth := BSSGP_DECODE_DEPTH_L3
+			}
+		}
 	};
 	g_gb[1].cfg := {
 		nsei := 97,
-		bvci := 210,
-		cell_id := {
-			ra_id := {
-				lai := {
-					mcc_mnc := mcc_mnc, lac := 13200},
-					rac := 0
-				},
-			cell_id := 20961
-		},
 		sgsn_role := false,
-		depth := BSSGP_DECODE_DEPTH_L3
+		bvc := {
+			{
+				bvci := 210,
+				cell_id := {
+					ra_id := {
+						lai := {
+							mcc_mnc := mcc_mnc,
+							lac := 13200
+						},
+						rac := 0
+					},
+					cell_id := 20961
+				},
+				depth := BSSGP_DECODE_DEPTH_L3
+			}
+		}
 	};
 	g_gb[2].cfg := {
 		nsei := 98,
-		bvci := 220,
-		cell_id := {
-			ra_id := {
-				lai := {
-					mcc_mnc := mcc_mnc, lac := 13300},
-					rac := 0
-				},
-			cell_id := 20962
-		},
 		sgsn_role := false,
-		depth := BSSGP_DECODE_DEPTH_L3
+		bvc := {
+			{
+				bvci := 220,
+				cell_id := {
+					ra_id := {
+						lai := {
+							mcc_mnc := mcc_mnc,
+							lac := 13300
+						},
+						rac := 0
+					},
+					cell_id := 20962
+				},
+				depth := BSSGP_DECODE_DEPTH_L3
+			}
+		}
 	};
 
 	f_init_vty();
@@ -413,7 +442,11 @@
 		tlli := f_gprs_tlli_random(),
 		tlli_old := omit,
 		ra := omit,
-		bssgp_cell_id := { gb[0].cfg.cell_id, gb[1].cfg.cell_id, gb[2].cfg.cell_id },
+		bssgp_cell_id := {
+			gb[0].cfg.bvc[0].cell_id,
+			gb[1].cfg.bvc[0].cell_id,
+			gb[2].cfg.bvc[0].cell_id
+		},
 		rnc_send_initial_ue := true,
 		vec := omit,
 		net := net_pars,
@@ -428,15 +461,18 @@
 	}
 
 	vc_conn := BSSGP_ConnHdlr.create(id);
-	connect(vc_conn:BSSGP[0], gb[0].vc_BSSGP:BSSGP_SP);
-	connect(vc_conn:BSSGP_SIG[0], gb[0].vc_BSSGP:BSSGP_SP_SIG);
-	connect(vc_conn:BSSGP_PROC[0], gb[0].vc_BSSGP:BSSGP_PROC);
-	connect(vc_conn:BSSGP[1], gb[1].vc_BSSGP:BSSGP_SP);
-	connect(vc_conn:BSSGP_SIG[1], gb[1].vc_BSSGP:BSSGP_SP_SIG);
-	connect(vc_conn:BSSGP_PROC[1], gb[1].vc_BSSGP:BSSGP_PROC);
-	connect(vc_conn:BSSGP[2], gb[2].vc_BSSGP:BSSGP_SP);
-	connect(vc_conn:BSSGP_SIG[2], gb[2].vc_BSSGP:BSSGP_SP_SIG);
-	connect(vc_conn:BSSGP_PROC[2], gb[2].vc_BSSGP:BSSGP_PROC);
+
+	connect(vc_conn:BSSGP[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_SP);
+	connect(vc_conn:BSSGP_SIG[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
+	connect(vc_conn:BSSGP_PROC[0], gb[0].vc_BSSGP_BVC[0]:BSSGP_PROC);
+
+	connect(vc_conn:BSSGP[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_SP);
+	connect(vc_conn:BSSGP_SIG[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
+	connect(vc_conn:BSSGP_PROC[1], gb[1].vc_BSSGP_BVC[0]:BSSGP_PROC);
+
+	connect(vc_conn:BSSGP[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_SP);
+	connect(vc_conn:BSSGP_SIG[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_SP_SIG);
+	connect(vc_conn:BSSGP_PROC[2], gb[2].vc_BSSGP_BVC[0]:BSSGP_PROC);
 
 	/* FIXME: support multiple RNCs */
 	if (g_ranap_enable) {
@@ -470,7 +506,7 @@
 	llc := f_llc_create(false);
 
 	/* register with BSSGP core */
-	f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
+	f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
 	/* tell GSUP dispatcher to send this IMSI to us */
 	f_create_gsup_expect(hex2str(g_pars.imsi));
 	/* tell GTP dispatcher to send this IMSI to us */
@@ -1091,7 +1127,7 @@
 
 	/* Simulate a foreign IMSI */
 	g_pars.imsi := '001010123456789'H;
-	f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
+	f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
 
 	g_pars.net.expect_auth := false;
 
@@ -2344,7 +2380,7 @@
 	f_bssgp_client_unregister(g_pars.imsi);
 	/* Simulate a foreign IMSI */
 	g_pars.imsi := '001010123456700'H;
-	f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[0]);
+	f_bssgp_client_register(g_pars.imsi, g_pars.tlli);
 
 	/* there is no auth */
 	g_pars.net.expect_auth := false;
@@ -2522,7 +2558,7 @@
 
 	log("rau complete unregistering");
 	f_bssgp_client_unregister(g_pars.imsi);
-	f_bssgp_client_register(g_pars.imsi, g_pars.tlli, g_pars.bssgp_cell_id[1], BSSGP_PROC[1]);
+	f_bssgp_client_register(g_pars.imsi, g_pars.tlli, BSSGP_PROC[1]);
 
 	log("sending second RAU via different RA");
 	f_routing_area_update(f_cellid_to_RAI(g_pars.bssgp_cell_id[1]), 1);