module SGsAP_Emulation {

/* SGsAP Emulation, runs on top of SGsAP_CodecPort.  It multiplexes/demultiplexes
 * the individual IMSIs/subscribers, so there can be separate TTCN-3 components handling
 * each of them.
 *
 * The SGsAP_Emulation.main() function processes SGsAP primitives from the SGsAP
 * socket via the SGsAP_CodecPort, and dispatches them to the per-IMSI components.
 *
 * For each new IMSI, the SgsapOps.create_cb() is called.  It can create
 * or resolve a TTCN-3 component, and returns a component reference to which that IMSI
 * is routed/dispatched.
 *
 * If a pre-existing component wants to register to handle a future inbound IMSI, it can
 * do so by registering an "expect" with the expected IMSI.
 *
 * Inbound SGsAP messages without IMSI (such as RESET-IND/ACK) are dispatched to
 * the SgsapOps.unitdata_cb() callback, which is registered with an argument to the
 * main() function below.
 *
 * (C) 2018 by 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.
 */

import from SGsAP_CodecPort all;
import from SGsAP_CodecPort_CtrlFunct all;
import from SGsAP_Types all;
import from SGsAP_Templates all;
import from Osmocom_Types all;
import from IPL4asp_Types all;
import from DNS_Helpers all;

type component SGsAP_ConnHdlr {
	port SGsAP_Conn_PT SGsAP;
	/* procedure based port to register for incoming connections */
	port SGsAPEM_PROC_PT SGsAP_PROC;
}

/* port between individual per-connection components and this dispatcher */
type port SGsAP_Conn_PT message {
	inout PDU_SGsAP;
} with { extension "internal" };

/* represents a single SGsAP Association */
type record AssociationData {
	SGsAP_ConnHdlr	comp_ref,
	hexstring	imsi optional
};

type component SGsAP_Emulation_CT {
	/* Port facing to the UDP SUT */
	port SGsAP_CODEC_PT SGsAP;
	/* All SGsAP_ConnHdlr SGsAP ports connect here
	 * SGsAP_Emulation_CT.main needs to figure out what messages
	 * to send where with CLIENT.send() to vc_conn */
	port SGsAP_Conn_PT SGsAP_CLIENT;
	/* currently tracked connections */
	var AssociationData SgsapAssociationTable[16];
	/* pending expected CRCX */
	var ExpectData SgsapExpectTable[8];
	/* procedure based port to register for incoming connections */
	port SGsAPEM_PROC_PT SGsAP_PROC;

	var charstring g_sgsap_id;
	var integer g_sgsap_conn_id := -1;
}

type function SGsAPCreateCallback(PDU_SGsAP msg, hexstring imsi, charstring id)
runs on SGsAP_Emulation_CT return SGsAP_ConnHdlr;

type function SGsAPUnitdataCallback(PDU_SGsAP msg)
runs on SGsAP_Emulation_CT return template PDU_SGsAP;

type record SGsAPOps {
	SGsAPCreateCallback create_cb,
	SGsAPUnitdataCallback unitdata_cb
}

type record SGsAP_conn_parameters {
	HostName remote_ip,
	PortNumber remote_sctp_port,
	HostName local_ip,
	PortNumber local_sctp_port
}

function tr_SGsAP_RecvFrom_R(template PDU_SGsAP msg)
runs on SGsAP_Emulation_CT return template SGsAP_RecvFrom {
	var template SGsAP_RecvFrom mrf := {
		connId := g_sgsap_conn_id,
		remName := ?,
		remPort := ?,
		locName := ?,
		locPort := ?,
		msg := msg
	}
	return mrf;
}

private function f_imsi_known(hexstring imsi)
runs on SGsAP_Emulation_CT return boolean {
	var integer i;
	for (i := 0; i < sizeof(SgsapAssociationTable); i := i+1) {
		if (SgsapAssociationTable[i].imsi == imsi) {
			return true;
		}
	}
	return false;
}

private function f_comp_known(SGsAP_ConnHdlr client)
runs on SGsAP_Emulation_CT return boolean {
	var integer i;
	for (i := 0; i < sizeof(SgsapAssociationTable); i := i+1) {
		if (SgsapAssociationTable[i].comp_ref == client) {
			return true;
		}
	}
	return false;
}

private function f_comp_by_imsi(hexstring imsi)
runs on SGsAP_Emulation_CT return SGsAP_ConnHdlr {
	var integer i;
	for (i := 0; i < sizeof(SgsapAssociationTable); i := i+1) {
		if (SgsapAssociationTable[i].imsi == imsi) {
			return SgsapAssociationTable[i].comp_ref;
		}
	}
	setverdict(fail, "SGsAP Association Table not found by IMSI", imsi);
	mtc.stop;
}

private function f_imsi_by_comp(SGsAP_ConnHdlr client)
runs on SGsAP_Emulation_CT return hexstring {
	var integer i;
	for (i := 0; i < sizeof(SgsapAssociationTable); i := i+1) {
		if (SgsapAssociationTable[i].comp_ref == client) {
			return SgsapAssociationTable[i].imsi;
		}
	}
	setverdict(fail, "SGsAP Association Table not found by component ", client);
	mtc.stop;
}

private function f_imsi_table_add(SGsAP_ConnHdlr comp_ref, hexstring imsi)
runs on SGsAP_Emulation_CT {
	var integer i;
	for (i := 0; i < sizeof(SgsapAssociationTable); i := i+1) {
		if (not isvalue(SgsapAssociationTable[i].imsi)) {
			SgsapAssociationTable[i].imsi := imsi;
			SgsapAssociationTable[i].comp_ref := comp_ref;
			return;
		}
	}
	testcase.stop("SGsAP Association Table full!");
}

private function f_imsi_table_del(SGsAP_ConnHdlr comp_ref, hexstring imsi)
runs on SGsAP_Emulation_CT {
	var integer i;
	for (i := 0; i < sizeof(SgsapAssociationTable); i := i+1) {
		if (SgsapAssociationTable[i].comp_ref == comp_ref and
		    SgsapAssociationTable[i].imsi == imsi) {
			SgsapAssociationTable[i].imsi := omit;
			SgsapAssociationTable[i].comp_ref := null;
			return;
		}
	}
	setverdict(fail, "SGsAP Association Table: Couldn't find to-be-deleted entry!");
	mtc.stop;
}


private function f_imsi_table_init()
runs on SGsAP_Emulation_CT {
	for (var integer i := 0; i < sizeof(SgsapAssociationTable); i := i+1) {
		SgsapAssociationTable[i].comp_ref := null;
		SgsapAssociationTable[i].imsi := omit;
	}
}

private function f_SGsAP_get_imsi(PDU_SGsAP pdu) return template (omit) IMSI
{
	if (ischosen(pdu.sGsAP_ALERT_ACK)) {
		return pdu.sGsAP_ALERT_ACK.iMSI;
	} else if (ischosen(pdu.sGsAP_ALERT_REJECT)) {
		return pdu.sGsAP_ALERT_REJECT.iMSI;
	} else if (ischosen(pdu.sGsAP_ALERT_REQUEST)) {
		return pdu.sGsAP_ALERT_REQUEST.iMSI;
	} else if (ischosen(pdu.sGsAP_DOWNLINK_UNITDATA)) {
		return pdu.sGsAP_DOWNLINK_UNITDATA.iMSI;
	} else if (ischosen(pdu.sGsAP_EPS_DETACH_ACK)) {
		return pdu.sGsAP_EPS_DETACH_ACK.iMSI;
	} else if (ischosen(pdu.sGsAP_EPS_DETACH_INDICATION)) {
		return pdu.sGsAP_EPS_DETACH_INDICATION.iMSI;
	} else if (ischosen(pdu.sGsAP_IMSI_DETACH_ACK)) {
		return pdu.sGsAP_IMSI_DETACH_ACK.iMSI;
	} else if (ischosen(pdu.sGsAP_IMSI_DETACH_INDICATION)) {
		return pdu.sGsAP_IMSI_DETACH_INDICATION.iMSI;
	} else if (ischosen(pdu.sGsAP_LOCATION_UPDATE_ACCEPT)) {
		return pdu.sGsAP_LOCATION_UPDATE_ACCEPT.iMSI;
	} else if (ischosen(pdu.sGsAP_LOCATION_UPDATE_REJECT)) {
		return pdu.sGsAP_LOCATION_UPDATE_REJECT.iMSI;
	} else if (ischosen(pdu.sGsAP_LOCATION_UPDATE_REQUEST)) {
		return pdu.sGsAP_LOCATION_UPDATE_REQUEST.iMSI;
	} else if (ischosen(pdu.sGsAP_MM_INFORMATION_REQUEST)) {
		return pdu.sGsAP_MM_INFORMATION_REQUEST.iMSI;
	} else if (ischosen(pdu.sGsAP_PAGING_REJECT)) {
		return pdu.sGsAP_PAGING_REJECT.iMSI;
	} else if (ischosen(pdu.sGsAP_PAGING_REQUEST)) {
		return pdu.sGsAP_PAGING_REQUEST.iMSI;
	} else if (ischosen(pdu.sGsAP_SERVICE_REQUEST)) {
		return pdu.sGsAP_SERVICE_REQUEST.iMSI;
	} else if (ischosen(pdu.sGsAP_STATUS)) {
		return pdu.sGsAP_STATUS.iMSI;
	} else if (ischosen(pdu.sGsAP_TMSI_REALLOCATION_COMPLETE)) {
		return pdu.sGsAP_TMSI_REALLOCATION_COMPLETE.iMSI;
	} else if (ischosen(pdu.sGsAP_UE_ACTIVITY_INDICATION)) {
		return pdu.sGsAP_UE_ACTIVITY_INDICATION.iMSI;
	} else if (ischosen(pdu.sGsAP_UE_UNREACHABLE)) {
		return pdu.sGsAP_UE_UNREACHABLE.iMSI;
	} else if (ischosen(pdu.sGsAP_UPLINK_UNITDATA)) {
		return pdu.sGsAP_UPLINK_UNITDATA.iMSI;
	} else if (ischosen(pdu.sGsAP_RELEASE_REQUEST)) {
		return pdu.sGsAP_RELEASE_REQUEST.iMSI;
	} else if (ischosen(pdu.sGsAP_SERVICE_ABORT_REQUEST)) {
		return pdu.sGsAP_SERVICE_ABORT_REQUEST.iMSI;
	} else if (ischosen(pdu.sGsAP_MO_CSFB_INDICATION)) {
		return pdu.sGsAP_MO_CSFB_INDICATION.iMSI;
	}
	return omit;
}

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

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

private function f_sgsap_xceive(template (value) PDU_SGsAP tx,
				template PDU_SGsAP rx_t := ?)
runs on SGsAP_Emulation_CT  return PDU_SGsAP {
	timer T := 10.0;
	var SGsAP_RecvFrom mrf;

	SGsAP.send(t_SGsAP_Send(g_sgsap_conn_id, tx));
	alt {
	[] SGsAP.receive(tr_SGsAP_RecvFrom_R(rx_t)) -> value mrf { }
	[] SGsAP.receive(tr_SctpAssocChange) { repeat; }
	[] SGsAP.receive(tr_SctpPeerAddrChange)  { repeat; }
	[] T.timeout {
		setverdict(fail, "Timeout waiting for ", rx_t);
		mtc.stop;
		}
	}
	return mrf.msg;
}

function main(SGsAPOps ops, SGsAP_conn_parameters p, charstring id) runs on SGsAP_Emulation_CT {
	var Result res;
	g_sgsap_id := id;
	f_imsi_table_init();
	f_expect_table_init();

	map(self:SGsAP, system:SGsAP_CODEC_PT);
	if (p.remote_sctp_port == -1) {
		res := SGsAP_CodecPort_CtrlFunct.f_IPL4_listen(SGsAP, p.local_ip, p.local_sctp_port, { sctp := valueof(ts_SCTP) });
	} else {
		res := SGsAP_CodecPort_CtrlFunct.f_IPL4_connect(SGsAP, p.remote_ip, p.remote_sctp_port,
								p.local_ip, p.local_sctp_port, -1, { sctp := valueof(ts_SCTP) });
	}
	if (not ispresent(res.connId)) {
		setverdict(fail, "Could not connect SGsAP socket, check your configuration");
		mtc.stop;
	}
	g_sgsap_conn_id := res.connId;

	while (true) {
		var SGsAP_ConnHdlr vc_conn;
		var template IMSI imsi_t;
		var hexstring imsi;
		var SGsAP_RecvFrom mrf;
		var PDU_SGsAP msg;
		var charstring vlr_name, mme_name;

		alt {
		/* SGsAP from client */
		[] SGsAP_CLIENT.receive(PDU_SGsAP:?) -> value msg sender vc_conn {
			/* Pass message through */
			/* TODO: check which ConnectionID client has allocated + store in table? */
			SGsAP.send(t_SGsAP_Send(g_sgsap_conn_id, msg));
			}
		[] SGsAP.receive(tr_SGsAP_RecvFrom_R(?)) -> value mrf {
			imsi_t := f_SGsAP_get_imsi(mrf.msg);
			if (isvalue(imsi_t)) {
				imsi := valueof(imsi_t.iMSI.digits);
				if (f_imsi_known(imsi)) {
					vc_conn := f_comp_by_imsi(imsi);
					SGsAP_CLIENT.send(mrf.msg) to vc_conn;
				} else {
					vc_conn := ops.create_cb.apply(mrf.msg, imsi, id);
					f_imsi_table_add(vc_conn, imsi);
					SGsAP_CLIENT.send(mrf.msg) to vc_conn;
				}
			} else {
				/* message contained no IMSI; is not IMSI-oriented */
				var template PDU_SGsAP resp := ops.unitdata_cb.apply(mrf.msg);
				if (isvalue(resp)) {
					SGsAP.send(t_SGsAP_Send(g_sgsap_conn_id, valueof(resp)));
				}
			}
			}
		[] SGsAP.receive(tr_SctpAssocChange) { }
		[] SGsAP.receive(tr_SctpPeerAddrChange)  { }
		[] SGsAP_PROC.getcall(SGsAPEM_register:{?,?}) -> param(imsi, vc_conn) {
			f_create_expect(imsi, vc_conn);
			SGsAP_PROC.reply(SGsAPEM_register:{imsi, vc_conn}) to vc_conn;
			}
		[] SGsAP_PROC.getcall(SGsAPEM_reset_mme:{?,-}) -> param(mme_name) {
			var octetstring mme_enc, vlr_enc;
			mme_enc := f_enc_dns_hostname(mme_name);
			msg := f_sgsap_xceive(ts_SGsAP_RESET_IND_MME(mme_enc));
			vlr_enc := msg.sGsAP_RESET_ACK.vLR_Name.name;
			vlr_name := f_dec_dns_hostname(vlr_enc);
			SGsAP_PROC.reply(SGsAPEM_reset_mme:{mme_name, vlr_name});
			}
		[] SGsAP_PROC.getcall(SGsAPEM_reset_vlr:{?,-}) -> param(vlr_name) {
			var octetstring mme_enc, vlr_enc;
			vlr_enc := f_enc_dns_hostname(vlr_name);
			msg := f_sgsap_xceive(ts_SGsAP_RESET_IND_VLR(vlr_enc));
			mme_enc := msg.sGsAP_RESET_ACK.mME_Name.name;
			mme_name := f_dec_dns_hostname(mme_enc);
			SGsAP_PROC.reply(SGsAPEM_reset_vlr:{vlr_name, mme_name});
			}


		}

	}
}

/* "Expect" Handling */

type record ExpectData {
	hexstring imsi optional,
	SGsAP_ConnHdlr vc_conn
}

signature SGsAPEM_register(in hexstring imsi, in SGsAP_ConnHdlr hdlr);

signature SGsAPEM_reset_vlr(in charstring vlr_name, out charstring mme_name);
signature SGsAPEM_reset_mme(in charstring mme_name, out charstring vlr_name);

type port SGsAPEM_PROC_PT procedure {
	inout SGsAPEM_register, SGsAPEM_reset_vlr, SGsAPEM_reset_mme;
} with { extension "internal" };

/* Function that can be used as create_cb and will usse the expect table */
function ExpectedCreateCallback(PDU_SGsAP msg, hexstring imsi, charstring id)
runs on SGsAP_Emulation_CT return SGsAP_ConnHdlr {
	var SGsAP_ConnHdlr ret := null;
	var integer i;

	for (i := 0; i < sizeof(SgsapExpectTable); i := i+1) {
		if (not ispresent(SgsapExpectTable[i].imsi)) {
			continue;
		}
		if (imsi == SgsapExpectTable[i].imsi) {
			ret := SgsapExpectTable[i].vc_conn;
			/* Release this entry */
			SgsapExpectTable[i].imsi := omit;
			SgsapExpectTable[i].vc_conn := null;
			log("Found Expect[", i, "] for ", msg, " handled at ", ret);
			return ret;
		}
	}
	setverdict(fail, "Couldn't find Expect for ", msg);
	mtc.stop;
}

private function f_create_expect(hexstring imsi, SGsAP_ConnHdlr hdlr)
runs on SGsAP_Emulation_CT {
	var integer i;

	/* Check an entry like this is not already presnt */
	for (i := 0; i < sizeof(SgsapExpectTable); i := i+1) {
		if (imsi == SgsapExpectTable[i].imsi) {
			setverdict(fail, "IMSI already present", imsi);
			mtc.stop;
		}
	}
	for (i := 0; i < sizeof(SgsapExpectTable); i := i+1) {
		if (not ispresent(SgsapExpectTable[i].imsi)) {
			SgsapExpectTable[i].imsi := imsi;
			SgsapExpectTable[i].vc_conn := hdlr;
			log("Created Expect[", i, "] for ", imsi, " to be handled at ", hdlr);
			return;
		}
	}
	testcase.stop("No space left in SgsapExpectTable")
}

/* client/conn_hdlr side function to use procedure port to create expect in emulation */
function f_create_sgsap_expect(hexstring imsi) runs on SGsAP_ConnHdlr {
	SGsAP_PROC.call(SGsAPEM_register:{imsi, self}) {
		[] SGsAP_PROC.getreply(SGsAPEM_register:{?,?}) {};
	}
}

/* client/conn_hdlr side function to use procedure port to send RESET from emulated MME */
function f_sgsap_reset_mme(charstring mme_name) runs on SGsAP_ConnHdlr return charstring {
	var charstring vlr_name;
	SGsAP_PROC.call(SGsAPEM_reset_mme:{mme_name, -}) {
		[] SGsAP_PROC.getreply(SGsAPEM_reset_mme:{mme_name,?}) -> param(vlr_name) {
			return vlr_name;
			};
	}
}

/* client/conn_hdlr side function to use procedure port to send RESET from emulated VLR */
function f_sgsap_reset_vlr(charstring vlr_name) runs on SGsAP_ConnHdlr return charstring {
	var charstring mme_name;
	SGsAP_PROC.call(SGsAPEM_reset_vlr:{vlr_name, -}) {
		[] SGsAP_PROC.getreply(SGsAPEM_reset_vlr:{vlr_name,?}) -> param(mme_name) {
			return mme_name;
			};
	}
}

private function f_expect_table_init()
runs on SGsAP_Emulation_CT {
	var integer i;
	for (i := 0; i < sizeof(SgsapExpectTable); i := i + 1) {
		SgsapExpectTable[i].imsi := omit;
	}
}

function DummyUnitdataCallback(PDU_SGsAP msg)
runs on SGsAP_Emulation_CT return template PDU_SGsAP {
	log("Ignoring SGsAP ", msg);
	return omit;
}


}
