Add Osmux support and tests for MGW

Depends: osmo-mgw.git Iac073f1db46569b46eddeaecc9934a2986bd50f1
Change-Id: Ibb58b2a4e08d6f30cfe347c217794d0d1310954f
diff --git a/library/MGCP_Templates.ttcn b/library/MGCP_Templates.ttcn
index 506100f..4cc2c6b 100644
--- a/library/MGCP_Templates.ttcn
+++ b/library/MGCP_Templates.ttcn
@@ -49,6 +49,12 @@
 		val := hex2str(cid)
 	};
 
+	/* Osmocom extension: X-Osmux: {*,%u} */
+	template MgcpParameter ts_MgcpParOsmuxCID(MgcpOsmuxCID osmux_cid) := {
+		code := "X-OSMUX",
+		val := f_mgcp_osmux_cid_encode(osmux_cid)
+	};
+
 	/* osmo-bsc_mgcp implements L/C/M/X only, osmo-mgw adds 'I' */
 	/* SDP: osmo-bsc_mgcp implements Tx of v,o,s,c,t,m,a */
 
@@ -89,6 +95,18 @@
 		sdp := sdp
 	}
 
+	template MgcpCommand ts_CRCX_osmux(MgcpTransId trans_id, charstring ep, MgcpConnectionMode mode, MgcpCallId call_id, MgcpOsmuxCID osmux_cid, template SDP_Message sdp := omit) := {
+		line := t_MgcpCmdLine("CRCX", trans_id, ep),
+		params := {
+			t_MgcpParConnMode(mode),
+			ts_MgcpParCallId(call_id),
+			//t_MgcpParReqId(omit),
+			t_MgcpParLocConnOpt("p:20, a:AMR"),
+			ts_MgcpParOsmuxCID(osmux_cid)
+		},
+		sdp := sdp
+	}
+
 	template MgcpCommand tr_CRCX(template MgcpEndpoint ep := ?) := {
 		line := t_MgcpCmdLine("CRCX", ?, ep),
 		params := *,
@@ -105,6 +123,16 @@
 		sdp := ?
 	}
 
+	template MgcpResponse tr_CRCX_ACK_osmux := {
+		line := {
+			code := "200",
+			trans_id := ?,
+			string := "OK"
+		},
+		params:= { { "I", ? }, {"X-OSMUX", ?}, *},
+		sdp := ?
+	}
+
 	template MgcpResponse ts_CRCX_ACK(MgcpTransId trans_id, MgcpConnectionId conn_id, template SDP_Message sdp := omit) := {
 		line := {
 			code := "200",
@@ -127,6 +155,19 @@
 		sdp := sdp
 	}
 
+	template MgcpCommand ts_MDCX_osmux(MgcpTransId trans_id, charstring ep, MgcpConnectionMode mode, MgcpCallId call_id, MgcpConnectionId conn_id, MgcpOsmuxCID osmux_cid, template SDP_Message sdp := omit) := {
+		line := t_MgcpCmdLine("MDCX", trans_id, ep),
+		params := {
+			t_MgcpParConnMode(mode),
+			ts_MgcpParCallId(call_id),
+			ts_MgcpParConnectionId(conn_id),
+			//t_MgcpParReqId(omit),
+			t_MgcpParLocConnOpt("p:20, a:AMR"),
+			ts_MgcpParOsmuxCID(osmux_cid)
+		},
+		sdp := sdp
+	}
+
 	template MgcpCommand tr_MDCX := {
 		line := t_MgcpCmdLine("MDCX", ?, ?),
 		params := *,
@@ -286,6 +327,21 @@
 		}
 	}
 
+	/* -1 is wildcard, positive is translated as string */
+	function f_mgcp_osmux_cid_encode(MgcpOsmuxCID osmux_cid) return charstring {
+		if (osmux_cid == -1) {
+			return "*";
+		}
+		return int2str(osmux_cid);
+	}
+
+	function f_mgcp_osmux_cid_decode(charstring osmux_cid) return MgcpOsmuxCID {
+		if (osmux_cid == "*") {
+			return -1;
+		}
+		return str2int(osmux_cid);
+	}
+
 	function f_mgcp_contains_par(MgcpMessage msg, MgcpInfoCode code) return boolean {
 		var MgcpParameterList pars;
 		if (ischosen(msg.command)) {
@@ -352,6 +408,10 @@
 		return str2hex(f_MgcpCmd_extract_par(cmd, "I"));
 	}
 
+	function f_MgcpCmd_extract_osmux_cid(MgcpCommand cmd) return MgcpOsmuxCID {
+		return f_mgcp_osmux_cid_decode(f_MgcpCmd_extract_par(cmd, "X-OSMUX"));
+	}
+
 
 	function f_mgcp_alloc_tid() return MgcpTransId {
 		return int2str(float2int(rnd()*2147483647.0));