module RTP_Emulation {

/* Functionalities that we want this module to imeplement:
 *  * act as a RTP source that generates a RTP Stream
 *  * act asaa RTP sink that consumes a RTP Stream
 *
 * for all of the above, we want to be able to 
 *  * specify the payload type
 *  * specify the interval / sample rate
 *  * create drop-outs in the stream
 *  * detect reordered or lost frames
 *  * validate if the size of the frames matches epectations
 *  * play back real audio (at least some tones?)
 *  * enable/disable generation/verification of RTCP
 */

/* Ideas:

* each component consists of transmitter and receiver
* transmitters and receivers can be operated as tuple?
* high-level operation
** set-up config at transmitter + receiver
** transmit sequence of payloads
** verify receiption of those payloads
* can operate full-duplex/bi-directional as needed

* transmitter
** trigger transmission of n number of packets
** transmit them at normal ptime interval
** payload size configurable
** payload contents PRBS or the like

* receiver
** count number of related packets at receiver
** check received payload type
** check received timestamp increments
** check received seq_nr increments
** (optionally) check for SSRC
** (optionally) check for payload size
** (optionally) check for payload contents

* later
** how to test transcoding?
** how to test pure play-out endpoints (rx only)?
** how to test "Rx from wrong IP/port" scenarios?
** how to test RTCP?
** maybe keep ports un-connected to show wrong src -lrt

*/




import from General_Types all;
import from Osmocom_Types all;
import from IPL4asp_Types all;
import from RTP_Types all;
import from RTP_CodecPort all;
import from RTP_CodecPort_CtrlFunct all;

import from IuUP_Types all;
import from IuUP_Emulation all;

type component RTP_Emulation_CT {
	/* down-facing ports for RTP and RTCP codec ports on top of IPL4asp */
	port RTP_CODEC_PT RTP;
	var integer g_rtp_conn_id := -1;
	port RTP_CODEC_PT RTCP;
	var integer g_rtcp_conn_id := -1;

	/* user-facing port for controlling the binding */
	port RTPEM_CTRL_PT CTRL;

	/* configurable by user, should be fixed */
	var RtpemConfig g_cfg := c_RtpemDefaultCfg;

	/* statistics */
	var RtpemStats g_stats_rtp := c_RtpemStatsReset;
	var RtpemStats g_stats_rtcp := c_RtpemStatsReset;

	var HostName g_remote_host;
	var PortNumber g_remote_port;
	var HostName g_local_host;
	var PortNumber g_local_port;

	/* state variables, change over time */
	var boolean g_rx_enabled := false;
	var LIN2_BO_LAST g_tx_next_seq := 0;
	var uint32_t g_tx_next_ts := 0;

	var INT7b g_rx_payload_type := 0;
	var LIN2_BO_LAST g_rx_last_seq;
	var uint32_t g_rx_last_ts;

	var IuUP_Entity g_iuup_ent; // := valueof(t_IuUP_Entity(1));
}

type enumerated RtpemMode {
	RTPEM_MODE_NONE,
	RTPEM_MODE_TXONLY,
	RTPEM_MODE_RXONLY,
	RTPEM_MODE_BIDIR
};

type record RtpemStats {
	/* number of packets transmitted */
	integer num_pkts_tx,
	/* number of RTP payload bytes transmitted */
	integer bytes_payload_tx,

	/* number of packets received */
	integer num_pkts_rx,
	/* number of RTP payload bytes received */
	integer bytes_payload_rx,
	/* number of packets received out-of-sequence */
	integer num_pkts_rx_err_seq,
	/* number of packets received wrong timestamp */
	integer num_pkts_rx_err_ts,
	/* number of packets received wrong payload type */
	integer num_pkts_rx_err_pt,
	/* number of packets received during Rx disable */
	integer num_pkts_rx_err_disabled,
	/* number of packets received with mismatching payload */
	integer num_pkts_rx_err_payload
}

const RtpemStats c_RtpemStatsReset := {
	num_pkts_tx := 0,
	bytes_payload_tx := 0,
	num_pkts_rx := 0,
	bytes_payload_rx := 0,
	num_pkts_rx_err_seq := 0,
	num_pkts_rx_err_ts := 0,
	num_pkts_rx_err_pt := 0,
	num_pkts_rx_err_disabled := 0,
	num_pkts_rx_err_payload := 0
}

type record RtpemConfig {
	INT7b tx_payload_type,
	integer tx_samplerate_hz,
	integer tx_duration_ms,
	BIT32_BO_LAST tx_ssrc,
	octetstring tx_fixed_payload optional,
	octetstring rx_fixed_payload optional,
	boolean iuup_mode,
	boolean iuup_tx_init
};

const RtpemConfig c_RtpemDefaultCfg := {
	tx_payload_type := 0,
	tx_samplerate_hz := 8000,
	tx_duration_ms := 20,
	tx_ssrc := '11011110101011011011111011101111'B,
	tx_fixed_payload := '01020304'O,
	rx_fixed_payload := '01020304'O,
	iuup_mode := false,
	iuup_tx_init := true
}

signature RTPEM_bind(in HostName local_host, inout PortNumber local_port);
signature RTPEM_connect(in HostName remote_host, in PortNumber remote_port);
signature RTPEM_mode(in RtpemMode mode);
signature RTPEM_configure(in RtpemConfig cfg);
signature RTPEM_stats_get(out RtpemStats stats, in boolean rtcp);

type port RTPEM_CTRL_PT procedure {
	inout RTPEM_bind, RTPEM_connect, RTPEM_mode, RTPEM_configure, RTPEM_stats_get;
} with { extension "internal" };

function f_rtpem_bind(RTPEM_CTRL_PT pt, in HostName local_host, inout PortNumber local_port) {
	pt.call(RTPEM_bind:{local_host, local_port}) {
		[] pt.getreply(RTPEM_bind:{local_host, ?}) -> param (local_port) {};
	}
}
function f_rtpem_connect(RTPEM_CTRL_PT pt, in HostName remote_host, in PortNumber remote_port) {
	pt.call(RTPEM_connect:{remote_host, remote_port}) {
		[] pt.getreply(RTPEM_connect:{remote_host, remote_port}) {};
	}
}
function f_rtpem_mode(RTPEM_CTRL_PT pt, in RtpemMode mode) {
	pt.call(RTPEM_mode:{mode}) {
		[] pt.getreply(RTPEM_mode:{mode}) {};
	}
}
function f_rtpem_configure(RTPEM_CTRL_PT pt, in RtpemConfig cfg) {
	pt.call(RTPEM_configure:{cfg}) {
		[] pt.getreply(RTPEM_configure:{cfg}) {};
	}
}
function f_rtpem_stats_get(RTPEM_CTRL_PT pt, boolean rtcp := false) return RtpemStats {
	var RtpemStats stats;
	pt.call(RTPEM_stats_get:{-, rtcp}) {
		[] pt.getreply(RTPEM_stats_get:{?, rtcp}) -> param(stats) {};
	}
	return stats;
}

function f_rtpem_stats_compare_value(integer a, integer b, integer tolerance := 0) return boolean {
	var integer temp;

	temp := (a - b)
	if (temp < 0) {
		temp := -temp;
	}

	if (temp > tolerance) {
		return false;
	}

	return true;
}

/* Cross-compare two rtpem-statistics. The transmission statistics on the a side
 * must match the reception statistics on the other side and vice versa. The
 * user may also supply a tolerance value (number of packets) when deviations
 * are acceptable */
function f_rtpem_stats_compare(RtpemStats a, RtpemStats b, integer tolerance := 0) return boolean {
	var integer plen;

	log("stats A: ", a);
	log("stats B: ", b);
	log("tolerance: ", tolerance, " packets");

	if (f_rtpem_stats_compare_value(a.num_pkts_tx, b.num_pkts_rx, tolerance) == false) {
		return false;
	}

	if (f_rtpem_stats_compare_value(a.num_pkts_rx, b.num_pkts_tx, tolerance) == false) {
		return false;
	}

	if(a.num_pkts_tx > 0) {
		plen := a.bytes_payload_tx / a.num_pkts_tx;
	} else {
		plen := 0;
	}

	if (f_rtpem_stats_compare_value(a.bytes_payload_tx, b.bytes_payload_rx, tolerance * plen) == false) {
		return false;
	}

	if (f_rtpem_stats_compare_value(a.bytes_payload_rx, b.bytes_payload_tx, tolerance * plen) == false) {
		return false;
	}

	return true;
}

/* Check the statistics for general signs of errors. This is a basic general
 * check that will fit most situations and  is intended to be executed by
 * the testcases as as needed. */
function f_rtpem_stats_err_check(RtpemStats s) {
	log("stats: ", s);

	/* Check if there was some activity at either on the RX or on the
	 * TX side, but complete silence would indicate some problem */
	if (s.num_pkts_tx < 1 and s.num_pkts_rx < 1) {
		setverdict(fail, "no RTP packet activity detected (packets)");
		mtc.stop;
	}
	if (s.bytes_payload_tx < 1 and s.bytes_payload_rx < 1) {
		setverdict(fail, "no RTP packet activity detected (bytes)");
		mtc.stop;
	}

	/* Check error counters */
	if (s.num_pkts_rx_err_seq != 0) {
		setverdict(fail, "RTP packet sequence number errors occurred");
		mtc.stop;
	}
	if (s.num_pkts_rx_err_ts != 0) {
		setverdict(fail, "RTP packet timestamp errors occurred");
		mtc.stop;
	}
	if (s.num_pkts_rx_err_pt != 0) {
		setverdict(fail, "RTP packet payload type errors occurred");
		mtc.stop;
	}
	if (s.num_pkts_rx_err_disabled != 0) {
		setverdict(fail, "RTP packets received while RX was disabled");
		mtc.stop;
	}
	if (s.num_pkts_rx_err_payload != 0) {
		setverdict(fail, "RTP packets with mismatching payload received");
		mtc.stop;
	}
}

template PDU_RTP ts_RTP(BIT32_BO_LAST ssrc, INT7b pt, LIN2_BO_LAST seq, uint32_t ts,
			octetstring payload, BIT1 marker := '0'B) := {
	version := 2,
	padding_ind := '0'B,
	extension_ind := '0'B,
	CSRC_count := 0,
	marker_bit := marker,
	payload_type := pt,
	sequence_number := seq,
	time_stamp := int2bit(ts, 32),
	SSRC_id := ssrc,
	CSRCs := omit,
	ext_header := omit,
	data := payload
}

private function f_tx_rtp(octetstring payload, BIT1 marker := '0'B) runs on RTP_Emulation_CT {
	if (g_cfg.iuup_mode) {
		payload := f_IuUP_Em_tx_encap(g_iuup_ent, payload);
	}
	var PDU_RTP rtp := valueof(ts_RTP(g_cfg.tx_ssrc, g_cfg.tx_payload_type, g_tx_next_seq,
					  g_tx_next_ts, payload, marker));
	RTP.send(t_RTP_Send(g_rtp_conn_id, RTP_messages_union:{rtp:=rtp}));
	/* increment sequence + timestamp for next transmit */
	g_tx_next_seq := g_tx_next_seq + 1;
	g_tx_next_ts := g_tx_next_ts + (g_cfg.tx_samplerate_hz / (1000 / g_cfg.tx_duration_ms));
}

function f_main() runs on RTP_Emulation_CT
{
	var Result res;
	var boolean is_rtcp

	timer T_transmit := int2float(g_cfg.tx_duration_ms)/1000.0;
	var RTP_RecvFrom rx_rtp;
	var RtpemConfig cfg;
	var template RTP_RecvFrom tr := {
		connId := ?,
		remName := ?,
		remPort := ?,
		locName := ?,
		locPort := ?,
		msg := ?
	};
	var template RTP_RecvFrom tr_rtp := tr;
	var template RTP_RecvFrom tr_rtcp := tr;
	tr_rtp.msg := { rtp := ? };
	tr_rtcp.msg := { rtcp := ? };

	g_iuup_ent := valueof(t_IuUP_Entity(g_cfg.iuup_tx_init));

	while (true) {
	alt {
		/* control procedures (calls) from the user */
		[] CTRL.getcall(RTPEM_bind:{?,?}) -> param(g_local_host, g_local_port) {
			if (g_local_port rem 2 == 1) {
				//CTRL.raise(RTPEM_bind, "Local Port is not an even port number!");
				log("Local Port is not an even port number!");
				continue;
			}
			res := RTP_CodecPort_CtrlFunct.f_IPL4_listen(RTP, g_local_host,
								g_local_port, {udp:={}});
			if (not ispresent(res.connId)) {
				setverdict(fail, "Could not listen on RTP socket, check your configuration");
				mtc.stop;
			}
			g_rtp_conn_id := res.connId;
			tr_rtp.connId := g_rtp_conn_id;
			res := RTP_CodecPort_CtrlFunct.f_IPL4_listen(RTCP, g_local_host,
								g_local_port+1, {udp:={}});
			if (not ispresent(res.connId)) {
				setverdict(fail, "Could not listen on RTCP socket, check your configuration");
				mtc.stop;
			}
			g_rtcp_conn_id := res.connId;
			tr_rtcp.connId := g_rtcp_conn_id;
			CTRL.reply(RTPEM_bind:{g_local_host, g_local_port});
		}
		[] CTRL.getcall(RTPEM_connect:{?,?}) -> param (g_remote_host, g_remote_port) {
			if (g_remote_port rem 2 == 1) {
				//CTRL.raise(RTPEM_connect, "Remote Port is not an even number!");
				log("Remote Port is not an even number!");
				continue;
			}
			res := RTP_CodecPort_CtrlFunct.f_IPL4_connect(RTP, g_remote_host,
								g_remote_port,
								g_local_host, g_local_port,
								g_rtp_conn_id, {udp:={}});
			if (not ispresent(res.connId)) {
				setverdict(fail, "Could not connect to RTP socket, check your configuration");
				mtc.stop;
			}
			res := RTP_CodecPort_CtrlFunct.f_IPL4_connect(RTCP, g_remote_host,
								g_remote_port+1,
								g_local_host, g_local_port+1,
								g_rtcp_conn_id, {udp:={}});
			if (not ispresent(res.connId)) {
				setverdict(fail, "Could not connect to RTCP socket, check your configuration");
				mtc.stop;
			}
			CTRL.reply(RTPEM_connect:{g_remote_host, g_remote_port});
		}
		[] CTRL.getcall(RTPEM_mode:{RTPEM_MODE_NONE}) {
			T_transmit.stop;
			g_rx_enabled := 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;
			CTRL.reply(RTPEM_mode:{RTPEM_MODE_TXONLY});
		}
		[] CTRL.getcall(RTPEM_mode:{RTPEM_MODE_RXONLY}) {

			T_transmit.stop;
			if (g_rx_enabled == false) {
				/* flush queues */
				RTP.clear;
				RTCP.clear;
				g_rx_enabled := true;
			}
			CTRL.reply(RTPEM_mode:{RTPEM_MODE_RXONLY});
		}
		[] CTRL.getcall(RTPEM_mode:{RTPEM_MODE_BIDIR}) {
			T_transmit.start;
			if (g_rx_enabled == false) {
				/* flush queues */
				RTP.clear;
				RTCP.clear;
				g_rx_enabled := true;
			}
			CTRL.reply(RTPEM_mode:{RTPEM_MODE_BIDIR});
		}
		[] CTRL.getcall(RTPEM_configure:{?}) -> param (cfg) {
			g_cfg := cfg;
			g_iuup_ent.cfg.active_init := g_cfg.iuup_tx_init;
			CTRL.reply(RTPEM_configure:{cfg});
		}
		[] CTRL.getcall(RTPEM_stats_get:{?, ?}) -> param (is_rtcp) {
			if (is_rtcp) {
				CTRL.reply(RTPEM_stats_get:{g_stats_rtcp, is_rtcp});
			} else {
				CTRL.reply(RTPEM_stats_get:{g_stats_rtp, is_rtcp});
			}
		}



		/* simply ignore any RTTP/RTP if receiver not enabled */
		[g_rx_enabled==false] RTP.receive(tr_rtp) {
			g_stats_rtp.num_pkts_rx_err_disabled := g_stats_rtp.num_pkts_rx_err_disabled+1;
			}
		[g_rx_enabled==false] RTCP.receive(tr_rtcp) {
			g_stats_rtcp.num_pkts_rx_err_disabled := g_stats_rtcp.num_pkts_rx_err_disabled+1;
			}

		/* process received RTCP/RTP if receiver enabled */
		[g_rx_enabled] RTP.receive(tr_rtp) -> value rx_rtp {
			/* increment counters */
			if (rx_rtp.msg.rtp.payload_type != g_cfg.tx_payload_type) {
				g_stats_rtp.num_pkts_rx_err_pt := g_stats_rtp.num_pkts_rx_err_pt+1;
			}
			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);
			}
		}
		[g_rx_enabled] RTCP.receive(tr_rtcp) -> value rx_rtp {
			//log("RX RTCP: ", rx_rtp);
			g_stats_rtcp.num_pkts_rx := g_stats_rtcp.num_pkts_rx+1;
		}

		/* transmit if timer has expired */
		[] T_transmit.timeout {
			/* send one RTP frame, re-start timer */
			f_tx_rtp(g_cfg.tx_fixed_payload);
			T_transmit.start;
			/* 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(g_cfg.tx_fixed_payload);
		}

		/* fail on any unexpected messages */
		[] RTP.receive {
			setverdict(fail, "Received unexpected type from RTP");
			mtc.stop;
		}
		[] RTCP.receive {
			setverdict(fail, "Received unexpected type from RTCP");
			mtc.stop;
		}
	}
	}
}


}
