/* GTP Emulation in TTCN-3
 *
 * (C) 2018 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 GTP_Emulation {

import from IPL4asp_Types all;
import from General_Types all;
import from Osmocom_Types all;
import from GTPC_Types all;
import from GTPU_Types all;
import from GTP_CodecPort all;
import from GTP_CodecPort_CtrlFunct all;

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

const integer GTP0_PORT := 3386;
const integer GTP1C_PORT := 2123;
const integer GTP1U_PORT := 2152;

type record GtpEmulationCfg {
	HostName gtpc_bind_ip,
	PortNumber gtpc_bind_port,
	HostName gtpu_bind_ip,
	PortNumber gtpu_bind_port,
	boolean sgsn_role
};

type component GTP_Emulation_CT {
	/* Communication with underlying GTP CodecPort */
	port GTPC_PT GTPC;
	port GTPU_PT GTPU;

	/* Communication with Clients */
	port GTPEM_PT CLIENT;
	port GTPEM_PROC_PT CLIENT_PROC;
	port GTPEM_PT CLIENT_DEFAULT;

	/* Configuration by the user */
	var GtpEmulationCfg g_gtp_cfg;

	/* State */
	var integer g_gtpc_id, g_gtpu_id;
	var OCT1 g_restart_ctr;
	var uint16_t g_c_seq_nr, g_u_seq_nr;
	var TidTableRec TidTable[16];
	var ImsiTableRec ImsiTable[16];
};

type record TidTableRec {
	OCT4 teid,
	GTP_ConnHdlr vc_conn
};

type record ImsiTableRec {
	hexstring imsi,
	GTP_ConnHdlr vc_conn
};

private function f_comp_by_teid(OCT4 teid) runs on GTP_Emulation_CT return GTP_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_comp_by_imsi(hexstring imsi) runs on GTP_Emulation_CT return GTP_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_tid_tbl_add(OCT4 teid, GTP_ConnHdlr vc_conn) runs on GTP_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_imsi_tbl_add(hexstring imsi, GTP_ConnHdlr vc_conn) runs on GTP_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);
}

function f_gtpc_extract_imsi(PDU_GTPC gtp) return template (omit) hexstring {
	if (ischosen(gtp.gtpc_pdu.createPDPContextRequest)) {
		return gtp.gtpc_pdu.createPDPContextRequest.imsi.digits;
	} else if (ischosen(gtp.gtpc_pdu.updatePDPContextRequest.updatePDPContextRequestSGSN)) {
		return gtp.gtpc_pdu.updatePDPContextRequest.updatePDPContextRequestSGSN.imsi.digits;
	} else if (ischosen(gtp.gtpc_pdu.updatePDPContextRequest.updatePDPContextRequestGGSN)) {
		return gtp.gtpc_pdu.updatePDPContextRequest.updatePDPContextRequestGGSN.imsi.digits;
	} else if (ischosen(gtp.gtpc_pdu.updatePDPContextRequest.updatePDPContextRequestCGW)) {
		return gtp.gtpc_pdu.updatePDPContextRequest.updatePDPContextRequestCGW.imsi.digits;
	} else if (ischosen(gtp.gtpc_pdu.pdu_NotificationRequest)) {
		return gtp.gtpc_pdu.pdu_NotificationRequest.imsi.digits;
	} else if (ischosen(gtp.gtpc_pdu.sendRouteingInformationForGPRSRequest)) {
		return gtp.gtpc_pdu.sendRouteingInformationForGPRSRequest.imsi.digits;
	} else if (ischosen(gtp.gtpc_pdu.sendRouteingInformationForGPRSResponse)) {
		return gtp.gtpc_pdu.sendRouteingInformationForGPRSResponse.imsi.digits;
	} else if (ischosen(gtp.gtpc_pdu.failureReportRequest)) {
		return gtp.gtpc_pdu.failureReportRequest.imsi.digits;
	} else if (ischosen(gtp.gtpc_pdu.noteMS_GPRSPresentRequest)) {
		return gtp.gtpc_pdu.noteMS_GPRSPresentRequest.imsi.digits;
	} else if (ischosen(gtp.gtpc_pdu.identificationResponse) ){
		return gtp.gtpc_pdu.identificationResponse.imsi.digits;
	} else if (ischosen(gtp.gtpc_pdu.sgsn_ContextRequest)) {
		return gtp.gtpc_pdu.sgsn_ContextRequest.imsi.digits;
	} else if (ischosen(gtp.gtpc_pdu.sgsn_ContextResponse)) {
		return gtp.gtpc_pdu.sgsn_ContextResponse.imsi.digits;
	} else if (ischosen(gtp.gtpc_pdu.forwardRelocationRequest)) {
		return gtp.gtpc_pdu.forwardRelocationRequest.imsi.digits;
	} else if (ischosen(gtp.gtpc_pdu.relocationCancelRequest)) {
		return gtp.gtpc_pdu.relocationCancelRequest.imsi.digits;
	} else if (ischosen(gtp.gtpc_pdu.uERegistrationQueryRequest)) {
		return gtp.gtpc_pdu.uERegistrationQueryRequest.imsi.digits;
	} else if (ischosen(gtp.gtpc_pdu.uERegistrationQueryResponse)) {
		return gtp.gtpc_pdu.uERegistrationQueryResponse.imsi.digits;
	} else if (ischosen(gtp.gtpc_pdu.mBMSNotificationRequest)) {
		return gtp.gtpc_pdu.mBMSNotificationRequest.imsi.digits;
	} else if (ischosen(gtp.gtpc_pdu.createMBMSContextRequest)) {
		return gtp.gtpc_pdu.createMBMSContextRequest.imsi.digits;
	} else if (ischosen(gtp.gtpc_pdu.deleteMBMSContextRequest)) {
		return gtp.gtpc_pdu.deleteMBMSContextRequest.imsi.digits;
	} else if (ischosen(gtp.gtpc_pdu.mS_InfoChangeNotificationRequest)) {
		return gtp.gtpc_pdu.mS_InfoChangeNotificationRequest.imsi.digits;
	} else if (ischosen(gtp.gtpc_pdu.mS_InfoChangeNotificationResponse)) {
		return gtp.gtpc_pdu.mS_InfoChangeNotificationResponse.imsi.digits;
	} else {
		return omit;
	}
}

