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.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

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 {
	/* Simple send/recv without caring about peer addr+port. Used with multi_conn_mode=false. */
	port MGCP_Conn_PT MGCP;
	/* Handle multiple connections concurrently. Used with multi_conn_mode=true. */
	port MGCP_Conn_Multi_PT MGCP_MULTI;
	/* 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" };

/* port between individual per-connection components and this dispatcher */
type port MGCP_Conn_Multi_PT message {
	inout MGCP_RecvFrom, MGCP_SendTo;
} 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;
	/* This one is used with multi_conn_mode=true and allows differentiating UDP sockets */
	port MGCP_Conn_Multi_PT MGCP_CLIENT_MULTI;
	/* 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;

	var MGCP_conn_parameters g_pars;
}

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,
	boolean multi_conn_mode
}

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;
		}
	}
	setverdict(fail, "MGCP Endpoint Table not found by Endpoint", ep);
	mtc.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;
		}
	}
	setverdict(fail, "MGCP Endpoint Table not found by component ", client);
	mtc.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;
		}
	}
	testcase.stop("MGCP Endpoint Table full!");
}

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!");
	mtc.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);
			mtc.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;
	}
}

private function f_forward_to_client(MGCP_RecvFrom mrf, MGCP_ConnHdlr vc_conn) runs on MGCP_Emulation_CT {
	if (g_pars.multi_conn_mode) {
		MGCP_CLIENT_MULTI.send(mrf) to vc_conn;
	} else {
		MGCP_CLIENT.send(mrf.msg.command) to vc_conn;
	}
}

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

	map(self:MGCP, system:MGCP_CODEC_PT);
	if (p.multi_conn_mode or 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:={} });
	}
	if (not ispresent(res.connId)) {
		setverdict(fail, "Could not connect MGCP socket, check your configuration");
		mtc.stop;
	}
	g_mgcp_conn_id := res.connId;

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

		alt {
		/* MGCP from client */
		[not p.multi_conn_mode] 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 from client in Multi Conn mode */
		[p.multi_conn_mode] MGCP_CLIENT_MULTI.receive(MGCP_SendTo:?) -> value mst sender vc_conn {
			/* If this is the resposne to a pending CRCX, extract Endpoint and store in table */
			if (f_trans_id_was_pending(mst.msg.response.line.trans_id)) {
				f_ep_table_add(vc_conn, f_mgcp_ep(mst.msg));
			}
			/* Pass message through */
			/* TODO: check which ConnectionID client has allocated + store in table? */
			MGCP.send(mst);
			}
		[] MGCP.receive(tr_MGCP_RecvFrom_R(?)) -> value mrf {
			if (not p.multi_conn_mode and p.callagent_udp_port == -1) {
				/* we aren't yet connected to the remote side
				   port, let's fix this. This way upper layers
				   can use Send/Recv without caring about UDP
				   src/dst addr + port */
				p.callagent_udp_port := mrf.remPort;
				res := 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 (not ispresent(res.connId)) {
					setverdict(fail, "Could not connect MGCP socket, check your configuration");
					mtc.stop;
				}
			}
			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);
					f_forward_to_client(mrf, 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};
						}
						f_forward_to_client(mrf, 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_SendToMrf(mrf, r));
						}
					}
				}
			} else {
				setverdict(fail, "Received unexpected MGCP response: ", mrf.msg.response);
				mtc.stop;
			}
			}
		[] MGCP_PROC.getcall(MGCPEM_register:{?,?}) -> param(crit, vc_conn) {
			f_create_expect(crit, vc_conn);
			MGCP_PROC.reply(MGCPEM_register:{crit, vc_conn}) to 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}) to 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);
	mtc.stop;
}

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);
			mtc.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;
		}
	}
	testcase.stop("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 delete 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;
}

/* Determine encoding name for a specified payload type number */
function f_encoding_name_from_pt(SDP_FIELD_PayloadType pt) return charstring {
	if (pt == PT_PCMU) {
		return "PCMU";
	} else if (pt == PT_GSM) {
		return "GSM";
	} else if (pt == PT_PCMA) {
		return "PCMA";
	} else if (pt == PT_GSMEFR) {
		return "GSM-EFR";
	} else if (pt == PT_GSMHR) {
		return "GSM-HR-08";
	} else if (pt == PT_AMR) {
		return "AMR";
	} else if (pt == PT_AMRWB) {
		return "AMR-WB";
	}

	setverdict(fail, "Unknown payload type ", pt);
	mtc.stop;
}

}
