/* GTPv2 Emulation in TTCN-3
 *
 * (C) 2018-2020 Harald Welte <laforge@gnumonks.org>
 * All rights reserved.
 *
 * Released under the terms of GNU General Public License, Version 2 or
 * (at your option) any later version.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

module GTPv2_Emulation {

import from IPL4asp_Types all;
import from General_Types all;
import from Osmocom_Types all;
import from GTPv2_Types all;
import from GTPv2_Templates all;
import from GTPv2_CodecPort all;
import from GTPv2_CodecPort_CtrlFunct all;

import from UECUPS_Types all;
import from UECUPS_CodecPort all;
import from UECUPS_CodecPort_CtrlFunct all;

/***********************************************************************
 * Main Emulation Component
 ***********************************************************************/

modulepar {
	charstring mp_uecups_host := "127.0.0.1";
	integer mp_uecups_port := UECUPS_SCTP_PORT;
};

const integer GTP2C_PORT := 2123;
const integer GTP1U_PORT := 2152;

type record Gtp2EmulationCfg {
	HostName gtpc_bind_ip,
	IPL4asp_Types.PortNumber gtpc_bind_port,
	HostName gtpc_remote_ip,
	IPL4asp_Types.PortNumber gtpc_remote_port,
	//HostName gtpu_bind_ip,
	//PortNumber gtpu_bind_port,
	boolean sgw_role,
	boolean use_gtpu_daemon
};

type component GTPv2_Emulation_CT {
	/* Communication with underlying GTP CodecPort */
	port GTPv2C_PT GTP2C;

	/* Control port to GTP-U Daemon */
	port UECUPS_CODEC_PT UECUPS;

	/* Communication with Clients */
	port GTP2EM_PT TEID0;
	port GTP2EM_PT CLIENT;
	port GTP2EM_PROC_PT CLIENT_PROC;

	/* Configuration by the user */
	var Gtp2EmulationCfg g_gtp2_cfg;

	/* State */
	var GtpPeer g_peer;
	var integer g_gtp2c_id;
	var OCT1 g_restart_ctr;
	var uint16_t g_c_seq_nr;
	var TidTableRec TidTable[256];
	var SeqTableRec SeqTable[256];
	var ImsiTableRec ImsiTable[256];
	var PidTableRec	PidTable[256];
	var integer g_uecups_conn_id;
};

/* local TEID <-> ConnHdlr mapping */
type record TidTableRec {
	OCT4 teid,
	GTP2_ConnHdlr vc_conn
};

/* local SeqNr <-> ConnHdlr mapping (until a response is received */
type record SeqTableRec {
	OCT3 seq,
	GTP2_ConnHdlr vc_conn
};

/* IMSI <-> ConnHdlr mapping */
type record ImsiTableRec {
	hexstring imsi,
	GTP2_ConnHdlr vc_conn
};

/* pid <-> ConnHdlr mapping (for UECUPS process termination indication) */
type record PidTableRec {
	/* process ID of the running process */
	integer pid,
	/* component that started it */
	GTP2_ConnHdlr vc_conn
};

private function f_comp_by_teid(OCT4 teid) runs on GTPv2_Emulation_CT return GTP2_ConnHdlr {
	var integer i;
	for (i := 0; i < sizeof(TidTable); i := i+1) {
		if (isbound(TidTable[i].teid) and TidTable[i].teid == teid) {
			return TidTable[i].vc_conn;
		}
	}
	setverdict(fail, "No Component for TEID ", teid);
	mtc.stop;
}

private function f_seq_known(OCT3 seq) runs on GTPv2_Emulation_CT return boolean {
	var integer i;
	for (i := 0; i < sizeof(SeqTable); i := i+1) {
		if (isbound(SeqTable[i].seq) and SeqTable[i].seq == seq) {
			return true;
		}
	}
	return false;
}

