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

private function f_sip_init() runs on SIP_Emulation_CT {
	map(self:SIP, system:SIP);
}

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) {
	id := id & "-SIP";

	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_sip_init();
	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 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) {
		setverdict(fail, "SIP ExpectedCreateCallback needs 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:{?,?}) {};
	}
}



}
