module SIP_Emulation {

/* SIP Emulation, runs on top of SIPmsg_PT.  It multiplexes/demultiplexes
 * the individual calls, so there can be separate TTCN-3 components handling
 * each of the calls
 *
 * The SIP_Emulation.main() function processes SIP message from the SIPmsg
 * socket via the SIPmsg_PT, and dispatches them to the per-connection components.
 *
 * Outbound SIP calls are initiated by sending a PDU_SIP_Request messages
 * to the component running the SIP_Emulation.main() function.
 *
 * For each new inbound call, the SipOps.create_cb() is called.  It can create
 * or resolve a TTCN-3 component, and returns a component reference to which that inbound
 * call 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 MNCC + SIP, and first trigger a connection from MNCC side in a
 * component which then subsequently should also handle the SIP emulation.
 *
 * (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 SIPmsg_Types all;
import from SIPmsg_PortType all;

type component SIP_ConnHdlr {
	/* ports towards SIP Emulation core / call dispatcher */
	port SIP_Conn_PT SIP;
	port SIPEM_PROC_PT SIP_PROC;
}

/* port between individual per-call components and this dispatcher */
type port SIP_Conn_PT message {
	inout PDU_SIP_Request, PDU_SIP_Response;
} with { extension "internal" };

/* represents a single SIP Call */
type record CallData {
	/* reference to the instance of the per-connection component */
	SIP_ConnHdlr	comp_ref,
	CallidString	call_id
}

type component SIP_Emulation_CT {
	/* SIP test port on bottom side */
	port SIPmsg_PT SIP;
	/* SIP port to the per-call clients */
	port SIP_Conn_PT CLIENT;

	var CallData SipCallTable[16];
	var ExpectData SipExpectTable[16];

	/* procedure based port to register for incoming connections */
	port SIPEM_PROC_PT CLIENT_PROC;
};

template RequestLine tr_ReqLine(template Method method) := {
	method := method,
	requestUri := ?,
	sipVersion := ?
}

private template PDU_SIP_Request tr_SIP_REGISTER := {
	requestLine := tr_ReqLine(REGISTER_E),
	msgHeader := t_SIP_msgHeader_any,
	messageBody := *,
	payload := *
}

private template PDU_SIP_Request tr_SIP_INVITE := {
	requestLine := tr_ReqLine(INVITE_E),
	msgHeader := t_SIP_msgHeader_any,
	messageBody := *,
	payload := *
}

template SipUrl tr_SIP_Url(template charstring user_or_num,
			   template charstring host := *,
			   template integer portField := *) := {
	scheme := "sip",
	userInfo := {
		userOrTelephoneSubscriber := user_or_num,
		password := *
	},
	hostPort := {
		host := host,
		portField := portField
	},
	urlParameters := *,
	headers := *
}
template (value) SipUrl ts_SIP_Url(charstring user_or_num,
			   template (omit) charstring host := omit,
			   template (omit) integer portField := omit) := {
	scheme := "sip",
	userInfo := {
		userOrTelephoneSubscriber := user_or_num,
		password := omit
	},
	hostPort := {
		host := host,
		portField := portField
	},
	urlParameters := omit,
	headers := omit
}

template Addr_Union tr_SIP_Addr(template SipUrl sip_url) := {
	nameAddr := {
		displayName := *,
		addrSpec := sip_url
	}
}
template (value) Addr_Union ts_SIP_Addr(template (value) SipUrl sip_url) := {
	nameAddr := {
		displayName := omit,
		addrSpec := sip_url
	}
}

template To tr_SIP_To(template Addr_Union addr) := {
	fieldName := TO_E,
	addressField := addr,
	toParams := *
}
template (value) To ts_SIP_To(template (value) Addr_Union addr) := {
	fieldName := TO_E,
	addressField := addr,
	toParams := omit
}

/* resolve component reference by connection ID */
private function f_call_id_known(CallidString call_id)
runs on SIP_Emulation_CT return boolean {
	var integer i;
	for (i := 0; i < sizeof(SipCallTable); i := i+1) {
		if (SipCallTable[i].call_id == call_id) {
			return true;
		}
	}
	return false;
}

/* resolve component reference by connection ID */
private function f_comp_by_call_id(CallidString call_id)
runs on SIP_Emulation_CT return SIP_ConnHdlr {
	var integer i;
	for (i := 0; i < sizeof(SipCallTable); i := i+1) {
		if (SipCallTable[i].call_id == call_id) {
			return SipCallTable[i].comp_ref;
		}
	}
	setverdict(fail, "SIP Call table not found by SIP Call ID ", call_id);
	mtc.stop;
}

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

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

private function f_call_table_init()
runs on SIP_Emulation_CT {
	for (var integer i := 0; i < sizeof(SipCallTable); i := i+1) {
		SipCallTable[i].comp_ref := null;
		SipCallTable[i].call_id := "";
	}
}

