module MGCP_Emulation {

/* MGCP Emulation, runs on top of MGCP_CodecPort.  It multiplexes/demultiplexes
 * the individual connections, so there can be separate TTCN-3 components handling
 * each of the connections.
 *
 * The MGCP_Emulation.main() function processes MGCP primitives from the MGCP
 * socket via the MGCP_CodecPort, and dispatches them to the per-connection components.
 *
 * For each new inbound connection, the MgcpOps.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 + MGCP, and first trigger a connection from BSC side in a
 * component which then subsequently should also handle the MGCP emulation.
 *
 * Inbound Unit Data messages (such as are dispatched to the MgcpOps.unitdata_cb() callback,
 * which is registered with an argument to the main() function below.
 *
 * (C) 2017-2018 by Harald Welte <laforge@gnumonks.org>
 * (C) 2018 by sysmocom - s.f.m.c. GmbH, Author: Daniel Willmann
 * All rights reserved.
 *
 * Released under the terms of GNU General Public License, Version 2 or
 * (at your option) any later version.
 */

import from MGCP_CodecPort all;
import from MGCP_CodecPort_CtrlFunct all;
import from MGCP_Types all;
import from MGCP_Templates all;
import from Osmocom_Types all;
import from IPL4asp_Types all;

type component MGCP_ConnHdlr {
	port MGCP_Conn_PT MGCP;
	/* procedure based port to register for incoming connections */
	port MGCPEM_PROC_PT MGCP_PROC;
}

/* port between individual per-connection components and this dispatcher */
type port MGCP_Conn_PT message {
	inout MgcpCommand, MgcpResponse;
} with { extension "internal" };

/* represents a single MGCP Endpoint */
type record EndpointData {
	MGCP_ConnHdlr	comp_ref,
	MgcpEndpoint	endpoint optional
};

/* pending CRCX with their transaction ID */
type set of MgcpTransId MgcpTransIds;

type component MGCP_Emulation_CT {
	/* Port facing to the UDP SUT */
	port MGCP_CODEC_PT MGCP;
	/* All MGCP_ConnHdlr MGCP ports connect here
	 * MGCP_Emulation_CT.main needs to figure out what messages
	 * to send where with CLIENT.send() to vc_conn */
	port MGCP_Conn_PT MGCP_CLIENT;
	/* currently tracked connections */
	var EndpointData MgcpEndpointTable[16];
	var MgcpTransIds MgcpPendingTrans := {};
	/* pending expected CRCX */
	var ExpectData MgcpExpectTable[8];
	/* procedure based port to register for incoming connections */
	port MGCPEM_PROC_PT MGCP_PROC;

	var charstring g_mgcp_id;
	var integer g_mgcp_conn_id := -1;
}

type function MGCPCreateCallback(MgcpCommand cmd, charstring id)
runs on MGCP_Emulation_CT return MGCP_ConnHdlr;

type function MGCPUnitdataCallback(MgcpMessage msg)
runs on MGCP_Emulation_CT return template MgcpMessage;

type record MGCPOps {
	MGCPCreateCallback create_cb,
	MGCPUnitdataCallback unitdata_cb
}

type record MGCP_conn_parameters {
	HostName callagent_ip,
	PortNumber callagent_udp_port,
	HostName mgw_ip,
	PortNumber mgw_udp_port
}

function tr_MGCP_RecvFrom_R(template MgcpMessage msg)
runs on MGCP_Emulation_CT return template MGCP_RecvFrom {
	var template MGCP_RecvFrom mrf := {
		connId := g_mgcp_conn_id,
		remName := ?,
		remPort := ?,
		locName := ?,
		locPort := ?,
		msg := msg
	}
	return mrf;
}

private function f_ep_known(MgcpEndpoint ep)
runs on MGCP_Emulation_CT return boolean {
	var integer i;
	for (i := 0; i < sizeof(MgcpEndpointTable); i := i+1) {
		if (MgcpEndpointTable[i].endpoint == ep) {
			return true;
		}
	}
	return false;
}

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

private function f_comp_by_ep(MgcpEndpoint ep)
runs on MGCP_Emulation_CT return MGCP_ConnHdlr {
	var integer i;
	for (i := 0; i < sizeof(MgcpEndpointTable); i := i+1) {
		if (MgcpEndpointTable[i].endpoint == ep) {
			return MgcpEndpointTable[i].comp_ref;
		}
	}
	log("MGCP Endpoint Table not found by Endpoint", ep);
	setverdict(fail);
	self.stop;
}

private function f_ep_by_comp(MGCP_ConnHdlr client)
runs on MGCP_Emulation_CT return MgcpEndpoint {
	var integer i;
	for (i := 0; i < sizeof(MgcpEndpointTable); i := i+1) {
		if (MgcpEndpointTable[i].comp_ref == client) {
			return MgcpEndpointTable[i].endpoint;
		}
	}
	log("MGCP Endpoint Table not found by component ", client);
	setverdict(fail);
	self.stop;
}

private function f_ep_table_add(MGCP_ConnHdlr comp_ref, MgcpEndpoint ep)
runs on MGCP_Emulation_CT {
	var integer i;
	for (i := 0; i < sizeof(MgcpEndpointTable); i := i+1) {
		if (not isvalue(MgcpEndpointTable[i].endpoint)) {
			MgcpEndpointTable[i].endpoint := ep;
			MgcpEndpointTable[i].comp_ref := comp_ref;
			return;
		}
	}
	setverdict(fail, "MGCP Endpoint Table full!");
	self.stop;
}

private function f_ep_table_del(MGCP_ConnHdlr comp_ref, MgcpEndpoint ep)
runs on MGCP_Emulation_CT {
	var integer i;
	for (i := 0; i < sizeof(MgcpEndpointTable); i := i+1) {
		if (MgcpEndpointTable[i].comp_ref == comp_ref and
		    MgcpEndpointTable[i].endpoint == ep) {
			MgcpEndpointTable[i].endpoint := omit;
			MgcpEndpointTable[i].comp_ref := null;
			return;
		}
	}
	setverdict(fail, "MGCP Endpoint Table: Couldn't find to-be-deleted entry!");
	self.stop;
}


/* Check if the given transaction ID is a pending CRCX. If yes, return true + remove */
private function f_trans_id_was_pending(MgcpTransId trans_id)
runs on MGCP_Emulation_CT return boolean {
	for (var integer i := 0; i < lengthof(MgcpPendingTrans); i := i+1) {
		if (MgcpPendingTrans[i] == trans_id) {
			/* Remove from list */
			var MgcpTransIds OldPendingTrans := MgcpPendingTrans;
			MgcpPendingTrans := {}
			for (var integer j := 0; j < lengthof(OldPendingTrans); j := j+1) {
				if (j != i) {
					MgcpPendingTrans := MgcpPendingTrans & {OldPendingTrans[j]};
				}
			}
			return true;
		}
	}
	return false;
}

/* TODO: move this to MGCP_Types? */
function f_mgcp_ep(MgcpMessage msg) return MgcpEndpoint {
	var MgcpParameterList params;
	var integer i;
	if (ischosen(msg.command)) {
		return msg.command.line.ep;
	} else {
		var MgcpEndpoint ep;
		if (f_mgcp_find_param(msg, "Z", ep) == false) {
			setverdict(fail, "No SpecificEndpointName in MGCP response", msg);
			self.stop;
		}
		return ep;
	}
}

private function f_ep_table_init()
runs on MGCP_Emulation_CT {
	for (var integer i := 0; i < sizeof(MgcpEndpointTable); i := i+1) {
		MgcpEndpointTable[i].comp_ref := null;
		MgcpEndpointTable[i].endpoint := omit;
	}
}

function main(MGCPOps ops, MGCP_conn_parameters p, charstring id) runs on MGCP_Emulation_CT {
	var Result res;
	g_mgcp_id := id;
	f_ep_table_init();
	f_expect_table_init();

	map(self:MGCP, system:MGCP_CODEC_PT);
	if (p.callagent_udp_port == -1) {
		res := MGCP_CodecPort_CtrlFunct.f_IPL4_listen(MGCP, p.mgw_ip, p.mgw_udp_port, { udp:={} });
	} else {
		res := MGCP_CodecPort_CtrlFunct.f_IPL4_connect(MGCP, p.callagent_ip, p.callagent_udp_port, p.mgw_ip, p.mgw_udp_port, -1, { udp:={} });
	}

	g_mgcp_conn_id := res.connId;

	while (true) {
		var MGCP_ConnHdlr vc_conn;
		var ExpectCriteria crit;
		var MGCP_RecvFrom mrf;
		var MgcpMessage msg;
		var MgcpCommand cmd;
		var MgcpResponse resp;
		var MgcpEndpoint ep;

		alt {
		/* MGCP from client */
		[] MGCP_CLIENT.receive(MgcpResponse:?) -> value resp sender vc_conn {
			msg := {
				response := resp
			};
			/* If this is the resposne to a pending CRCX, extract Endpoint and store in table */
			if (f_trans_id_was_pending(resp.line.trans_id)) {
				f_ep_table_add(vc_conn, f_mgcp_ep(msg));
			}
			/* Pass message through */
			/* TODO: check which ConnectionID client has allocated + store in table? */
			MGCP.send(t_MGCP_Send(g_mgcp_conn_id, msg));
			}
		[] MGCP.receive(tr_MGCP_RecvFrom_R(?)) -> value mrf {
			if (p.callagent_udp_port == -1) {
				/* we aren't yet connected to the remote side port, let's fix this */
				p.callagent_udp_port := mrf.remPort;
				MGCP_CodecPort_CtrlFunct.f_IPL4_connect(MGCP, p.callagent_ip, p.callagent_udp_port, p.mgw_ip, p.mgw_udp_port, g_mgcp_conn_id, { udp:={} });
			}
			if (ischosen(mrf.msg.command)) {
				cmd := mrf.msg.command;
				if (f_ep_known(cmd.line.ep)) {
					vc_conn := f_comp_by_ep(cmd.line.ep);
					MGCP_CLIENT.send(cmd) to vc_conn;
				} else {
					if (cmd.line.verb == "CRCX") {
						vc_conn := ops.create_cb.apply(cmd, id);
						if (not match(cmd.line.ep, t_MGCP_EP_wildcard)) {
							/* non-wildcard EP, use directly */
							f_ep_table_add(vc_conn, cmd.line.ep);
						} else {
							/* add this transaction to list of pending transactions */
							MgcpPendingTrans := MgcpPendingTrans & {cmd.line.trans_id};
						}
						MGCP_CLIENT.send(cmd) to vc_conn;
					} else {
						/* connectionless MGCP, i.e. messages without ConnectionId */
						var template MgcpMessage r := ops.unitdata_cb.apply(mrf.msg);
						if (isvalue(r)) {
							MGCP.send(t_MGCP_Send(g_mgcp_conn_id, r));
						}
					}
				}
			} else {
				setverdict(fail, "Received unexpected MGCP response: ", mrf.msg.response);
				self.stop;
			}
			}
		[] MGCP_PROC.getcall(MGCPEM_register:{?,?}) -> param(crit, vc_conn) {
			f_create_expect(crit, vc_conn);
			MGCP_PROC.reply(MGCPEM_register:{crit, vc_conn});
			}
		[] MGCP_PROC.getcall(MGCPEM_delete_ep:{?,?}) -> param(ep, vc_conn) {
			f_ep_table_del(vc_conn, ep);
			MGCP_PROC.reply(MGCPEM_delete_ep:{ep, vc_conn});
			}
		}

	}
}

/* "Expect" Handling */

/*  */
type record ExpectCriteria {
	MgcpConnectionId connid optional,
	MgcpEndpoint endpoint optional,
	MgcpTransId transid optional
}

type record ExpectData {
	ExpectCriteria crit optional,
	MGCP_ConnHdlr vc_conn
}

signature MGCPEM_register(in ExpectCriteria cmd, in MGCP_ConnHdlr hdlr);
signature MGCPEM_delete_ep(in MgcpEndpoint ep, in MGCP_ConnHdlr hdlr);

type port MGCPEM_PROC_PT procedure {
	inout MGCPEM_register, MGCPEM_delete_ep;
} with { extension "internal" };

function f_get_mgcp_by_crit(ExpectCriteria crit)
return template MgcpCommand {
	var template MgcpCommand ret := {
		line := {
			verb := ?,
			trans_id := ?,
			ep := ?,
			ver := ?
		},
		params := *,
		sdp := *
	}
	if (ispresent(crit.connid)) {
		ret.params := { *, ts_MgcpParConnectionId(crit.connid), * };
	}
	if (ispresent(crit.endpoint)) {
		ret.line.ep := crit.endpoint;
	}
	if (ispresent(crit.transid)) {
		ret.line.trans_id := crit.transid;
	}

	return ret;
}

/* Function that can be used as create_cb and will usse the expect table */
function ExpectedCreateCallback(MgcpCommand cmd, charstring id)
runs on MGCP_Emulation_CT return MGCP_ConnHdlr {
	var MGCP_ConnHdlr ret := null;
	var template MgcpCommand mgcpcmd;
	var integer i;

	for (i := 0; i < sizeof(MgcpExpectTable); i := i+1) {
		if (not ispresent(MgcpExpectTable[i].crit)) {
			continue;
		}
		/* FIXME: Ignore criteria for now */
		mgcpcmd := f_get_mgcp_by_crit(MgcpExpectTable[i].crit);
		if (match(cmd, mgcpcmd)) {
			ret := MgcpExpectTable[i].vc_conn;
			/* Release this entry */
			MgcpExpectTable[i].crit := omit;
			MgcpExpectTable[i].vc_conn := null;
			log("Found Expect[", i, "] for ", cmd, " handled at ", ret);
			return ret;
		}
	}
	setverdict(fail, "Couldn't find Expect for CRCX", cmd);
	return ret;
}

private function f_create_expect(ExpectCriteria crit, MGCP_ConnHdlr hdlr)
runs on MGCP_Emulation_CT {
	var integer i;

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

/* client/conn_hdlr side function to use procedure port to create expect in emulation */
function f_create_mgcp_expect(ExpectCriteria dest_number) runs on MGCP_ConnHdlr {
	MGCP_PROC.call(MGCPEM_register:{dest_number, self}) {
		[] MGCP_PROC.getreply(MGCPEM_register:{?,?}) {};
	}
}

/* client/conn_hdlr side function to use procedure port to create expect in emulation */
function f_create_mgcp_delete_ep(MgcpEndpoint ep) runs on MGCP_ConnHdlr {
	MGCP_PROC.call(MGCPEM_delete_ep:{ep, self}) {
		[] MGCP_PROC.getreply(MGCPEM_delete_ep:{?,?}) {};
	}
}


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

function DummyUnitdataCallback(MgcpMessage msg)
runs on MGCP_Emulation_CT return template MgcpMessage {
	log("Ignoring MGCP ", msg);
	return omit;
}


}
