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;
		}
	}
	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;
	}
}

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:={} });
	}
	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 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;
				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);
					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);
				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 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;
}

/* 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;
}

}