private function f_call_table_add(SIP_ConnHdlr comp_ref, CallidString call_id)
runs on SIP_Emulation_CT {
	for (var integer i := 0; i < sizeof(SipCallTable); i := i+1) {
		if (SipCallTable[i].call_id == "") {
			SipCallTable[i].comp_ref := comp_ref;
			SipCallTable[i].call_id := call_id;
			log("Added SIP Call Table entry [", i, "] for ", call_id, " at ", comp_ref);
			return;
		}
	}
	testcase.stop("SIP Call table full");
}

private function f_call_table_del(CallidString call_id)
runs on SIP_Emulation_CT {
	for (var integer i := 0; i < sizeof(SipCallTable); i := i+1) {
		if (SipCallTable[i].call_id == call_id) {
			SipCallTable[i].comp_ref := null;
			SipCallTable[i].call_id := "";
			log("Deleted SIP Call Table entry [", i, "] for ", call_id);
			return;
		}
	}
	setverdict(fail, "SIP Call table attempt to delete non-existant ", call_id);
	mtc.stop;
}

/* call-back type, to be provided by specific implementation; called when new call connection
 * arrives */
type function SipCreateCallback(PDU_SIP_Request sip_req, charstring id)
runs on SIP_Emulation_CT return SIP_ConnHdlr;

type record SipOps {
	SipCreateCallback create_cb
};

function f_init_sip(inout SIP_Emulation_CT ct, charstring id := "SIP_EMU") {
	var SipOps ops := {
		create_cb := refers(SIP_Emulation.ExpectedCreateCallback)
	};

	ct := SIP_Emulation_CT.create(id) alive;
	map(ct:SIP, system:SIP);
	ct.start(SIP_Emulation.main(ops, id));
}

function main(SipOps ops, charstring id)
runs on SIP_Emulation_CT {

	f_expect_table_init();
	f_call_table_init();

	while (true) {
		var SIP_ConnHdlr vc_hdlr, vc_conn;
		var PDU_SIP_Request sip_req;
		var PDU_SIP_Response sip_resp;
		var SipUrl sip_to;

		alt {
		/* SIP REGISTER was received on SIP socket/port */
		[] SIP.receive(tr_SIP_REGISTER) -> value sip_req {
			var CallidString call_id := sip_req.msgHeader.callId.callid;
			if (f_call_id_known(call_id)) {
				/* re-register? */
				vc_conn := f_comp_by_call_id(call_id);
			} else {
				/* new REGISTER: check expect */
				vc_conn := ops.create_cb.apply(sip_req, id);
				f_call_table_add(vc_conn, call_id);
			}
			CLIENT.send(sip_req) to vc_conn;
			}
		/* SIP INVITE was received on SIP socket/port */
		[] SIP.receive(tr_SIP_INVITE) -> value sip_req {
			var CallidString call_id := sip_req.msgHeader.callId.callid;
			if (f_call_id_known(call_id)) {
				/* re-invite? */
				vc_conn := f_comp_by_call_id(call_id);
			} else {
				/* new INVITE: check expect */
				vc_conn := ops.create_cb.apply(sip_req, id);
				f_call_table_add(vc_conn, call_id);
			}
			CLIENT.send(sip_req) to vc_conn;
			}
		/* other SIP request was received on SIP socket/port */
		[] SIP.receive(PDU_SIP_Request:?) -> value sip_req {
			var CallidString call_id := sip_req.msgHeader.callId.callid;
			if (f_call_id_known(call_id)) {
				vc_conn := f_comp_by_call_id(call_id);
				CLIENT.send(sip_req) to vc_conn;
			} else {
				setverdict(fail, "SIP Request for unknown call ", call_id);
				mtc.stop;
			}
			}
		/* SIP response was received on SIP socket/port */
		[] SIP.receive(PDU_SIP_Response:?) -> value sip_resp {
			var CallidString call_id := sip_resp.msgHeader.callId.callid;
			if (f_call_id_known(call_id)) {
				vc_conn := f_comp_by_call_id(call_id);
				CLIENT.send(sip_resp) to vc_conn;
			} else {
				setverdict(fail, "SIP Response for unknown call ", call_id);
				mtc.stop;
			}
			}

		/* a ConnHdlr is sending us a SIP REGISTER: Forward to SIP port */
		[] CLIENT.receive(tr_SIP_REGISTER) -> value sip_req sender vc_conn {
			var CallidString call_id := sip_req.msgHeader.callId.callid;
			if (f_call_id_known(call_id)) {
				/* re-register */
				vc_conn := f_comp_by_call_id(call_id);
			} else {
				/* new REGISTER: add to table */
				f_call_table_add(vc_conn, call_id);
			}
			SIP.send(sip_req);
			}

		/* a ConnHdlr is sending us a SIP INVITE: Forward to SIP port */
		[] CLIENT.receive(tr_SIP_INVITE) -> value sip_req sender vc_conn {
			var CallidString call_id := sip_req.msgHeader.callId.callid;
			if (f_call_id_known(call_id)) {
				/* re-invite? */
				vc_conn := f_comp_by_call_id(call_id);
			} else {
				/* new INVITE: add to table */
				f_call_table_add(vc_conn, call_id);
			}
			SIP.send(sip_req);
			}
		/* a ConnHdlr is sending us a SIP request: Forward to SIP port */
		[] CLIENT.receive(PDU_SIP_Request:?) -> value sip_req sender vc_conn {
			SIP.send(sip_req);
			}
		/* a ConnHdlr is sending us a SIP request: Forward to SIP port */
		[] CLIENT.receive(PDU_SIP_Response:?) -> value sip_resp sender vc_conn {
			SIP.send(sip_resp);
			}

		[] CLIENT_PROC.getcall(SIPEM_register:{?,?}) -> param(sip_to, vc_hdlr) sender vc_conn {
			f_create_expect(sip_to, vc_hdlr);
			CLIENT_PROC.reply(SIPEM_register:{sip_to, vc_hdlr}) to vc_conn;
			}

		}
	}
}