private function f_comp_by_seq(OCT3 seq) runs on GTPv2_Emulation_CT return GTP2_ConnHdlr {
	var integer i;
	for (i := 0; i < sizeof(SeqTable); i := i+1) {
		if (isbound(SeqTable[i].seq) and SeqTable[i].seq == seq) {
			return SeqTable[i].vc_conn;
		}
	}
	setverdict(fail, "No Component for SEQ ", seq);
	mtc.stop;
}

private function f_comp_by_imsi(hexstring imsi) runs on GTPv2_Emulation_CT return GTP2_ConnHdlr {
	var integer i;
	for (i := 0; i < sizeof(ImsiTable); i := i+1) {
		if (isbound(ImsiTable[i].imsi) and ImsiTable[i].imsi == imsi) {
			return ImsiTable[i].vc_conn;
		}
	}
	setverdict(fail, "No Component for IMSI ", imsi);
	mtc.stop;
}

private function f_comp_by_pid(integer pid) runs on GTPv2_Emulation_CT return GTP2_ConnHdlr {
	var integer i;
	for (i := 0; i < sizeof(PidTable); i := i+1) {
		if (isbound(PidTable[i].pid) and PidTable[i].pid == pid) {
			/* fixme: remove */
			return PidTable[i].vc_conn;
		}
	}
	setverdict(fail, "No Component for PID ", pid);
	mtc.stop;
}

private function f_tid_tbl_add(OCT4 teid, GTP2_ConnHdlr vc_conn) runs on GTPv2_Emulation_CT {
	var integer i;
	for (i := 0; i < sizeof(TidTable); i := i+1) {
		if (not isbound(TidTable[i].teid)) {
			TidTable[i].teid := teid;
			TidTable[i].vc_conn := vc_conn;
			return;
		}
	}
	testcase.stop("No Space in TidTable for ", teid);
}

private function f_seq_tbl_add(OCT3 seq, GTP2_ConnHdlr vc_conn) runs on GTPv2_Emulation_CT {
	var integer i;
	for (i := 0; i < sizeof(SeqTable); i := i+1) {
		if (not isbound(SeqTable[i].seq)) {
			SeqTable[i].seq := seq;
			SeqTable[i].vc_conn := vc_conn;
			return;
		}
	}
	testcase.stop("No Space in SeqTable for ", seq);
}

private function f_seq_tbl_del(OCT3 seq) runs on GTPv2_Emulation_CT {
	var integer i;
	for (i := 0; i < sizeof(SeqTable); i := i+1) {
		if (isbound(SeqTable[i].seq) and SeqTable[i].seq == seq) {
			SeqTable[i] := {
				seq := -,
				vc_conn := null
			}
		}
	}
}

private function f_imsi_tbl_add(hexstring imsi, GTP2_ConnHdlr vc_conn) runs on GTPv2_Emulation_CT {
	var integer i;
	for (i := 0; i < sizeof(ImsiTable); i := i+1) {
		if (not isbound(ImsiTable[i].imsi)) {
			ImsiTable[i].imsi := imsi;
			ImsiTable[i].vc_conn := vc_conn;
			return;
		}
	}
	testcase.stop("No Space in IMSI Table for ", imsi);
}

private function f_pid_tbl_add(integer pid, GTP2_ConnHdlr vc_conn) runs on GTPv2_Emulation_CT {
	var integer i;
	for (i := 0; i < sizeof(PidTable); i := i+1) {
		if (not isbound(PidTable[i].pid)) {
			PidTable[i].pid := pid;
			PidTable[i].vc_conn := vc_conn;
			return;
		}
	}
	testcase.stop("No Space in PID Table for ", pid);
}


/* allocate an unused local teid */
private function f_alloc_teid() runs on GTPv2_Emulation_CT return OCT4 {
	var OCT4 teid;
	var integer i, j;
	for (i := 0; i < 100; i := i+1) {
		teid := f_rnd_octstring(4);
		for (j := 0; j < sizeof(TidTable); j := j+1) {
			if (isbound(TidTable) and TidTable[i].teid == teid) {
				continue;
			}
		}
		/* we iterated over all entries and found no match: great! */
		return teid;
	}
	testcase.stop("Cannot find unused TEID after ", i, " attempts");
}

