NS_Emulation: Support multiple NS-VC within one NSE (NS-VCG)

This is something we need to simulate more complex scenarios,
particularly in the context of frame relay.

Change-Id: If1220852785853f8a5d8de183d5053ddd6ccb958
diff --git a/pcu/PCU_Tests_SNS.ttcn b/pcu/PCU_Tests_SNS.ttcn
index 86b83c2..cd0cc67 100644
--- a/pcu/PCU_Tests_SNS.ttcn
+++ b/pcu/PCU_Tests_SNS.ttcn
@@ -14,6 +14,7 @@
 import from PCU_Tests_NS all;
 import from SGSN_Components all;
 import from Osmocom_Gb_Types all;
+import from NS_Emulation all;
 import from NS_CodecPort all;
 import from NS_Types all;
 import from RAW_NS all;
@@ -27,8 +28,9 @@
 runs on RAW_NS_CT {
 	log("f_incoming_sns_size(idx=", idx, ")");
 	var PDU_NS rx;
+	var NSVCConfiguration nsvc_cfg := g_nsconfig[idx].nsvc[0];
 
-	if (mp_nsconfig.provider.ip.address_family == AF_INET) {
+	if (nsvc_cfg.provider.ip.address_family == AF_INET) {
 		/* expect one single SNS-SIZE with RESET flag; 4x v4 EP; no v6 EP */
 		rx := f_ns_exp(tr_SNS_SIZE(g_nsconfig[idx].nsei, rst_flag := true, max_nsvcs := 8,
 					   num_v4 := 4, num_v6 := omit), idx);
@@ -45,7 +47,9 @@
 runs on RAW_NS_CT {
 	log("f_outgoing_sns_size(idx=", idx, ")");
 	var PDU_NS rx;
-	if (mp_nsconfig.provider.ip.address_family == AF_INET) {
+	var NSVCConfiguration nsvc_cfg := g_nsconfig[idx].nsvc[0];
+
+	if (nsvc_cfg.provider.ip.address_family == AF_INET) {
 		NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_SIZE(g_nsconfig[idx].nsei, rst_flag := true, max_nsvcs := 1,
 								num_v4 := 1, num_v6 := omit)
 					));
@@ -63,17 +67,17 @@
 runs on RAW_NS_CT {
 	log("f_incoming_sns_config(idx=", idx, ")");
 	var PDU_NS rx;
+	var NSVCConfiguration nsvc_cfg := g_nsconfig[idx].nsvc[0];
 
-	if (mp_nsconfig.provider.ip.address_family == AF_INET) {
-		var template IP4_Elements v4_elem := { tr_SNS_IPv4(mp_nsconfig.provider.ip.remote_ip,
-								   mp_nsconfig.provider.ip.remote_udp_port) };
+	if (nsvc_cfg.provider.ip.address_family == AF_INET) {
+		var template IP4_Elements v4_elem := { tr_SNS_IPv4(nsvc_cfg.provider.ip.remote_ip,
+								   nsvc_cfg.provider.ip.remote_udp_port) };
 		rx := f_ns_exp(tr_SNS_CONFIG(g_nsconfig[idx].nsei, end_flag := true, v4 := v4_elem), idx);
 	} else {
-		var template IP6_Elements v6_elem := { tr_SNS_IPv6(mp_nsconfig.provider.ip.remote_ip,
-								   mp_nsconfig.provider.ip.remote_udp_port) };
+		var template IP6_Elements v6_elem := { tr_SNS_IPv6(nsvc_cfg.provider.ip.remote_ip,
+								   nsvc_cfg.provider.ip.remote_udp_port) };
 		rx := f_ns_exp(tr_SNS_CONFIG(g_nsconfig[idx].nsei, end_flag := true, v6 := v6_elem), idx);
 	}
-
 	NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_CONFIG_ACK(g_nsconfig[idx].nsei, cause)));
 }
 
@@ -82,13 +86,15 @@
 runs on RAW_NS_CT {
 	log("f_outgoing_sns_config(idx=", idx, ")");
 	var PDU_NS rx;
-	if (mp_nsconfig.provider.ip.address_family == AF_INET) {
-		var template (omit) IP4_Elements v4 := { ts_SNS_IPv4(g_nsconfig[idx].provider.ip.local_ip,
-								     g_nsconfig[idx].provider.ip.local_udp_port) }
+	var NSVCConfiguration nsvc_cfg := g_nsconfig[idx].nsvc[0];
+
+	if (nsvc_cfg.provider.ip.address_family == AF_INET) {
+		var template (omit) IP4_Elements v4 := { ts_SNS_IPv4(nsvc_cfg.provider.ip.local_ip,
+								     nsvc_cfg.provider.ip.local_udp_port) }
 		NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_CONFIG(g_nsconfig[idx].nsei, true, v4)));
 	} else {
-		var template (omit) IP6_Elements v6 := { ts_SNS_IPv6(g_nsconfig[idx].provider.ip.local_ip,
-								     g_nsconfig[idx].provider.ip.local_udp_port) }
+		var template (omit) IP6_Elements v6 := { ts_SNS_IPv6(nsvc_cfg.provider.ip.local_ip,
+								     nsvc_cfg.provider.ip.local_udp_port) }
 		NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_CONFIG(g_nsconfig[idx].nsei, true, omit, v6)));
 	}
 	rx := f_ns_exp(tr_SNS_CONFIG_ACK(g_nsconfig[idx].nsei, cause), idx);
@@ -99,17 +105,18 @@
 runs on RAW_NS_CT {
 	log("f_outgoing_sns_config_1c1u(idx=", idx, ")");
 	var PDU_NS rx;
-	if (mp_nsconfig.provider.ip.address_family == AF_INET) {
-		var template (omit) IP4_Elements v4 := { ts_SNS_IPv4(g_nsconfig[0].provider.ip.local_ip,
-								     g_nsconfig[0].provider.ip.local_udp_port, 1, 0),
-							 ts_SNS_IPv4(g_nsconfig[1].provider.ip.local_ip,
-								     g_nsconfig[1].provider.ip.local_udp_port, 0, 1) };
+
+	if (mp_nsconfig.nsvc[0].provider.ip.address_family == AF_INET) {
+		var template (omit) IP4_Elements v4 := { ts_SNS_IPv4(g_nsconfig[0].nsvc[0].provider.ip.local_ip,
+								     g_nsconfig[0].nsvc[0].provider.ip.local_udp_port, 1, 0),
+							 ts_SNS_IPv4(g_nsconfig[1].nsvc[0].provider.ip.local_ip,
+								     g_nsconfig[1].nsvc[0].provider.ip.local_udp_port, 0, 1) };
 		NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_CONFIG(g_nsconfig[idx].nsei, true, v4)));
 	} else {
-		var template (omit) IP6_Elements v6 := { ts_SNS_IPv6(g_nsconfig[0].provider.ip.local_ip,
-								     g_nsconfig[0].provider.ip.local_udp_port, 1, 0),
-							 ts_SNS_IPv6(g_nsconfig[1].provider.ip.local_ip,
-								     g_nsconfig[1].provider.ip.local_udp_port, 0, 1) };
+		var template (omit) IP6_Elements v6 := { ts_SNS_IPv6(g_nsconfig[0].nsvc[0].provider.ip.local_ip,
+								     g_nsconfig[0].nsvc[0].provider.ip.local_udp_port, 1, 0),
+							 ts_SNS_IPv6(g_nsconfig[1].nsvc[0].provider.ip.local_ip,
+								     g_nsconfig[1].nsvc[0].provider.ip.local_udp_port, 0, 1) };
 		NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_CONFIG(g_nsconfig[idx].nsei, true, omit, v6)));
 	}
 	rx := f_ns_exp(tr_SNS_CONFIG_ACK(g_nsconfig[idx].nsei, cause), idx);
