stp: Support testing multi-home SCTP features with IPv4+IPv6

The IP addr module parameter is split now, IPA module has its own set
of configurable addresses, and M3UA its own. Moreover, in M3UA the
single address is transformed to be an array of addresses, to support
multi-homing with both IPv4 and IPv6 addresses.

Related: SYS#4915
Change-Id: Ib1925ed1df5cea3fa66f28b5625532d454a2c338
diff --git a/stp/STP_Tests_M3UA.ttcn b/stp/STP_Tests_M3UA.ttcn
index 68cea2a..22272f3 100644
--- a/stp/STP_Tests_M3UA.ttcn
+++ b/stp/STP_Tests_M3UA.ttcn
@@ -35,6 +35,8 @@
 import from STP_Tests_Common all;
 
 modulepar {
+	HostList mp_stp_m3ua_ip := { "127.0.0.1", "::1" };
+	HostList mp_local_m3ua_ip := { "127.0.0.1", "::1" };
 	integer mp_stp_m3ua_port := 2905;
 	integer mp_stp_m3ua_clnt_port := 2906;
 	integer mp_local_m3ua_port := 9999;
@@ -92,14 +94,54 @@
 	}
 }
 
+private template (value) Socket ts_Socket(HostName hostName, PortNumber portNumber) := {
+	hostName := hostName,
+        portNumber := portNumber
+};
+
+private template (value) SctpTuple ts_SCTP(template (omit) integer ppid := 3,
+					   template (omit) integer stream := 0,
+					   template (omit) SocketList remSocks := omit) := {
+	sinfo_stream := stream,
+	sinfo_ppid := ppid,
+	remSocks := remSocks,
+	assocId := omit
+};
+
 friend function f_M3UA_connect(integer i) runs on RAW_M3UA_CT {
 	var Result res;
-	res := M3UA_CodecPort_CtrlFunct.f_IPL4_connect(M3UA[i], mp_stp_ip, mp_stp_m3ua_port,
-						       mp_local_ip, mp_local_m3ua_port+i, 0,
-							{sctp:=valueof(ts_SCTP)});
+	var Option opt_add_local_addrs;
+	var OptionList opt_list := {};
+	var template SocketList opt_add_remote_addrs;
+
+	if (lengthof(mp_local_m3ua_ip) == 0 or lengthof(mp_stp_m3ua_ip) == 0) {
+		setverdict(fail, "Empty local or remote address trying to connect SCTP socket: ",
+			   mp_local_m3ua_ip, " / ", mp_stp_m3ua_ip);
+		mtc.stop;
+	}
+
+	if (lengthof(mp_local_m3ua_ip) > 1) {
+		opt_add_local_addrs.sctpAdditionalLocalAddresses := substr(mp_local_m3ua_ip, 1,
+								           lengthof(mp_local_m3ua_ip) - 1); //{mp_local_m3ua_ip};
+		opt_list := {opt_add_local_addrs};
+	}
+
+	if (lengthof(mp_stp_m3ua_ip) > 1) {
+		for (var integer j := 1; j < lengthof(mp_stp_m3ua_ip); j := j + 1) {
+			var Socket sk := valueof(ts_Socket(mp_stp_m3ua_ip[j], mp_stp_m3ua_port));
+			opt_add_remote_addrs[j - 1] := sk;
+		}
+	} else {
+		opt_add_remote_addrs := omit;
+	}
+
+	res := M3UA_CodecPort_CtrlFunct.f_IPL4_connect(M3UA[i], mp_stp_m3ua_ip[0], mp_stp_m3ua_port,
+						       mp_local_m3ua_ip[0], mp_local_m3ua_port+i, 0,
+						       {sctp:=valueof(ts_SCTP(3, 0, opt_add_remote_addrs))},
+						       opt_list);
 	if (not ispresent(res.connId)) {
 		setverdict(fail, "Could not connect M3UA socket, check your configuration");
-	mtc.stop;
+		mtc.stop;
 	}
 	g_m3ua_conn_id[i] := res.connId;
 }
@@ -112,11 +154,26 @@
 
 friend function f_M3UA_listen(integer i) runs on RAW_M3UA_CT {
 	var Result res;
-	res := M3UA_CodecPort_CtrlFunct.f_IPL4_listen(M3UA[i], mp_local_ip, mp_local_m3ua_port+i,
-							{sctp:=valueof(ts_SCTP)});
+	var Option opt_add_local_addrs;
+	var OptionList opt_list := {};
+
+	if (lengthof(mp_local_m3ua_ip) == 0 ) {
+		setverdict(fail, "Empty local address trying to bind SCTP socket: ",
+			   mp_local_m3ua_ip);
+		mtc.stop;
+	}
+
+	if (lengthof(mp_local_m3ua_ip) > 1) {
+		opt_add_local_addrs.sctpAdditionalLocalAddresses := substr(mp_local_m3ua_ip, 1,
+								           lengthof(mp_local_m3ua_ip) - 1); //{mp_local_m3ua_ip};
+		opt_list := {opt_add_local_addrs};
+	}
+
+	res := M3UA_CodecPort_CtrlFunct.f_IPL4_listen(M3UA[i], mp_local_m3ua_ip[0], mp_local_m3ua_port+i,
+						      {sctp:=valueof(ts_SCTP)}, opt_list);
 	if (not ispresent(res.connId)) {
 		setverdict(fail, "Could not bind M3UA socket, check your configuration");
-	mtc.stop;
+		mtc.stop;
 	}
 }