/* obtain the IMSI from a GTPv2C PDU, if there is any IMSI contained. The way how the TITAN
 * GTPv2 decoders are structured (explict IE members rather than a list/set of generic IE structures)
 * doesn't make this easy, but requires lots of boilerplate code.  Oh well.. */
function f_gtp2c_extract_imsi(PDU_GTPCv2 gtp) return template (omit) hexstring {
	if (ischosen(gtp.gtpcv2_pdu.createSessionRequest)) {
		if (ispresent(gtp.gtpcv2_pdu.createSessionRequest.iMSI)) {
			return gtp.gtpcv2_pdu.createSessionRequest.iMSI.iMSI_Value;
		}
	} else if (ischosen(gtp.gtpcv2_pdu.downlinkDataNotification)) {
		if (ispresent(gtp.gtpcv2_pdu.downlinkDataNotification.iMSI)) {
			return gtp.gtpcv2_pdu.downlinkDataNotification.iMSI.iMSI_Value;
		}
	} else if (ischosen(gtp.gtpcv2_pdu.downlinkDataNotificationAcknowledgement)) {
		if (ispresent(gtp.gtpcv2_pdu.downlinkDataNotificationAcknowledgement.iMSI)) {
			return gtp.gtpcv2_pdu.downlinkDataNotificationAcknowledgement.iMSI.iMSI_Value;
		}
	} else if (ischosen(gtp.gtpcv2_pdu.downlinkDataNotificationFailureIndication)) {
		if (ispresent(gtp.gtpcv2_pdu.downlinkDataNotificationFailureIndication.iMSI)) {
			return gtp.gtpcv2_pdu.downlinkDataNotificationFailureIndication.iMSI.iMSI_Value;
		}
	} else if (ischosen(gtp.gtpcv2_pdu.createIndirectDataForwardingTunnelRequest)) {
		if (ispresent(gtp.gtpcv2_pdu.createIndirectDataForwardingTunnelRequest.iMSI)) {
			return gtp.gtpcv2_pdu.createIndirectDataForwardingTunnelRequest.iMSI.iMSI_Value;
		}
	} else if (ischosen(gtp.gtpcv2_pdu.stopPagingIndication)) {
		if (ispresent(gtp.gtpcv2_pdu.stopPagingIndication.iMSI)) {
			return gtp.gtpcv2_pdu.stopPagingIndication.iMSI.iMSI_Value;
		}
	} else if (ischosen(gtp.gtpcv2_pdu.forwardRelocationRequest)) {
		if (ispresent(gtp.gtpcv2_pdu.forwardRelocationRequest.iMSI)) {
			return gtp.gtpcv2_pdu.forwardRelocationRequest.iMSI.iMSI_Value;
		}
	} else if (ischosen(gtp.gtpcv2_pdu.contextRequest)) {
		if (ispresent(gtp.gtpcv2_pdu.contextRequest.iMSI)) {
			return gtp.gtpcv2_pdu.contextRequest.iMSI.iMSI_Value;
		}
	} else if (ischosen(gtp.gtpcv2_pdu.identificationResponse)) {
		if (ispresent(gtp.gtpcv2_pdu.identificationResponse.iMSI)) {
			return gtp.gtpcv2_pdu.identificationResponse.iMSI.iMSI_Value;
		}
	} else if (ischosen(gtp.gtpcv2_pdu.changeNotificationRequest)) {
		if (ispresent(gtp.gtpcv2_pdu.changeNotificationRequest)) {
			return gtp.gtpcv2_pdu.changeNotificationRequest.iMSI.iMSI_Value;
		}
	} else if (ischosen(gtp.gtpcv2_pdu.changeNotificationResponse)) {
		if (ispresent(gtp.gtpcv2_pdu.changeNotificationResponse.iMSI)) {
			return gtp.gtpcv2_pdu.changeNotificationResponse.iMSI.iMSI_Value;
		}
	} else if (ischosen(gtp.gtpcv2_pdu.relocationCancelRequest)) {
		if (ispresent(gtp.gtpcv2_pdu.relocationCancelRequest.iMSI)) {
			return gtp.gtpcv2_pdu.relocationCancelRequest.iMSI.iMSI_Value;
		}
	} else if (ischosen(gtp.gtpcv2_pdu.uE_RegistrationQueryRequest)) {
		if (ispresent(gtp.gtpcv2_pdu.uE_RegistrationQueryRequest.iMSI)) {
			return gtp.gtpcv2_pdu.uE_RegistrationQueryRequest.iMSI.iMSI_Value;
		}
	} else if (ischosen(gtp.gtpcv2_pdu.uE_RegistrationQueryResponse)) {
		if (ispresent(gtp.gtpcv2_pdu.uE_RegistrationQueryResponse.iMSI)) {
			return gtp.gtpcv2_pdu.uE_RegistrationQueryResponse.iMSI.iMSI_Value;
		}
	} else if (ischosen(gtp.gtpcv2_pdu.suspendNotification)) {
		if (ispresent(gtp.gtpcv2_pdu.suspendNotification.iMSI)) {
			return gtp.gtpcv2_pdu.suspendNotification.iMSI.iMSI_Value;
		}
	} else if (ischosen(gtp.gtpcv2_pdu.resumeNotification)) {
		if (ispresent(gtp.gtpcv2_pdu.resumeNotification.iMSI)) {
			return gtp.gtpcv2_pdu.resumeNotification.iMSI.iMSI_Value;
		}
	} else if (ischosen(gtp.gtpcv2_pdu.cSPagingIndication)) {
		if (ispresent(gtp.gtpcv2_pdu.cSPagingIndication.iMSI)) {
			return gtp.gtpcv2_pdu.cSPagingIndication.iMSI.iMSI_Value;
		}
	} else if (ischosen(gtp.gtpcv2_pdu.pGW_DownlinkTriggeringNotification)) {
		if (ispresent(gtp.gtpcv2_pdu.pGW_DownlinkTriggeringNotification.iMSI)) {
			return gtp.gtpcv2_pdu.pGW_DownlinkTriggeringNotification.iMSI.iMSI_Value;
		}
	} else if (ischosen(gtp.gtpcv2_pdu.pGW_DownlinkTriggeringAcknowledge)) {
		if (ispresent(gtp.gtpcv2_pdu.pGW_DownlinkTriggeringAcknowledge.iMSI)) {
			return gtp.gtpcv2_pdu.pGW_DownlinkTriggeringAcknowledge.iMSI.iMSI_Value;
		}
	} else if (ischosen(gtp.gtpcv2_pdu.traceSessionActivation)) {
		if (ispresent(gtp.gtpcv2_pdu.traceSessionActivation.iMSI)) {
			return gtp.gtpcv2_pdu.traceSessionActivation.iMSI.iMSI_Value;
		}
	}
	return omit;
}

