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
 */

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;

	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 RtpemConfig {
	INT7b tx_payload_type,
	integer tx_samplerate_hz,
	integer tx_duration_ms,
	BIT32_BO_LAST tx_ssrc,
	octetstring tx_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,
	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);

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

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;

	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.connId := g_rtp_conn_id;
	tr_rtp.msg := { rtp := ? };
	tr_rtp.connId := g_rtcp_conn_id;
	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:={}});
			g_rtp_conn_id := res.connId;
			res := RTP_CodecPort_CtrlFunct.f_IPL4_listen(RTP, g_local_host,
								g_local_port+1, {udp:={}});
			g_rtcp_conn_id := res.connId;
			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:={}});
			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:={}});
			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});
		}

		/* simply ignore any RTTP/RTCP if receiver not enabled */
		[g_rx_enabled==false] RTP.receive(tr_rtp) { }
		[g_rx_enabled==false] RTCP.receive(tr_rtp) { }

		/* process received RTCP/RTP if receiver enabled */
		[g_rx_enabled] RTP.receive(tr_rtp) -> value rx_rtp {
			log("RX RTP: ", rx_rtp);
			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);
		}

		/* 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;
		}

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


}