/***********************************************************************
 * "Expect" Handling (mapping for expected incoming SIP callds from IUT)
 ***********************************************************************/

/* data about an expected future incoming connection */
type record ExpectData {
	/* SIP "To" (destination number) based on which we can match */
	SipUrl sip_to optional,
	/* component reference registered for the connection */
	SIP_ConnHdlr vc_conn
}

/* procedure based port to register for incoming calls */
signature SIPEM_register(SipUrl sip_to, SIP_ConnHdlr vc_conn);

type port SIPEM_PROC_PT procedure {
	inout SIPEM_register;
} with { extension "internal" };


/* CreateCallback that can be used as create_cb and will use the expect table */
function ExpectedCreateCallback(PDU_SIP_Request sip_req, charstring id)
runs on SIP_Emulation_CT return SIP_ConnHdlr {
	var SIP_ConnHdlr ret := null;
	var SipUrl sip_to;
	var integer i;

	if (sip_req.requestLine.method != INVITE_E and
	    sip_req.requestLine.method != REGISTER_E) {
		setverdict(fail, "SIP ExpectedCreateCallback needs REGISTER/INVITE");
		mtc.stop
		return ret;
	}
	sip_to := sip_req.msgHeader.toField.addressField.nameAddr.addrSpec;

	for (i := 0; i < sizeof(SipExpectTable); i := i+1) {
		if (not ispresent(SipExpectTable[i].sip_to)) {
			continue;
		}
		/* build a template, use '*' for all 'omit' values */
		var template SipUrl t_exp := SipExpectTable[i].sip_to;
		if (not ispresent(t_exp.hostPort.host)) {
			t_exp.hostPort.host := *;
		}
		if (not ispresent(t_exp.hostPort.portField)) {
			t_exp.hostPort.portField := *;
		} else if (valueof(t_exp.hostPort.portField) == 5060) {
			/* if the port number is 5060, it may be omitted */
			t_exp.hostPort.portField := 5060 ifpresent;
		}
		if (not ispresent(t_exp.urlParameters)) {
			t_exp.urlParameters := *;
		}
		if (not ispresent(t_exp.headers)) {
			t_exp.headers := *;
		}
		/* match against the constructed template */
		if (match(sip_to, t_exp)) {
			ret := SipExpectTable[i].vc_conn;
			/* release this entry to be used again */
			SipExpectTable[i].sip_to := omit;
			SipExpectTable[i].vc_conn := null;
			log("Found SipExpect[", i, "] for ", sip_to, " handled at ", ret);
			return ret;
		}
	}

	setverdict(fail, "Couldn't find SipExpect for incoming call ", sip_to);
	mtc.stop
	return ret;
}

/* server/emulation side function to create expect */
private function f_create_expect(SipUrl sip_to, SIP_ConnHdlr hdlr)
runs on SIP_Emulation_CT {
	var integer i;
	for (i := 0; i < sizeof(SipExpectTable); i := i+1) {
		if (not ispresent(SipExpectTable[i].sip_to)) {
			SipExpectTable[i].sip_to := sip_to;
			SipExpectTable[i].vc_conn := hdlr;
			log("Created SipExpect[", i, "] for ", sip_to, " to be handled at ", hdlr);
			return;
		}
	}
	testcase.stop("No space left in SipExpectTable");
}

/* client/conn_hdlr side function to use procedure port to create expect in emulation */
function f_create_sip_expect(SipUrl sip_to) runs on SIP_ConnHdlr {
	SIP_PROC.call(SIPEM_register:{sip_to, self}) {
		[] SIP_PROC.getreply(SIPEM_register:{?,?}) {};
	}
}



}
