module RTP_Endpoint {

	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;

	/* state for one of the two UDP sockets in and endpoint */
	type record RtpEndpointSub {
		ConnectionId	connection_id,
		HostName	local_name,
		PortNumber	local_port,
		HostName	remote_name,
		PortNumber	remote_port
	}
	/* state for one RTP+RTCP endpoint */
	type record RtpEndpoint {
		/* static configuration */
		INT7b		payload_type,
		integer		sample_rate,		/* e.g. 8000 */
		integer		samples_per_pkt,	/* e.g. 160 */
		BIT32_BO_LAST	ssrc,

		/* dynamic state */
		uint32_t	next_ts,
		LIN2_BO_LAST	next_seq_no,
		RtpEndpointSub	rtp,
		RtpEndpointSub	rtcp
	}

/*
	type component RTP_CT {
		port RTP_CODEC_PT RTP;
		ConnectionId	g_conn_id := 1;
	}

	modulepar {
		HostName rtp_local_ip := "127.0.0.1";
		PortNumber rtp_local_base_port := 10000;
	}
*/

	template RTP_messages_union ts_RTP(BIT1 marker, INT7b pt, LIN2_BO_LAST seq, uint32_t ts,
					   BIT32_BO_LAST ssrc, octetstring data) := {
		rtp := {
			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 := data
		}
	}

	template RTP_messages_union tr_RTP(template INT7b pt, template octetstring data,
					   template BIT32_BO_LAST ssrc := ?,
					   template LIN2_BO_LAST seq := ?,
					   template BIT32_BO_LAST ts := ?) := {
		rtp := {
			version := 2,
			padding_ind := ?,
			extension_ind := ?,
			CSRC_count := ?,
			marker_bit := ?,
			payload_type := pt,
			sequence_number := seq,
			time_stamp := ts,
			SSRC_id := ssrc,
			CSRCs := *,
			ext_header := *,
			data := data
		}
	}

	function rtp_endpoint_init(inout RtpEndpoint ep, charstring local_name, PortNumber local_port,
				   uint32_t ssrc) {
		ep.rtp.local_name := local_name;
		ep.rtp.local_port := local_port;
		ep.rtp.connection_id := -1;
		ep.rtcp.local_name := local_name;
		ep.rtcp.local_port := local_port + 1;
		ep.rtcp.connection_id := -1;
		ep.ssrc := int2bit(ssrc, 32);

		ep.payload_type := 99;
		ep.sample_rate := 8000;
		ep.samples_per_pkt := 160;
		ep.next_ts := float2int(rnd()*4294967295.0);
		ep.next_seq_no := float2int(rnd()*65535.0);
	}

	function rtp_endpoint_sub_close(inout RTP_CODEC_PT RTP, inout RtpEndpointSub sub) {
		if (sub.connection_id != -1) {
			f_IPL4_close(RTP, sub.connection_id, { udp := {} });
			sub.connection_id := -1;
		}
	}

	function rtp_endpoint_sub_connect(inout RTP_CODEC_PT RTP, inout RtpEndpointSub sub) {
		var Result res;

		res := f_IPL4_connect(RTP, sub.remote_name, sub.remote_port,
					sub.local_name, sub.local_port, sub.connection_id, { udp := {} });
		if (not ispresent(res.connId)) {
			setverdict(fail, "Could not connect RTP, check your configuration");
			mtc.stop;
		}
		/* connect without previous bind: save conenction id allocated by IPL4asp */
		if (sub.connection_id == -1) {
			sub.connection_id := res.connId;
		}
	}

	function rtp_endpoint_close(inout RTP_CODEC_PT RTP, inout RtpEndpoint ep) {
		rtp_endpoint_sub_close(RTP, ep.rtp);
		rtp_endpoint_sub_close(RTP, ep.rtcp);
	}

	/* connect the RTP and RTCP */
	function rtp_endpoint_connect(inout RTP_CODEC_PT RTP, inout RtpEndpoint ep) {
		rtp_endpoint_sub_connect(RTP, ep.rtp);
		rtp_endpoint_sub_connect(RTP, ep.rtcp);
	}

	function rtp_endpoint_sub_bind(inout RTP_CODEC_PT RTP, inout RtpEndpointSub sub) {
		var Result res;
		rtp_endpoint_sub_close(RTP, sub);
		res := f_IPL4_listen(RTP, sub.local_name, sub.local_port, { udp := {} });
		if (not ispresent(res.connId)) {
			setverdict(fail, "Could not listen to RTP, check your configuration");
			mtc.stop;
		}
		sub.connection_id := res.connId;
	}

	function rtp_endpoint_bind(inout RTP_CODEC_PT RTP, inout RtpEndpoint ep) {
		rtp_endpoint_sub_bind(RTP, ep.rtp);
		rtp_endpoint_sub_bind(RTP, ep.rtcp);
	}

	/* send user-specified data through given endpoint, incrementing seq_no and timestamp */
	function rtp_endpoint_send(inout RTP_CODEC_PT RTP, inout RtpEndpoint ep,
				   octetstring data := '00'O) {
		var RTP_messages_union rtp;
		/* generate RTP packet as abstract TTCN-3 type */
		rtp := valueof(ts_RTP('0'B, ep.payload_type, ep.next_seq_no, ep.next_ts, ep.ssrc, data));
		/* increment for next packet */
		ep.next_seq_no := ep.next_seq_no + 1;
		ep.next_ts := ep.next_ts + ep.samples_per_pkt;
		/* encode and send */
		RTP.send(t_RTP_Send(ep.rtp.connection_id, rtp));
	}
}