private template (value) SctpTuple ts_SCTP(template (omit) integer ppid := omit) := {
	sinfo_stream := omit,
	sinfo_ppid := ppid,
	remSocks := omit,
	assocId := omit
};

function tr_UECUPS_RecvFrom_R(template PDU_UECUPS msg)
runs on GTPv2_Emulation_CT return template UECUPS_RecvFrom {
	var template UECUPS_RecvFrom mrf := {
		connId := g_uecups_conn_id,
		remName := ?,
		remPort := ?,
		locName := ?,
		locPort := ?,
		msg := msg
	}
	return mrf;
}


private template PortEvent tr_SctpAssocChange := {
	sctpEvent := {
		sctpAssocChange := ?
	}
}
private template PortEvent tr_SctpPeerAddrChange := {
	sctpEvent := {
		sctpPeerAddrChange := ?
	}
}

private function f_uecups_xceive(template (value) PDU_UECUPS tx,
				template PDU_UECUPS rx_t := ?)
runs on GTPv2_Emulation_CT  return PDU_UECUPS {
	timer T := 10.0;
	var UECUPS_RecvFrom mrf;

	UECUPS.send(t_UECUPS_Send(g_uecups_conn_id, tx));
	T.start;
	alt {
	[] UECUPS.receive(tr_UECUPS_RecvFrom_R(rx_t)) -> value mrf { }
	[] UECUPS.receive(tr_SctpAssocChange) { repeat; }
	[] UECUPS.receive(tr_SctpPeerAddrChange)  { repeat; }
	[] T.timeout {
		setverdict(fail, "Timeout waiting for ", rx_t);
		mtc.stop;
		}
	}
	return mrf.msg;
}