@@ -120,17 +127,17 @@
 runs on RAW_NS_CT {
 	log("f_outgoing_sns_config_1c1u_separate(idx=", idx, ")");
 	var PDU_NS rx;
-	if (mp_nsconfig.provider.ip.address_family == AF_INET) {
-		var template (omit) IP4_Elements v4 := { ts_SNS_IPv4(g_nsconfig[1].provider.ip.local_ip,
-								     g_nsconfig[1].provider.ip.local_udp_port, 1, 0),
-							 ts_SNS_IPv4(g_nsconfig[2].provider.ip.local_ip,
-								     g_nsconfig[2].provider.ip.local_udp_port, 0, 1) };
+	if (mp_nsconfig.nsvc[0].provider.ip.address_family == AF_INET) {
+		var template (omit) IP4_Elements v4 := { ts_SNS_IPv4(g_nsconfig[1].nsvc[0].provider.ip.local_ip,
+								     g_nsconfig[1].nsvc[0].provider.ip.local_udp_port, 1, 0),
+							 ts_SNS_IPv4(g_nsconfig[2].nsvc[0].provider.ip.local_ip,
+								     g_nsconfig[2].nsvc[0].provider.ip.local_udp_port, 0, 1) };
 		NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_CONFIG(g_nsconfig[idx].nsei, true, v4)));
 	} else {
-		var template (omit) IP6_Elements v6 := { ts_SNS_IPv6(g_nsconfig[1].provider.ip.local_ip,
-								     g_nsconfig[1].provider.ip.local_udp_port, 1, 0),
-							 ts_SNS_IPv6(g_nsconfig[2].provider.ip.local_ip,
-								     g_nsconfig[2].provider.ip.local_udp_port, 0, 1) };
+		var template (omit) IP6_Elements v6 := { ts_SNS_IPv6(g_nsconfig[1].nsvc[0].provider.ip.local_ip,
+								     g_nsconfig[1].nsvc[0].provider.ip.local_udp_port, 1, 0),
+							 ts_SNS_IPv6(g_nsconfig[2].nsvc[0].provider.ip.local_ip,
+								     g_nsconfig[2].nsvc[0].provider.ip.local_udp_port, 0, 1) };
 		NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_CONFIG(g_nsconfig[idx].nsei, true, omit, v6)));
 	}
 	rx := f_ns_exp(tr_SNS_CONFIG_ACK(g_nsconfig[idx].nsei, cause), idx);
