module MNCC_Emulation {

/* MNCC Emulation, runs on top of MNCC_CodecPort.  It multiplexes/demultiplexes
 * the individual calls, so there can be separate TTCN-3 components handling
 * each of the calls
 *
 * The MNCC_Emulation.main() function processes MNCC primitives from the MNCC
 * socket via the MNCC_CodecPort, and dispatches them to the per-connection components.
 *
 * Outbound MNCC connections are initiated by sending a MNCC_Call_Req primitive
 * to the component running the MNCC_Emulation.main() function.
 *
 * For each new inbound connections, the MnccOps.create_cb() is called.  It can create
 * or resolve a TTCN-3 component, and returns a component reference to which that inbound
 * connection is routed/dispatched.
 *
 * If a pre-existing component wants to register to handle a future inbound call, it can
 * do so by registering an "expect" with the expected destination phone number.  This is e.g. useful
 * if you are simulating BSC + MNCC, and first trigger a connection from BSC side in a
 * component which then subsequently should also handle the MNCC emulation.
 *
 * Inbound Unit Data messages (such as are dispatched to the MnccOps.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.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */


import from Osmocom_Types all;
import from MNCC_CodecPort all;
import from MNCC_Types all;
import from UD_Types all;

modulepar {
	int mp_mncc_version := 8;
}

/* General "base class" component definition, of which specific implementations
 * derive themselves by means of the "extends" feature */
type component MNCC_ConnHdlr {
	/* ports towards MNCC Emulator core / call dispatchar */
	port MNCC_Conn_PT MNCC;
	port MNCCEM_PROC_PT MNCC_PROC;
}

/* Auxiliary primitive that can happen on the port between per-connection client and this dispatcher */
type enumerated MNCC_Conn_Prim {
	/* MNCC tell us that connection was released */
	MNCC_CONN_PRIM_DISC_IND,
	/* we tell MNCC to release connection */
	MNCC_CONN_PRIM_DISC_REQ
}

type record MNCC_Conn_Req {
	MNCC_PDU		mncc
}

/* port between individual per-connection components and this dispatcher */
type port MNCC_Conn_PT message {
	inout MNCC_PDU, MNCC_Conn_Prim, MNCC_Conn_Req;
} with { extension "internal" };


/* represents a single MNCC call */
type record ConnectionData {
	/* reference to the instance of the per-connection component */
	MNCC_ConnHdlr	comp_ref,
	integer		mncc_call_id
}

type component MNCC_Emulation_CT {
	/* UNIX DOMAIN socket on the bottom side, using primitives */
	port MNCC_CODEC_PT MNCC;
	/* MNCC port to the per-connection clients */
	port MNCC_Conn_PT MNCC_CLIENT;

	/* use 16 as this is also the number of SCCP connections that SCCP_Emulation can handle */
	var ConnectionData MnccCallTable[16];

	/* pending expected incoming connections */
	var ExpectData MnccExpectTable[8];
	/* procedure based port to register for incoming connections */
	port MNCCEM_PROC_PT MNCC_PROC;

	var integer g_mncc_ud_id;
};

private function f_call_id_known(uint32_t mncc_call_id)
runs on MNCC_Emulation_CT return boolean {
	var integer i;
	for (i := 0; i < sizeof(MnccCallTable); i := i+1) {
		if (MnccCallTable[i].mncc_call_id == mncc_call_id){
			return true;
		}
	}
	return false;
}

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

/* resolve component reference by connection ID */
private function f_comp_by_call_id(uint32_t mncc_call_id)
runs on MNCC_Emulation_CT return MNCC_ConnHdlr {
	var integer i;
	for (i := 0; i < sizeof(MnccCallTable); i := i+1) {
		if (MnccCallTable[i].mncc_call_id == mncc_call_id) {
			return MnccCallTable[i].comp_ref;
		}
	}
	setverdict(fail, "MNCC Call table not found by MNCC Call ID ", mncc_call_id);
	mtc.stop;
}

/* resolve connection ID by component reference */
private function f_call_id_by_comp(MNCC_ConnHdlr client)
runs on MNCC_Emulation_CT return integer {
	for (var integer i := 0; i < sizeof(MnccCallTable); i := i+1) {
		if (MnccCallTable[i].comp_ref == client) {
			return MnccCallTable[i].mncc_call_id;
		}
	}
	setverdict(fail, "MNCC Call table not found by component ", client);
	mtc.stop;
}

private function f_gen_call_id()
runs on MNCC_Emulation_CT return integer {
	var uint32_t call_id;

	do {
		call_id := float2int(rnd()*4294967296.0);
	} while (f_call_id_known(call_id) == true);

	return call_id;
}

private function f_expect_table_init()
runs on MNCC_Emulation_CT {
	for (var integer i := 0; i < sizeof(MnccExpectTable); i := i+1) {
		MnccExpectTable[i].dest_number := omit;
		MnccExpectTable[i].vc_conn := null;
	}
}

private function f_call_table_init()
runs on MNCC_Emulation_CT {
	for (var integer i := 0; i < sizeof(MnccCallTable); i := i+1) {
		MnccCallTable[i].comp_ref := null;
		MnccCallTable[i].mncc_call_id := -1;
	}
}

private function f_call_table_add(MNCC_ConnHdlr comp_ref, uint32_t mncc_call_id)
runs on MNCC_Emulation_CT {
	for (var integer i := 0; i < sizeof(MnccCallTable); i := i+1) {
		if (MnccCallTable[i].mncc_call_id == -1) {
			MnccCallTable[i].comp_ref := comp_ref;
			MnccCallTable[i].mncc_call_id := mncc_call_id;
			log("Added conn table entry ", i, comp_ref, mncc_call_id);
			return;
		}
	}
	testcase.stop("MNCC Call table full!");
}

private function f_call_table_del(uint32_t mncc_call_id)
runs on MNCC_Emulation_CT {
	for (var integer i := 0; i < sizeof(MnccCallTable); i := i+1) {
		if (MnccCallTable[i].mncc_call_id == mncc_call_id) {
			log("Deleted conn table entry ", i,
			    MnccCallTable[i].comp_ref, mncc_call_id);
			MnccCallTable[i].mncc_call_id := -1;
			MnccCallTable[i].comp_ref := null;
			return
		}
	}
	setverdict(fail, "MNCC Call table attempt to delete non-existant ", mncc_call_id);
	mtc.stop;
}


private function f_connect(charstring sock) runs on MNCC_Emulation_CT {
	var UD_connect_result res;
	timer T := 5.0;

	T.start;
	MNCC.send(UD_connect:{sock, -1});
	alt {
	[] MNCC.receive(UD_connect_result:?) -> value res {
		if (ispresent(res.result) and ispresent(res.result.result_code) and res.result.result_code == ERROR) {
			setverdict(fail, "Error connecting to MNCC socket", res);
			mtc.stop;
		} else {
			g_mncc_ud_id := res.id;
		}
		}
	[] T.timeout {
		setverdict(fail, "Timeout connecting to MNCC socket");
		mtc.stop;
		}
	}
}

private function f_listen(charstring sock) runs on MNCC_Emulation_CT {
	var UD_listen_result res;
	var UD_connected udc;
	timer T := 5.0;

	T.start;
	MNCC.send(UD_listen:{sock});
	alt {
	[] MNCC.receive(UD_listen_result:?) -> value res {
		if (ispresent(res.result) and ispresent(res.result.result_code) and res.result.result_code == ERROR) {
			setverdict(fail, "Error listening to MNCC socket", res);
			mtc.stop;
		} else {
			g_mncc_ud_id := res.id;
		}
		}
	[] T.timeout {
		setverdict(fail, "Timeout listening to MNCC socket");
		mtc.stop;
		}
	}

	T.start;
	alt {
	[] MNCC.receive(UD_connected:?) -> value udc {
		g_mncc_ud_id := res.id;
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for MNCC connection");
		mtc.stop;
		}
	}
}

/* call-back type, to be provided by specific implementation; called when new SCCP connection
 * arrives */
type function MnccCreateCallback(MNCC_PDU conn_ind, charstring id)
runs on MNCC_Emulation_CT return MNCC_ConnHdlr;

type function MnccUnitdataCallback(MNCC_PDU mncc)
runs on MNCC_Emulation_CT return template MNCC_PDU;

type record MnccOps {
	MnccCreateCallback create_cb,
	MnccUnitdataCallback unitdata_cb
}

function main(MnccOps ops, charstring id, charstring sock, boolean role_server := false)
runs on MNCC_Emulation_CT {

	if (not set_MNCC_version(mp_mncc_version)) {
		setverdict(fail, "Failed configuring MNCC enc/dec to version ", mp_mncc_version);
		return;
	}

	if (role_server) {
		f_listen(sock);
		MNCC.send(t_SD_MNCC(g_mncc_ud_id, ts_MNCC_HELLO(version := mp_mncc_version)));
	} else {
		f_connect(sock);
	}
	f_expect_table_init();
	f_call_table_init();

	while (true) {
		var MNCC_send_data sd;
		var MNCC_Conn_Req creq;
		var MNCC_ConnHdlr vc_conn;
		var MNCC_PDU mncc;
		var MNCC_ConnHdlr vc_hdlr;
		var charstring dest_nr;
		var uint32_t mncc_call_id;

		alt {
		/* MNCC -> Client: UNIT-DATA (connectionless SCCP) from a BSC */
		[] MNCC.receive(t_SD_MNCC_MSGT(g_mncc_ud_id, MNCC_SOCKET_HELLO)) -> value sd {
			/* Connectionless Procedures like HELLO */
			var template MNCC_PDU resp;
			resp := ops.unitdata_cb.apply(sd.data);
			if (isvalue(resp)) {
				MNCC.send(t_SD_MNCC(g_mncc_ud_id, resp));
			}
			}

		/* MNCC -> Client: Release Indication / confirmation */
		[] MNCC.receive(t_SD_MNCC_MSGT(g_mncc_ud_id, (MNCC_REL_IND, MNCC_REL_CNF))) -> value sd {
			var uint32_t call_id := f_mncc_get_call_id(sd.data);
			/* forward to respective client */
			vc_conn := f_comp_by_call_id(call_id);
			MNCC_CLIENT.send(sd.data) to vc_conn;
			/* remove from call table */
			f_call_table_del(call_id);
			}

		/* MNCC -> Client: call related messages */
		[] MNCC.receive(t_SD_MNCC_MSGT(g_mncc_ud_id, ?)) -> value sd {
			var uint32_t call_id := f_mncc_get_call_id(sd.data);

			if (f_call_id_known(call_id)) {
				vc_conn := f_comp_by_call_id(call_id);
				MNCC_CLIENT.send(sd.data) to vc_conn;
			} else {
				/* TODO: Only accept this for SETUP.req? */
				vc_conn := ops.create_cb.apply(sd.data, id)
				/* store mapping between client components and SCCP connectionId */
				f_call_table_add(vc_conn, call_id);
				/* handle user payload */
				MNCC_CLIENT.send(sd.data) to vc_conn;
			}
			}

		/* Client -> MNCC Socket: RELEASE.ind or RELEASE.cnf: forward + drop call table entry */
		[] MNCC_CLIENT.receive(MNCC_PDU:{msg_type := (MNCC_REL_IND, MNCC_REL_CNF), u:=?}) -> value mncc sender vc_conn {
			var integer call_id := f_call_id_by_comp(vc_conn);
			/* forward to MNCC socket */
			MNCC.send(t_SD_MNCC(g_mncc_ud_id, mncc));
			/* remove from call table */
			f_call_table_del(call_id);
			}

		/* Client -> MNCC Socket: Normal message */
		[] MNCC_CLIENT.receive(MNCC_PDU:?) -> value mncc sender vc_conn {
			if (mncc.msg_type == MNCC_SETUP_REQ and not role_server) {
				/* ConnHdlr -> MNCC Server: SETUP.req: add to call table */
				f_call_table_add(vc_conn, f_mncc_get_call_id(mncc));
			} else if (mncc.msg_type == MNCC_SETUP_IND and role_server) {
				/* ConnHdlr -> MNCC Client: SETUP.ind: add to call table */
				f_call_table_add(vc_conn, f_mncc_get_call_id(mncc));
			}
			/* forward to MNCC socket */
			MNCC.send(t_SD_MNCC(g_mncc_ud_id, mncc));
			}

		[] MNCC_CLIENT.receive(MNCC_PDU:?) -> value mncc sender vc_conn {
			/* forward to MNCC socket */
			MNCC.send(t_SD_MNCC(g_mncc_ud_id, mncc));
			}


		/* Client -> us: procedure call to register expect */
		[] MNCC_PROC.getcall(MNCCEM_register:{?,?}) -> param(dest_nr, vc_hdlr) {
			f_create_expect(dest_nr, vc_hdlr);
			MNCC_PROC.reply(MNCCEM_register:{dest_nr, vc_hdlr}) to vc_hdlr;
			}

		[] MNCC_PROC.getcall(MNCCEM_change_connhdlr:{?,?}) -> param(mncc_call_id, vc_hdlr) {
			f_call_table_del(mncc_call_id);
			f_call_table_add(vc_hdlr, mncc_call_id);
			MNCC_PROC.reply(MNCCEM_change_connhdlr:{mncc_call_id, vc_hdlr}) to vc_hdlr;
			}
		}
	}
}

private function f_mgcp_ep_extract_cic(charstring inp) return integer {
	var charstring local_part := regexp(inp, "(*)@*", 0);
	return hex2int(str2hex(local_part));

}

/***********************************************************************
 * "Expect" Handling (mapping for expected incoming MNCC calls from IUT)
 ***********************************************************************/

/* data about an expected future incoming connection */
type record ExpectData {
	/* destination number based on which we can match it */
	charstring dest_number optional,
	/* component reference for this connection */
	MNCC_ConnHdlr vc_conn
}

/* procedure based port to register for incoming calls */
signature MNCCEM_register(in charstring dest_nr, in MNCC_ConnHdlr hdlr);
signature MNCCEM_change_connhdlr(in uint32_t mncc_call_id, in MNCC_ConnHdlr hdlr);

type port MNCCEM_PROC_PT procedure {
	inout MNCCEM_register, MNCCEM_change_connhdlr;
} with { extension "internal" };

/* CreateCallback that can be used as create_cb and will use the expectation table */
function ExpectedCreateCallback(MNCC_PDU conn_ind, charstring id)
runs on MNCC_Emulation_CT return MNCC_ConnHdlr {
	var MNCC_ConnHdlr ret := null;
	var charstring dest_number;
	var integer i;

	if (not ischosen(conn_ind.u.signal) or
	    (conn_ind.msg_type != MNCC_SETUP_IND and conn_ind.msg_type != MNCC_SETUP_REQ)) {
		setverdict(fail, "MNCC ExpectedCreateCallback needs MNCC_SETUP_{IND,REQ}");
		mtc.stop;
		return ret;
	}
	dest_number := conn_ind.u.signal.called.number;

	for (i := 0; i < sizeof(MnccExpectTable); i:= i+1) {
		if (not ispresent(MnccExpectTable[i].dest_number)) {
			continue;
		}
		if (dest_number == MnccExpectTable[i].dest_number) {
			ret := MnccExpectTable[i].vc_conn;
			/* release this entry to be used again */
			MnccExpectTable[i].dest_number := omit;
			MnccExpectTable[i].vc_conn := null;
			log("Found MnccExpect[", i, "] for ", dest_number, " handled at ", ret);
			/* return the component reference */
			return ret;
		}
	}
	setverdict(fail, "Couldn't find MnccExpect for incoming call ", dest_number);
	mtc.stop;
	return ret;
}

/* server/emulation side function to create expect */
private function f_create_expect(charstring dest_number, MNCC_ConnHdlr hdlr)
runs on MNCC_Emulation_CT {
	var integer i;
	for (i := 0; i < sizeof(MnccExpectTable); i := i+1) {
		if (not ispresent(MnccExpectTable[i].dest_number)) {
			MnccExpectTable[i].dest_number := dest_number;
			MnccExpectTable[i].vc_conn := hdlr;
			log("Created MnccExpect[", i, "] for ", dest_number, " to be handled at ", hdlr);
			return;
		}
	}
	testcase.stop("No space left in MnccMnccExpectTable");
}

/* client/conn_hdlr side function to use procedure port to create expect in emulation */
function f_create_mncc_expect(charstring dest_number) runs on MNCC_ConnHdlr {
	MNCC_PROC.call(MNCCEM_register:{dest_number, self}) {
		[] MNCC_PROC.getreply(MNCCEM_register:{?,?}) {};
	}
}

/* Move MNCC handling for a given call id to another MNCC_ConnHdlr test component. */
function f_mncc_change_connhdlr(uint32_t mncc_call_id) runs on MNCC_ConnHdlr {
	MNCC_PROC.call(MNCCEM_change_connhdlr:{mncc_call_id, self}) {
		[] MNCC_PROC.getreply(MNCCEM_change_connhdlr:{?,?}) {};
	}
}

function DummyUnitdataCallback(MNCC_PDU mncc)
runs on MNCC_Emulation_CT return template MNCC_PDU {
	log("Ignoring MNCC ", mncc);
	return omit;
}

}
