RTP_Emulation: Several fixes and improvements for IuUP streams

* Immediate tx of IuUP (N)ACK control packets. Without this, INIT ACK
is delayed until the TX side of the RTP endpoint is enabled.

* Allow and handle IuUP control messages even if g_rx_enabled is false.

* Properly validate user data payload if IuUP is in use.

Change-Id: Id4f8b02a8123bb30b659c40148c8ab4c7c2078a1
diff --git a/library/RTP_Emulation.ttcn b/library/RTP_Emulation.ttcn
index bdca75d..8c5dbc9 100644
--- a/library/RTP_Emulation.ttcn
+++ b/library/RTP_Emulation.ttcn
@@ -502,9 +502,22 @@
 		}
 
 
-		/* simply ignore any RTTP/RTP if receiver not enabled */
-		[not g_rx_enabled] RTP.receive(tr_rtp) {
-			g_stats_rtp.num_pkts_rx_err_disabled := g_stats_rtp.num_pkts_rx_err_disabled+1;
+		/* simply ignore any RTCP/RTP if receiver not enabled */
+		[not g_rx_enabled] RTP.receive(tr_rtp) -> value rx_rtp {
+			/* In IuUP we need to decode possible Control packets, such as INIT-ACK: */
+			if (g_cfg.iuup_mode) {
+				/* In IuUP we need to decode possible Control packets, such as INIT-ACK: */
+				rx_rtp.msg.rtp.data := f_IuUP_Em_rx_decaps(g_iuup_ent, rx_rtp.msg.rtp.data);
+				if (lengthof(rx_rtp.msg.rtp.data) != 0) {
+					/* Unexpected RTP payload (user data) arrived: */
+					g_stats_rtp.num_pkts_rx_err_disabled := g_stats_rtp.num_pkts_rx_err_disabled+1;
+				} else if (isvalue(g_iuup_ent.pending_tx_pdu)) {
+					/* IuUP Control packet was received and requires sending back something: */
+					f_tx_rtp(''O);
+				}
+			} else {
+				g_stats_rtp.num_pkts_rx_err_disabled := g_stats_rtp.num_pkts_rx_err_disabled+1;
+			}
 			}
 		[not g_rx_enabled] RTCP.receive(tr_rtcp) {
 			g_stats_rtcp.num_pkts_rx_err_disabled := g_stats_rtcp.num_pkts_rx_err_disabled+1;
@@ -519,11 +532,18 @@
 			g_stats_rtp.num_pkts_rx := g_stats_rtp.num_pkts_rx+1;
 			g_stats_rtp.bytes_payload_rx := g_stats_rtp.bytes_payload_rx +
 								lengthof(rx_rtp.msg.rtp.data);
-			if (ispresent(g_cfg.rx_fixed_payload) and rx_rtp.msg.rtp.data != g_cfg.rx_fixed_payload) {
-				g_stats_rtp.num_pkts_rx_err_payload := g_stats_rtp.num_pkts_rx_err_payload + 1;
-			}
 			if (g_cfg.iuup_mode) {
 				rx_rtp.msg.rtp.data := f_IuUP_Em_rx_decaps(g_iuup_ent, rx_rtp.msg.rtp.data);
+				/* IuUP Control packet was received which may require sending back something: */
+				if (lengthof(rx_rtp.msg.rtp.data) == 0) {
+					if (isvalue(g_iuup_ent.pending_tx_pdu)) {
+						f_tx_rtp(''O);
+					}
+					repeat;
+				}
+			}
+			if (ispresent(g_cfg.rx_fixed_payload) and rx_rtp.msg.rtp.data != g_cfg.rx_fixed_payload) {
+				g_stats_rtp.num_pkts_rx_err_payload := g_stats_rtp.num_pkts_rx_err_payload + 1;
 			}
 			if (DATA.checkstate("Connected")) {
 				DATA.send(rx_rtp.msg.rtp);