private function f_init(Gtp2EmulationCfg cfg) runs on GTPv2_Emulation_CT {
	var Result res;

	map(self:GTP2C, system:GTP2C);
	res := GTPv2_CodecPort_CtrlFunct.f_IPL4_listen(GTP2C, cfg.gtpc_bind_ip,
						     cfg.gtpc_bind_port, {udp:={}});
	g_gtp2c_id := res.connId;

	g_restart_ctr := f_rnd_octstring(1);
	g_c_seq_nr := f_rnd_int(65535);
	g_gtp2_cfg := cfg;
	g_peer := {
		connId := g_gtp2c_id,
		remName := g_gtp2_cfg.gtpc_remote_ip,
		remPort := g_gtp2_cfg.gtpc_remote_port
	}

	if (g_gtp2_cfg.use_gtpu_daemon) {
		map(self:UECUPS, system:UECUPS);
		res := UECUPS_CodecPort_CtrlFunct.f_IPL4_connect(UECUPS, mp_uecups_host, mp_uecups_port, "", -1, -1, { sctp := valueof(ts_SCTP) });
		if (not ispresent(res.connId)) {
			setverdict(fail, "Could not connect UECUPS socket, check your configuration");
			testcase.stop;
		}
		g_uecups_conn_id := res.connId;

		/* clear all tunnel state in the daemon at start */
		f_uecups_xceive({reset_all_state := {}}, {reset_all_state_res:=?});
	}

	/* make sure we always pass incoming UECUPS indications whenever receiving fom the UECUPS port */
	activate(as_uecups_ind());
}

private altstep as_uecups_ind() runs on GTPv2_Emulation_CT {
var UECUPS_RecvFrom rx;
var GTP2_ConnHdlr vc_conn;
/* handle incoming program_term_ind; dispatch to whatever component started the process */
[] UECUPS.receive(tr_UECUPS_RecvFrom_R({program_term_ind:=?})) -> value rx {
	vc_conn := f_comp_by_pid(rx.msg.program_term_ind.pid);
	CLIENT.send(rx.msg.program_term_ind) to vc_conn;
	/* FIXME: remove from table */
	repeat;
	}
}