private function f_init(GtpEmulationCfg cfg) runs on GTP_Emulation_CT {
	var Result res;

	map(self:GTPC, system:GTPC);
	res := GTP_CodecPort_CtrlFunct.f_IPL4_listen(GTPC, cfg.gtpc_bind_ip,
						     cfg.gtpc_bind_port, {udp:={}});
	g_gtpc_id := res.connId;

	map(self:GTPU, system:GTPU);
	res := GTP_CodecPort_CtrlFunct.f_GTPU_listen(GTPU, cfg.gtpu_bind_ip,
						     cfg.gtpu_bind_port, {udp:={}});
	g_gtpu_id := res.connId;

	g_restart_ctr := f_rnd_octstring(1);
	g_c_seq_nr := f_rnd_int(65535);
	g_u_seq_nr := f_rnd_int(65535);
	g_gtp_cfg := cfg;
}

function main(GtpEmulationCfg cfg) runs on GTP_Emulation_CT {
	var Gtp1cUnitdata g1c_ud;
	var Gtp1uUnitdata g1u_ud;
	var GTP_ConnHdlr vc_conn;
	var hexstring imsi;
	var OCT4 teid;

	f_init(cfg);

	while (true) {
	alt {
	/* route inbound GTP-C based on IMSI or TEID */
	[] GTPC.receive(Gtp1cUnitdata:?) -> value g1c_ud {
		var template hexstring imsi_t := f_gtpc_extract_imsi(g1c_ud.gtpc);
		if (isvalue(imsi_t)) {
			vc_conn := f_comp_by_imsi(valueof(imsi_t));
			CLIENT.send(g1c_ud) to vc_conn;
		} else if(g1c_ud.gtpc.teid != int2oct(0, 4)) {
			vc_conn := f_comp_by_teid(g1c_ud.gtpc.teid);
			CLIENT.send(g1c_ud) to vc_conn;
		} else {
			/* Check if a default port is set: */
			if (CLIENT_DEFAULT.checkstate("Connected")) {
				CLIENT_DEFAULT.send(g1c_ud);
			} 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(g1c_ud) to TidTable[i].vc_conn;
					}
				}
			}
		}
		}
	[] GTPU.receive(Gtp1uUnitdata:?) -> value g1u_ud {
		vc_conn := f_comp_by_teid(g1u_ud.gtpu.teid);
		CLIENT.send(g1u_ud) to vc_conn;
		}

	/* transparently forward any GTP-C / GTP-U from clients to peer[s] */
	[] CLIENT.receive(Gtp1cUnitdata:?) -> value g1c_ud sender vc_conn {
		GTPC.send(g1c_ud);
		}
	[] CLIENT.receive(Gtp1uUnitdata:?) -> value g1u_ud sender vc_conn {
		GTPU.send(g1u_ud);
		}
	[] CLIENT_DEFAULT.receive(Gtp1cUnitdata:?) -> value g1c_ud sender vc_conn {
		GTPC.send(g1c_ud);
		}

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

	[] CLIENT_PROC.getcall(GTPEM_register_teid:{?}) -> param(teid) sender vc_conn {
		f_tid_tbl_add(teid, vc_conn);
		CLIENT_PROC.reply(GTPEM_register_teid:{teid}) to vc_conn;
		}

	}
	}
}


/***********************************************************************
 * Interaction between Main and Client Components
 ***********************************************************************/
type port GTPEM_PT message {
	inout Gtp1cUnitdata, Gtp1uUnitdata;
} with { extension "internal" };

signature GTPEM_register_imsi(hexstring imsi);
signature GTPEM_register_teid(OCT4 teid);

type port GTPEM_PROC_PT procedure {
	inout GTPEM_register_imsi, GTPEM_register_teid;
} with { extension "internal" };

/***********************************************************************
 * Client Compoennt
 ***********************************************************************/

type component GTP_ConnHdlr {
	port GTPEM_PT GTP;
	port GTPEM_PROC_PT GTP_PROC;
};

function f_gtp_register_imsi(hexstring imsi) runs on GTP_ConnHdlr {
	GTP_PROC.call(GTPEM_register_imsi:{imsi}) {
		[] GTP_PROC.getreply(GTPEM_register_imsi:{imsi});
	}
}

function f_gtp_register_teid(OCT4 teid) runs on GTP_ConnHdlr {
	GTP_PROC.call(GTPEM_register_teid:{teid}) {
		[] GTP_PROC.getreply(GTPEM_register_teid:{teid});
	}
}

}