@@ -140,15 +147,16 @@
 runs on RAW_NS_CT {
 	log("f_outgoing_sns_add(idx_add=", idx_add, ")");
 	var PDU_NS rx;
-	if (mp_nsconfig.provider.ip.address_family == AF_INET) {
-		var template (omit) IP4_Elements v4 := { ts_SNS_IPv4(g_nsconfig[idx_add].provider.ip.local_ip,
-								     g_nsconfig[idx_add].provider.ip.local_udp_port,
+	var NSVCConfiguration nsvc_cfg := g_nsconfig[idx].nsvc[0];
+	if (nsvc_cfg.provider.ip.address_family == AF_INET) {
+		var template (omit) IP4_Elements v4 := { ts_SNS_IPv4(nsvc_cfg.provider.ip.local_ip,
+								     nsvc_cfg.provider.ip.local_udp_port,
 								     w_sig, w_user) };
 		NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_ADD(g_nsconfig[idx].nsei, 23, v4)));
 		rx := f_ns_exp(tr_SNS_ACK(g_nsconfig[idx].nsei, 23, omit, v4));
 	} else {
-		var template (omit) IP6_Elements v6 := { ts_SNS_IPv6(g_nsconfig[idx_add].provider.ip.local_ip,
-								     g_nsconfig[idx_add].provider.ip.local_udp_port,
+		var template (omit) IP6_Elements v6 := { ts_SNS_IPv6(nsvc_cfg.provider.ip.local_ip,
+								     nsvc_cfg.provider.ip.local_udp_port,
 								     w_sig, w_user) };
 		NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_ADD(g_nsconfig[idx].nsei, 23, omit, v6)));
 		rx := f_ns_exp(tr_SNS_ACK(g_nsconfig[idx].nsei, 23, omit, omit, v6));
@@ -159,15 +167,16 @@
 runs on RAW_NS_CT {
 	log("f_outgoing_sns_del(idx_del=", idx_del, ")");
 	var PDU_NS rx;
-	if (mp_nsconfig.provider.ip.address_family == AF_INET) {
-		var template (omit) IP4_Elements v4 := { ts_SNS_IPv4(g_nsconfig[idx_del].provider.ip.local_ip,
-								     g_nsconfig[idx_del].provider.ip.local_udp_port,
+	var NSVCConfiguration nsvc_cfg := g_nsconfig[idx_del].nsvc[0];
+	if (nsvc_cfg.provider.ip.address_family == AF_INET) {
+		var template (omit) IP4_Elements v4 := { ts_SNS_IPv4(nsvc_cfg.provider.ip.local_ip,
+								     nsvc_cfg.provider.ip.local_udp_port,
 								     w_sig, w_user) };
 		NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_DEL(g_nsconfig[idx].nsei, 24, omit, v4)));
 		rx := f_ns_exp(tr_SNS_ACK(g_nsconfig[idx].nsei, 24, omit, v4));
 	} else {
-		var template (omit) IP6_Elements v6 := { ts_SNS_IPv6(g_nsconfig[idx_del].provider.ip.local_ip,
-								     g_nsconfig[idx_del].provider.ip.local_udp_port,
+		var template (omit) IP6_Elements v6 := { ts_SNS_IPv6(nsvc_cfg.provider.ip.local_ip,
+								     nsvc_cfg.provider.ip.local_udp_port,
 								     w_sig, w_user) };
 		NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_DEL(g_nsconfig[idx].nsei, 24, omit, omit, v6)));
 		rx := f_ns_exp(tr_SNS_ACK(g_nsconfig[idx].nsei, 24, omit, omit, v6));
@@ -178,15 +187,16 @@
 runs on RAW_NS_CT {
 	log("f_outgoing_sns_chg_weight(idx_chg=", idx_chg, ")");
 	var PDU_NS rx;
-	if (mp_nsconfig.provider.ip.address_family == AF_INET) {
-		var template (omit) IP4_Elements v4 := { ts_SNS_IPv4(g_nsconfig[idx_chg].provider.ip.local_ip,
-								     g_nsconfig[idx_chg].provider.ip.local_udp_port,
+	var NSVCConfiguration nsvc_cfg := g_nsconfig[idx_chg].nsvc[0];
+	if (nsvc_cfg.provider.ip.address_family == AF_INET) {
+		var template (omit) IP4_Elements v4 := { ts_SNS_IPv4(nsvc_cfg.provider.ip.local_ip,
+								     nsvc_cfg.provider.ip.local_udp_port,
 								     w_sig, w_user) };
 		NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_CHG_WEIGHT(g_nsconfig[idx].nsei, 25, v4)));
 		rx := f_ns_exp(tr_SNS_ACK(g_nsconfig[idx].nsei, 25, omit, v4));
 	} else {
-		var template (omit) IP6_Elements v6 := { ts_SNS_IPv6(g_nsconfig[idx_chg].provider.ip.local_ip,
-								     g_nsconfig[idx_chg].provider.ip.local_udp_port,
+		var template (omit) IP6_Elements v6 := { ts_SNS_IPv6(nsvc_cfg.provider.ip.local_ip,
+								     nsvc_cfg.provider.ip.local_udp_port,
 								     w_sig, w_user) };
 		NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_CHG_WEIGHT(g_nsconfig[idx].nsei, 25, omit, v6)));
 		rx := f_ns_exp(tr_SNS_ACK(g_nsconfig[idx].nsei, 25, omit, omit, v6));