function main(Gtp2EmulationCfg cfg) runs on GTPv2_Emulation_CT {
	var Gtp2cUnitdata g2c_ud;
	var PDU_GTPCv2 g2c;
	var GTP2_ConnHdlr vc_conn;
	var hexstring imsi;
	var OCT4 teid;
	var PDU_UECUPS rx_uecups;
	var UECUPS_CreateTun gtc;
	var UECUPS_DestroyTun gtd;
	var UECUPS_StartProgram sprog;

	f_init(cfg);

	while (true) {
	alt {
	/* route inbound GTP2-C based on TEID, SEQ or IMSI */
	[] GTP2C.receive(Gtp2cUnitdata:?) -> value g2c_ud {
		var template hexstring imsi_t := f_gtp2c_extract_imsi(g2c_ud.gtpc);
		if (not ispresent(g2c_ud.gtpc.tEID) or g2c_ud.gtpc.tEID == int2oct(0, 4)) {
			/* if this is a response, route by SEQ */
			if (match(g2c_ud.gtpc, tr_PDU_GTP2C_msgtypes(gtp2_responses))
			    and f_seq_known(g2c_ud.gtpc.sequenceNumber)) {
				vc_conn := f_comp_by_seq(g2c_ud.gtpc.sequenceNumber);
				CLIENT.send(g2c_ud.gtpc) to vc_conn;
			} else {
				TEID0.send(g2c_ud.gtpc);
			}
		} else if (ispresent(g2c_ud.gtpc.tEID) and g2c_ud.gtpc.tEID != int2oct(0, 4)) {
			vc_conn := f_comp_by_teid(g2c_ud.gtpc.tEID);
			CLIENT.send(g2c_ud.gtpc) to vc_conn;
		} else if (isvalue(imsi_t)) {
			vc_conn := f_comp_by_imsi(valueof(imsi_t));
			CLIENT.send(g2c_ud.gtpc) to vc_conn;
		} else {
			/* Send to all clients */
			var integer i;
			for (i := 0; i < sizeof(TidTable); i := i+1) {
				if (isbound(TidTable[i].teid) and TidTable[i].teid == teid) {
					CLIENT.send(g2c_ud.gtpc) to TidTable[i].vc_conn;
				}
			}
		}

		/* remove sequence number if response was received */
		if (match(g2c_ud.gtpc, tr_PDU_GTP2C_msgtypes(gtp2_responses))) {
			f_seq_tbl_del(g2c_ud.gtpc.sequenceNumber);
		}

		}

	[] TEID0.receive(PDU_GTPCv2:?) -> value g2c sender vc_conn {
		/* patch in the next sequence number */
		/* FIXME: do this only for outbound requests */
		g2c.sequenceNumber := int2oct(g_c_seq_nr, 3);
		g_c_seq_nr := g_c_seq_nr + 1;
		/* build Gtp2cUnitdata */
		g2c_ud := { peer := g_peer, gtpc := g2c };
		GTP2C.send(g2c_ud);
		if (match(g2c, tr_PDU_GTP2C_msgtypes(gtp2_requests))) {
			f_seq_tbl_add(g2c.sequenceNumber, vc_conn);
		}
		}

	[] CLIENT.receive(PDU_GTPCv2:?) -> value g2c sender vc_conn {
		/* patch in the next sequence number */
		/* FIXME: do this only for outbound requests */
		g2c.sequenceNumber := int2oct(g_c_seq_nr, 3);
		g_c_seq_nr := g_c_seq_nr + 1;
		/* build Gtp2cUnitdata */
		g2c_ud := { peer := g_peer, gtpc := g2c };
		GTP2C.send(g2c_ud);
		if (match(g2c, tr_PDU_GTP2C_msgtypes(gtp2_requests))) {
			f_seq_tbl_add(g2c.sequenceNumber, vc_conn);
		}
		}

	[] CLIENT_PROC.getcall(GTP2EM_register_imsi:{?}) -> param(imsi) sender vc_conn {
		f_imsi_tbl_add(imsi, vc_conn);
		CLIENT_PROC.reply(GTP2EM_register_imsi:{imsi}) to vc_conn;
		}

	[] CLIENT_PROC.getcall(GTP2EM_register_teid:{?}) -> param(teid) sender vc_conn {
		f_tid_tbl_add(teid, vc_conn);
		CLIENT_PROC.reply(GTP2EM_register_teid:{teid}) to vc_conn;
		}
	[] CLIENT_PROC.getcall(GTP2EM_allocate_teid:{}) -> sender vc_conn {
		var OCT4 t := f_alloc_teid();
		f_tid_tbl_add(t, vc_conn);
		CLIENT_PROC.reply(GTP2EM_allocate_teid:{} value t) to vc_conn;
		}
	[] CLIENT_PROC.getcall(GTP2EM_create_tunnel:{?}) -> param(gtc) sender vc_conn {
		rx_uecups := f_uecups_xceive({create_tun := gtc}, {create_tun_res:={result:=OK}});
		CLIENT_PROC.reply(GTP2EM_create_tunnel:{gtc}) to vc_conn;
		}
	[] CLIENT_PROC.getcall(GTP2EM_destroy_tunnel:{?}) -> param(gtd) sender vc_conn {
		rx_uecups := f_uecups_xceive({destroy_tun := gtd}, {destroy_tun_res:={result:=OK}});
		CLIENT_PROC.reply(GTP2EM_destroy_tunnel:{gtd}) to vc_conn;
		}
	[] CLIENT_PROC.getcall(GTP2EM_start_program:{?}) -> param(sprog) sender vc_conn {
		rx_uecups := f_uecups_xceive({start_program := sprog}, {start_program_res:=?});
		/* if successful: store (pid, vc_conn) tuple so we can route program_term_ind */
		if (rx_uecups.start_program_res.result == OK) {
			f_pid_tbl_add(rx_uecups.start_program_res.pid, vc_conn);
		}
		CLIENT_PROC.reply(GTP2EM_start_program:{sprog} value rx_uecups.start_program_res) to vc_conn;
		}

	}
	}
}


