library: RTP_Emulation: implement new RTPEM_MODE_LOOPBACK

Change-Id: Iee8f736e1eebc357fc997353ee4b629d24dc09e7
Related: OS#1572
diff --git a/library/RTP_Emulation.ttcn b/library/RTP_Emulation.ttcn
index 539ea45..de2c877 100644
--- a/library/RTP_Emulation.ttcn
+++ b/library/RTP_Emulation.ttcn
@@ -97,6 +97,7 @@
 	var PortNumber g_local_port;
 
 	/* state variables, change over time */
+	var boolean g_loopback := false;
 	var boolean g_rx_enabled := false;
 	var boolean g_tx_connected := false; /* Set to true after connect() */
 	var LIN2_BO_LAST g_tx_next_seq := 0;
@@ -116,7 +117,8 @@
 	RTPEM_MODE_NONE,
 	RTPEM_MODE_TXONLY,
 	RTPEM_MODE_RXONLY,
-	RTPEM_MODE_BIDIR
+	RTPEM_MODE_BIDIR,
+	RTPEM_MODE_LOOPBACK
 };
 
 type record RtpemStats {
@@ -512,12 +514,14 @@
 		[] CTRL.getcall(RTPEM_mode:{RTPEM_MODE_NONE}) {
 			T_transmit.stop;
 			g_rx_enabled := false;
+			g_loopback := false;
 			CTRL.reply(RTPEM_mode:{RTPEM_MODE_NONE});
 		}
 		[] CTRL.getcall(RTPEM_mode:{RTPEM_MODE_TXONLY}) {
 			/* start transmit timer */
 			T_transmit.start;
 			g_rx_enabled := false;
+			g_loopback := false;
 			CTRL.reply(RTPEM_mode:{RTPEM_MODE_TXONLY});
 		}
 		[] CTRL.getcall(RTPEM_mode:{RTPEM_MODE_RXONLY}) {
@@ -529,6 +533,7 @@
 				RTCP.clear;
 				g_rx_enabled := true;
 			}
+			g_loopback := false;
 			CTRL.reply(RTPEM_mode:{RTPEM_MODE_RXONLY});
 		}
 		[] CTRL.getcall(RTPEM_mode:{RTPEM_MODE_BIDIR}) {
@@ -539,8 +544,20 @@
 				RTCP.clear;
 				g_rx_enabled := true;
 			}
+			g_loopback := false;
 			CTRL.reply(RTPEM_mode:{RTPEM_MODE_BIDIR});
 		}
+		[] CTRL.getcall(RTPEM_mode:{RTPEM_MODE_LOOPBACK}) {
+			T_transmit.stop;
+			if (g_rx_enabled == false) {
+				/* flush queues */
+				RTP.clear;
+				RTCP.clear;
+				g_rx_enabled := true;
+			}
+			g_loopback := true;
+			CTRL.reply(RTPEM_mode:{RTPEM_MODE_LOOPBACK});
+		}
 		[] CTRL.getcall(RTPEM_configure:{?}) -> param (cfg) {
 			g_cfg := cfg;
 			g_iuup_ent.cfg := g_cfg.iuup_cfg;
@@ -599,8 +616,16 @@
 				}
 			}
 
-			/* Match the received payload against any of the predefined fixed rx payloads */
-			f_check_fixed_rx_payloads(rx_rtp.msg.rtp.payload_type, rx_rtp.msg.rtp.data);
+			if (g_loopback) {
+				f_tx_rtp(rx_rtp.msg.rtp.data, rx_rtp.msg.rtp.payload_type);
+				/* update counters */
+				g_stats_rtp.num_pkts_tx := g_stats_rtp.num_pkts_tx + 1;
+				g_stats_rtp.bytes_payload_tx := g_stats_rtp.bytes_payload_tx
+							      + lengthof(rx_rtp.msg.rtp.data);
+			} else {
+				/* Match the received payload against any of the predefined fixed rx payloads */
+				f_check_fixed_rx_payloads(rx_rtp.msg.rtp.payload_type, rx_rtp.msg.rtp.data);
+			}
 
 			if (DATA.checkstate("Connected")) {
 				DATA.send(rx_rtp.msg.rtp);