/***********************************************************************
 * Interaction between Main and Client Components
 ***********************************************************************/
type port GTP2EM_PT message {
	inout PDU_GTPCv2, UECUPS_ProgramTermInd;
} with { extension "internal" };

signature GTP2EM_register_imsi(hexstring imsi);
signature GTP2EM_register_teid(OCT4 teid);
signature GTP2EM_allocate_teid() return OCT4;
signature GTP2EM_create_tunnel(UECUPS_CreateTun gtc);
signature GTP2EM_destroy_tunnel(UECUPS_DestroyTun gtd);
signature GTP2EM_start_program(UECUPS_StartProgram sprog) return UECUPS_StartProgramRes;

type port GTP2EM_PROC_PT procedure {
	inout GTP2EM_register_imsi, GTP2EM_register_teid, GTP2EM_allocate_teid,
	      GTP2EM_create_tunnel, GTP2EM_destroy_tunnel, GTP2EM_start_program;
} with { extension "internal" };

/***********************************************************************
 * Client Component
 ***********************************************************************/

type component GTP2_ConnHdlr {
	port GTP2EM_PT GTP2;
	port GTP2EM_PROC_PT GTP2_PROC;
};

function f_gtp2_register_imsi(hexstring imsi) runs on GTP2_ConnHdlr {
	GTP2_PROC.call(GTP2EM_register_imsi:{imsi}) {
		[] GTP2_PROC.getreply(GTP2EM_register_imsi:{imsi});
	}
}

function f_gtp2_register_teid(OCT4 teid) runs on GTP2_ConnHdlr {
	GTP2_PROC.call(GTP2EM_register_teid:{teid}) {
		[] GTP2_PROC.getreply(GTP2EM_register_teid:{teid});
	}
}

function f_gtp2_allocate_teid() runs on GTP2_ConnHdlr return OCT4 {
	var OCT4 t;
	GTP2_PROC.call(GTP2EM_allocate_teid:{}) {
		[] GTP2_PROC.getreply(GTP2EM_allocate_teid:{}) -> value t {
			return t;
		}
	}
}

function f_gtp2_create_tunnel(template (value) UECUPS_CreateTun gtc)
runs on GTP2_ConnHdlr {
	GTP2_PROC.call(GTP2EM_create_tunnel:{valueof(gtc)}) {
		[] GTP2_PROC.getreply(GTP2EM_create_tunnel:{gtc});
	}
}

function f_gtp2_destroy_tunnel(template (value) UECUPS_DestroyTun gtd)
runs on GTP2_ConnHdlr {
	GTP2_PROC.call(GTP2EM_destroy_tunnel:{valueof(gtd)}) {
		[] GTP2_PROC.getreply(GTP2EM_destroy_tunnel:{gtd});
	}
}

function f_gtp2_start_program(template (value) UECUPS_StartProgram sprog)
runs on GTP2_ConnHdlr return UECUPS_StartProgramRes {
	var UECUPS_StartProgramRes res;
	GTP2_PROC.call(GTP2EM_start_program:{valueof(sprog)}) {
		[] GTP2_PROC.getreply(GTP2EM_start_program:{sprog}) -> value res;
	}
	return res;
}



}
