module SIP_Tests {

/* osmo-sip-connector test suite in TTCN-3
 * (C) 2018-2019 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 General_Types all;
import from Osmocom_Types all;
import from Native_Functions all;
import from Misc_Helpers all;

import from Osmocom_CTRL_Functions all;
import from Osmocom_CTRL_Types all;
import from Osmocom_CTRL_Adapter all;

import from TELNETasp_PortType all;
import from Osmocom_VTY_Functions all;

import from MNCC_Emulation all;
import from MNCC_Types all;

import from SDP_Types all;

import from SIP_Emulation all;
import from SIPmsg_Types all;
import from SIP_Templates all;

modulepar {
	charstring mp_local_host := "127.0.0.2";
	charstring mp_osmosip_host := "127.0.0.1";
	integer mp_osmosip_port_ctrl := -1; /* RFU */
	charstring mp_mncc := "/tmp/mncc";
}

type component test_CT extends CTRL_Adapter_CT {
	var MNCC_Emulation_CT vc_MNCC;
	var SIP_Emulation_CT vc_SIP;

	port TELNETasp_PT SIPVTY;
}

type component ConnHdlr extends SIP_ConnHdlr, MNCC_ConnHdlr {
	var ConnHdlrPars g_pars;
	timer g_Tguard;
}

type record ConnHdlrPars {
	float t_guard,
	CallPars g_cp optional
}

type record CallPars {
	boolean is_mo,
	charstring calling,
	charstring called,

	uint32_t mncc_call_id optional,
	CallParsComputed comp optional,

	charstring sip_rtp_addr,
	uint16_t sip_rtp_port,
	charstring cn_rtp_addr,
	uint16_t cn_rtp_port,

	/* Send SDP to MNCC, and expect to receive SDP from MNCC. mncc_with_sdp := false tests legacy compatibility to
	 * the time when we did not include SDP in MNCC messages. mncc_with_sdp := true expects SDP to pass through the
	 * SUT osmo-sip-connector unchanged. */
	boolean mncc_with_sdp
}

type record CallParsComputed {
	CallidString sip_call_id,
	SipAddr sip_url_ext,
	SipAddr sip_url_gsm,
	charstring sip_body,
	integer sip_seq_nr
}

private template (value) CallPars t_CallPars(boolean is_mo, boolean mncc_with_sdp := true) := {
	is_mo := is_mo,
	calling := "12345",
	called := "98766",

	mncc_call_id := omit,
	comp := omit,
	sip_rtp_addr := "1.2.3.4",
	sip_rtp_port := 1234,
	cn_rtp_addr := "5.6.7.8",
	cn_rtp_port := 5678,
	mncc_with_sdp := mncc_with_sdp
}

private function f_CallPars_compute(inout CallPars cp) {
	if (cp.is_mo) {
		cp.comp.sip_url_ext := valueof(ts_SipAddr(cp.called, mp_local_host, 5060));
		cp.comp.sip_url_gsm := valueof(ts_SipAddr(cp.calling, mp_osmosip_host, 5060));
		cp.mncc_call_id := f_rnd_int(429496725);
	} else {
		cp.comp.sip_url_ext := valueof(ts_SipAddr(cp.calling, mp_local_host, 5060));
		cp.comp.sip_url_gsm := valueof(ts_SipAddr(cp.called, mp_osmosip_host, 5060));
		cp.comp.sip_call_id := hex2str(f_rnd_hexstring(15));
	}
	cp.comp.sip_seq_nr := f_rnd_int(4294967295);
	cp.comp.sip_body := "";
}

private function f_mgcp_addr2addrtype(charstring addr) return charstring {
	for (var integer i := 0; i < lengthof(addr); i := i + 1) {
		if (addr[i] == ":") {
			return "IP6";
		}
	}
	return "IP4";
}

private function f_addrstr2addr(charstring addr) return octetstring {
	if (f_addr_is_ipv6(addr)) {
		return f_inet6_addr(addr);
	} else {
		return f_inet_addr(addr);
	}
}

function f_init_mncc(charstring id) runs on test_CT {
	id := id & "-MNCC";
	var MnccOps ops := {
		create_cb := refers(MNCC_Emulation.ExpectedCreateCallback),
		unitdata_cb := refers(MNCC_Emulation.DummyUnitdataCallback)
	};

	vc_MNCC := MNCC_Emulation_CT.create(id);
	map(vc_MNCC:MNCC, system:MNCC_CODEC_PT);
	vc_MNCC.start(MNCC_Emulation.main(ops, id, mp_mncc, true));
}

function f_init() runs on test_CT {
	//f_ipa_ctrl_start_client(mp_osmosip_host, mp_osmosip_port_ctrl);
	f_init_mncc("SIP_Test");
	log("end of f_init_mncc");
	f_init_sip(vc_SIP, "SIP_Test");
	log("end of f_init_sip");

	map(self:SIPVTY, system:SIPVTY);
	f_vty_set_prompts(SIPVTY);
	f_vty_transceive(SIPVTY, "enable");
	log("end of f_init");
}

type function void_fn(charstring id) runs on ConnHdlr;

function f_start_handler(void_fn fn, ConnHdlrPars pars)
runs on test_CT return ConnHdlr {
	var ConnHdlr vc_conn;
	var charstring id := testcasename();

	vc_conn := ConnHdlr.create(id);

	connect(vc_conn:SIP, vc_SIP:CLIENT);
	connect(vc_conn:SIP_PROC, vc_SIP:CLIENT_PROC);

	connect(vc_conn:MNCC, vc_MNCC:MNCC_CLIENT);
	connect(vc_conn:MNCC_PROC, vc_MNCC:MNCC_PROC);

	vc_conn.start(f_handler_init(fn, id, pars));
	return vc_conn;
}

private altstep as_Tguard() runs on ConnHdlr {
	[] g_Tguard.timeout {
		setverdict(fail, "Tguard timeout");
		mtc.stop;
	}
}

private function f_handler_init(void_fn fn, charstring id, ConnHdlrPars pars)
runs on ConnHdlr {
	g_pars := pars;
	g_Tguard.start(pars.t_guard);
	activate(as_Tguard());

	/* call the user-supied test case function */
	fn.apply(id);
}


template (value) ConnHdlrPars t_Pars := {
	t_guard := 30.0,
	g_cp := omit
}

altstep as_SIP_expect_resp(template PDU_SIP_Response sip_expect) runs on ConnHdlr
{
	[] SIP.receive(sip_expect);
	[] SIP.receive {
		log("FAIL: expected SIP message ", sip_expect);
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received unexpected SIP message");
	}
}

function f_SIP_expect_req(template PDU_SIP_Request sip_expect) runs on ConnHdlr return PDU_SIP_Request
{
	var PDU_SIP_Request rx;
	alt {
		[] SIP.receive(sip_expect) -> value rx;
		[] SIP.receive {
			log("FAIL: expected SIP message ", sip_expect);
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received unexpected SIP message");
		}
	}
	return rx;
}

/* Update 'last_sdp', and match with expectation of what the current SDP should be.
 * Useful to ensure that MNCC or SIP send and possibly resend only the expected SDP.
 * last_sdp keeps the last non-empty rx_sdp, across multiple check_sdp() invocations.
 * rx_sdp is the SDP charstring just received. If it is nonempty, update last_sdp to rx_sdp.
 * After updating last_sdp as appropriate, match last_sdp with expect_sdp. */
private function check_sdp(inout charstring last_sdp,
			   charstring rx_sdp,
			   template charstring expect_sdp)
{
	/* If there is new SDP, store it. */
	if (lengthof(rx_sdp) > 0) {
		if (last_sdp != rx_sdp) {
			log("SDP update from ", last_sdp, " to ", rx_sdp);
		}

		/* If MNCC sent SDP data, remember it as the last valid SDP */
		last_sdp := rx_sdp;
	}
	/* Validate expectations of the SDP data */
	if (not match(last_sdp, expect_sdp)) {
		log("FAIL: expected SDP ", expect_sdp, " but got ", last_sdp);
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "unexpected SDP");
	}
}

/* Establish a mobile terminated call described in 'cp' */
function f_establish_mt(inout CallPars cp) runs on ConnHdlr {
	var template SipAddr sip_addr_gsm := tr_SipAddr_from_val(cp.comp.sip_url_gsm);
	var template SipAddr sip_addr_ext := tr_SipAddr_from_val(cp.comp.sip_url_ext);
	var MNCC_PDU mncc;

	/* The last SDP that the MSC received via MNCC from osmo-sip-connector */
	var charstring sdp_to_msc := "";
	/* At first, allow any empty and nonempty SDP. As the test progresses, this may expect specific SDP instead. */
	var template charstring expect_sdp_to_msc := *;

	/* If cp.mncc_with_sdp == true, expect SDP forwarding like this:
	 *
	 *  SDP1: SIP agent's RTP and codec info
	 *  SDP2: osmo-msc's RTP and codec info
	 *
	 *            MNCC   osmo-sip-connector   SIP
	 *                         |<--SDP1-----           SIP Invite
	 *                         |----------->           SIP (Invite) Trying
	 *           <--SDP1-------|                       MNCC SETUP req
	 *           ------------->|                       MNCC CALL CONF ind
	 *           <-------------|                       MNCC RTP CREATE (SDP optional, still unchanged from SDP1)
	 *           -------SDP2-->|                       MNCC RTP CREATE
	 *           ------------->|                       MNCC ALERT ind
	 *                         |-------------->        SIP (Invite) Ringing
	 *  (MT picks up)          |
	 *           ------------->|                       MNCC SETUP CNF
	 *           <-------------|                       MNCC RTP CONNECT (SDP optional, still unchanged from SDP1)
	 *                         |--------SDP2-->        SIP (Invite) OK
	 *                         |<--------------        SIP ACK
	 *           <-------------|                       MNCC SETUP COMPL (SDP optional, still unchanged from SDP1)
	 */

	/* Ask MNCC_Emulation to "expect" a call to the given called number */
	f_create_mncc_expect(cp.called);

	/* OSC <- SIP: A party sends SIP invite for a MT-call into OSC */
	SIP.send(ts_SIP_INVITE(cp.comp.sip_call_id, cp.comp.sip_url_ext, cp.comp.sip_url_gsm,
				cp.comp.sip_seq_nr, cp.comp.sip_body));
	if (cp.mncc_with_sdp) {
		/* We just sent SDP via SIP, now expect the same SDP in MNCC to the MSC */
		expect_sdp_to_msc := cp.comp.sip_body;
	}

	/* OSC -> SIP */
	as_SIP_expect_resp(tr_SIP_Response(cp.comp.sip_call_id, sip_addr_ext, sip_addr_gsm, *,
					   "INVITE", 100, ?, "Trying", *));

	alt {
	/* MSC <- OSC: OSC generates MNCC_SETUP_REQ from INVITE */
	[] MNCC.receive(tr_MNCC_SETUP_req) -> value mncc {
			cp.mncc_call_id := mncc.u.signal.callref;
			/* Expect the SDP sent via SIP to arrive in MNCC */
			check_sdp(sdp_to_msc, mncc.u.signal.sdp, expect_sdp_to_msc);
		}
	[] SIP.receive {
		setverdict(fail, "Received unexpected SIP response");
		SIP.send(ts_SIP_ACK(cp.comp.sip_call_id, cp.comp.sip_url_ext, cp.comp.sip_url_gsm,
				    cp.comp.sip_seq_nr, omit));
		mtc.stop;
		}
	}

	/* MSC -> OSC: After MS sends CALL CONF in response to SETUP */
	MNCC.send(ts_MNCC_CALL_CONF_ind(cp.mncc_call_id));
	/* MSC <- OSC: OSC asks MSC to create RTP socket */
	MNCC.receive(tr_MNCC_RTP_CREATE(cp.mncc_call_id)) -> value mncc {
		check_sdp(sdp_to_msc, mncc.u.rtp.sdp, expect_sdp_to_msc);
	}

	/* MSC -> OSC: SDP that the MSC will send via MNCC */
	var charstring cn_sdp := "v=0\r\no=Osmocom 0 0 IN IP4 1.1.1.1\r\ns=GSM Call\r\nc=IN " &
		f_mgcp_addr2addrtype(cp.cn_rtp_addr) & " " & cp.cn_rtp_addr &
		"\r\nt=0 0\r\nm=audio " & int2str(cp.cn_rtp_port) &
		" RTP/AVP 0\r\na=rtpmap:0 GSM/8000\r\n";
	/* OSC -> SIP: what SDP to expect in SIP from osmo-sip-connector */
	var template charstring expect_sdp_to_sip := pattern "*" & cp.cn_rtp_addr & "*";

	mncc := valueof(ts_MNCC_RTP_CREATE(cp.mncc_call_id));
	mncc.u.rtp.is_ipv6 := f_addr_is_ipv6(cp.cn_rtp_addr);
	mncc.u.rtp.ip := f_addrstr2addr(cp.cn_rtp_addr);
	mncc.u.rtp.rtp_port := cp.cn_rtp_port;
	if (cp.mncc_with_sdp) {
		/* MSC -> OSC: tell OSC our RTP info in SDP form */
		mncc.u.rtp.sdp := cn_sdp;
		/* OSC -> SIP: and expect it unchanged on SIP later, but allow osmo-sip-connector to append an
		 * "a=sendrecv;" */
		expect_sdp_to_sip := pattern cn_sdp & "*";
	}
	MNCC.send(mncc);

	/* MSC -> OSC: After MS is ringing and sent CC ALERTING */
	MNCC.send(ts_MNCC_ALERT_ind(cp.mncc_call_id));

	/* Now expect SIP response "Ringing" back to MO, containing the same SDP information as in the MNCC RTP CREATE
	 * sent to OSC above */
	SIP.clear;

	/* 180 Ringing should not contain any SDP. */
	as_SIP_expect_resp(tr_SIP_Response(cp.comp.sip_call_id, sip_addr_ext, sip_addr_gsm, *,
					   "INVITE", 180, ?, "Ringing", omit));

	/* MSC -> OSC: After MT user has picked up and sent CC CONNECT */
	MNCC.send(ts_MNCC_SETUP_CNF(cp.mncc_call_id));

	SIP.clear;
	/* MSC <- OSC: OSC asks MSC to connect its RTP stream to remote end */
	MNCC.receive(tr_MNCC_RTP_CONNECT(cp.mncc_call_id, f_addrstr2addr(cp.sip_rtp_addr), cp.sip_rtp_port))
		-> value mncc {
		check_sdp(sdp_to_msc, mncc.u.rtp.sdp, expect_sdp_to_msc);
	}

	/* OSC -> SIP: OSC confirms call establishment to SIP side */
	as_SIP_expect_resp(tr_SIP_Response(cp.comp.sip_call_id, sip_addr_ext, sip_addr_gsm, contact_addr := ?,
					   method := "INVITE", status_code := 200,
					   seq_nr := ?, reason := "OK",
					   body := expect_sdp_to_sip));

	/* OSC <- SIP: SIP world acknowledges "200 OK" */
	SIP.send(ts_SIP_ACK(cp.comp.sip_call_id, cp.comp.sip_url_ext, cp.comp.sip_url_gsm,
			    cp.comp.sip_seq_nr, omit));
	/* MSC <- OSC: OSC sends SETUP COMPL to MNCC (which triggers CC CONNECT ACK */
	MNCC.receive(tr_MNCC_SETUP_COMPL_req(cp.mncc_call_id)) -> value mncc {
		check_sdp(sdp_to_msc, mncc.u.signal.sdp, expect_sdp_to_msc);
	}
}

/* Establish a mobile originated call described in 'cp' */
function f_establish_mo(inout CallPars cp) runs on ConnHdlr {
	var MNCC_number dst := valueof(ts_MNCC_number(cp.called, GSM48_TON_UNKNOWN));
	var MNCC_number src := valueof(ts_MNCC_number(cp.calling, GSM48_TON_UNKNOWN));
	var template SipAddr sip_addr_gsm := tr_SipAddr_from_val(cp.comp.sip_url_gsm);
	var template SipAddr sip_addr_ext := tr_SipAddr_from_val(cp.comp.sip_url_ext);
	var PDU_SIP_Request sip_req;
	var integer seq_nr;
	var MNCC_PDU mncc;

	/* The last SDP that the MSC received via MNCC from osmo-sip-connector */
	var charstring sdp_to_msc := "";
	/* At first, allow any empty and nonempty SDP. As the test progresses, this may expect specific SDP instead. */
	var template charstring expect_sdp_to_msc := *;

	/* If cp.mncc_with_sdp == true, expect SDP forwarding like this:
	 *
	 *  SDP1: osmo-msc's RTP and codec info
	 *  SDP2: SIP agent's RTP and codec info
	 *
	 *            MNCC   osmo-sip-connector   SIP
	 *           -------SDP1-->|                       MNCC SETUP ind
	 *           <-------------|                       MNCC RTP CREATE (?)
	 *                         |-----SDP1-->           SIP Invite
	 *                         |<-----------           SIP (Invite) Trying
	 *           <-------------|                       MNCC CALL PROC req
	 *                         |<-----------           SIP (Invite) Ringing
	 *           <-------------|                       MNCC ALERT req
	 *                         |        (MT picks up)
	 *                         |<--SDP2-----           SIP (Invite) OK
	 *           <--SDP2-------|                       MNCC RTP CONNECT (SDP optional, still unchanged from SDP2)
	 *           <-------------|                       MNCC SETUP rsp (SDP optional, still unchanged from SDP2)
	 *           ------------->|                       MNCC SETUP COMPL ind (SDP optional, still unchanged from SDP1)
	 *                         |------------>          SIP ACK
	 */

	var charstring cn_sdp := "v=0\r\no=Osmocom 0 0 IN IP4 1.1.1.1\r\ns=GSM Call\r\nc=IN " &
		f_mgcp_addr2addrtype(cp.cn_rtp_addr) & " " & cp.cn_rtp_addr &
		"\r\nt=0 0\r\nm=audio " & int2str(cp.cn_rtp_port) &
		" RTP/AVP 0\r\na=rtpmap:0 GSM/8000\r\n";

	f_create_sip_expect(cp.comp.sip_url_ext.addr.nameAddr.addrSpec);

	/* MSC -> OSC: MSC sends SETUP.ind after CC SETUP was received from MS */
	mncc := valueof(ts_MNCC_SETUP_ind(cp.mncc_call_id, dst, src, "262420123456789"));
	if (cp.mncc_with_sdp) {
		mncc.u.signal.sdp := cn_sdp;
	}
	MNCC.send(mncc);

	/* MSC <- OSC: Create GSM side RTP socket */
	MNCC.receive(tr_MNCC_RTP_CREATE(cp.mncc_call_id)) {
		mncc := valueof(ts_MNCC_RTP_CREATE(cp.mncc_call_id));
		mncc.u.rtp.payload_msg_type := oct2int('0300'O);
		/* FIXME: makes no sense to send cp.cn_rtp_addr back to the cn. */
		mncc.u.rtp.is_ipv6 := f_addr_is_ipv6(cp.cn_rtp_addr);
		mncc.u.rtp.ip := f_addrstr2addr(cp.cn_rtp_addr);
		mncc.u.rtp.rtp_port := cp.cn_rtp_port;
		MNCC.send(mncc);
		}

	/* OSC -> SIP: Send INVITE with GSM side IP/Port in SDP */
	var template charstring expect_sdp_to_sip := ?;
	if (cp.mncc_with_sdp) {
		/* Expect the same SDP as sent to osmo-sip-connector in MNCC, and allow osmo-sip-connector to append an
		 * "a=sendrecv;" */
		expect_sdp_to_sip := pattern cn_sdp & "*";
	}
	sip_req := f_SIP_expect_req(tr_SIP_INVITE(?, sip_addr_gsm, sip_addr_ext, ?, expect_sdp_to_sip));
	cp.comp.sip_url_gsm.params := sip_req.msgHeader.fromField.fromParams;
	cp.comp.sip_call_id := sip_req.msgHeader.callId.callid;
	seq_nr := sip_req.msgHeader.cSeq.seqNumber;

	/* OSC <- SIP: Notify call is proceeding */
	SIP.send(ts_SIP_Response(cp.comp.sip_call_id, cp.comp.sip_url_gsm, cp.comp.sip_url_ext,
				 "INVITE", 100, seq_nr, "Trying", sip_req.msgHeader.via));
	/* MSC <- OSC: "100 Trying" translated to MNCC_CALL_PROC_REQ */
	MNCC.receive(tr_MNCC_CALL_PROC_req(cp.mncc_call_id)) -> value mncc {
		check_sdp(sdp_to_msc, mncc.u.signal.sdp, "");
	}

	/* OSC <- SIP: SIP-terminated user is ringing now. 180 Ringing should not contain any SDP. */
	SIP.send(ts_SIP_Response(cp.comp.sip_call_id, cp.comp.sip_url_gsm, cp.comp.sip_url_ext,
				 "INVITE", 180, seq_nr, "Ringing", sip_req.msgHeader.via, omit));

	/* MSC <- OSC: "180 Ringing" translated to MNCC_ALERT_REQ */
	MNCC.receive(tr_MNCC_ALERT_req(cp.mncc_call_id)) -> value mncc {
		check_sdp(sdp_to_msc, mncc.u.signal.sdp, expect_sdp_to_msc);
	}

	/* OSC <- SIP: SIP-terminated user has accepted the call */
	SIP.send(ts_SIP_Response(cp.comp.sip_call_id, cp.comp.sip_url_gsm, cp.comp.sip_url_ext,
				 "INVITE", 200, seq_nr, "OK", sip_req.msgHeader.via,
				 cp.comp.sip_body));

	if (cp.mncc_with_sdp) {
		/* If we expect SDP forwarding, from now on expect MNCC to reflect the SDP that we just sent on SIP. */
		expect_sdp_to_msc := cp.comp.sip_body;
	}
	/* If we don't expect SDP forwarding, just keep expect_sdp_to_msc := *. */

	MNCC.receive(tr_MNCC_RTP_CONNECT(cp.mncc_call_id)) -> value mncc {
		check_sdp(sdp_to_msc, mncc.u.rtp.sdp, expect_sdp_to_msc);
	}
	/* MSC <- OSC: "200 OK" translated to MNCC_SETUP_RSP */
	MNCC.receive(tr_MNCC_SETUP_rsp(cp.mncc_call_id)) -> value mncc {
		check_sdp(sdp_to_msc, mncc.u.signal.sdp, expect_sdp_to_msc);
	}

	/* MSC -> OSC: CC CONNECT ACK was received from MS */
	MNCC.send(ts_MNCC_SETUP_COMPL_ind(cp.mncc_call_id));
	/* OSC -> SIP: Acknowledge the call */
	SIP.receive(tr_SIP_ACK(cp.comp.sip_call_id, sip_addr_gsm, sip_addr_ext, ?, omit));
}

/* Release call from the mobile side */
function f_release_mobile(inout CallPars cp) runs on ConnHdlr {
	var template SipAddr sip_addr_gsm := tr_SipAddr_from_val(cp.comp.sip_url_gsm);
	var template SipAddr sip_addr_ext := tr_SipAddr_from_val(cp.comp.sip_url_ext);
	var PDU_SIP_Request sip_req;
	SIP.clear;
	/* MSC -> OSC: Simulate a CC DISCONNET from the MT user */
	MNCC.send(ts_MNCC_DISC_ind(cp.mncc_call_id, ts_MNCC_cause(0)));

	/* OSC -> SIP: Expect BYE from OSC to SIP side */
	sip_req := f_SIP_expect_req(tr_SIP_BYE(cp.comp.sip_call_id, sip_addr_gsm, sip_addr_ext, ?, *));
	cp.comp.sip_url_gsm.params := sip_req.msgHeader.fromField.fromParams;

	/* OSC <- SIP: Acknowledge the BYE */
	SIP.send(ts_SIP_Response(cp.comp.sip_call_id, cp.comp.sip_url_gsm, cp.comp.sip_url_ext,
					 "BYE", 200, sip_req.msgHeader.cSeq.seqNumber, "OK",
					 sip_req.msgHeader.via));
	/* MSC <- OSC: Send REL_REQ to MSC, triggers CC RELEASE REQ to MS */
	MNCC.receive(tr_MNCC_REL_req(cp.mncc_call_id)); // CAUSE?
	/* MSC -> OSC: MS has responded with CC CLEAR COMPL, triggers MNCC_REL_CNF */
	MNCC.send(ts_MNCC_REL_cnf(cp.mncc_call_id, ts_MNCC_cause(0)));
}

/* Release call from the SIP side */
function f_release_sip(inout CallPars cp) runs on ConnHdlr {
	var template SipAddr sip_addr_gsm := tr_SipAddr_from_val(cp.comp.sip_url_gsm);
	var template SipAddr sip_addr_ext := tr_SipAddr_from_val(cp.comp.sip_url_ext);
	/* OSC <- SIP: SIP-side sends a BYE to OSC */
	SIP.send(ts_SIP_BYE(cp.comp.sip_call_id, cp.comp.sip_url_ext, cp.comp.sip_url_gsm,
			    cp.comp.sip_seq_nr, omit));
	/* MSC <- OSC: Expect OSC to cause MNCC Disconnect Request */
	MNCC.receive(tr_MNCC_DISC_req(cp.mncc_call_id));
	/* MSC -> OSC: Indicate GSM side release */
	MNCC.send(ts_MNCC_REL_ind(cp.mncc_call_id, ts_MNCC_cause(0)));
	/* OSC -> SIP: Confirmation to SIP side */
	as_SIP_expect_resp(tr_SIP_Response(cp.comp.sip_call_id, sip_addr_ext, sip_addr_gsm, *,
					   "BYE", 200, cp.comp.sip_seq_nr, "OK", omit));
}

/* Successful MT Call, which is subsequently released by GSM side */
private function f_TC_mt_success_rel_gsm(charstring id) runs on ConnHdlr {
	var CallPars cp := g_pars.g_cp;
	f_CallPars_compute(cp);
	cp.comp.sip_body := "v=0\r\no=Osmocom 0 0 IN IP4 1.1.1.1\r\ns=GSM Call\r\nc=IN " &
			    f_mgcp_addr2addrtype(cp.sip_rtp_addr) & " " & cp.sip_rtp_addr &
			    "\r\nt=0 0\r\nm=audio " & int2str(cp.sip_rtp_port) &
			    " RTP/AVP 0\r\na=rtpmap:0 GSM/8000\r\n";
	f_sleep(3.0)

	f_establish_mt(cp);
	/* now call is fully established */
	f_sleep(2.0);
	f_release_mobile(cp);
	setverdict(pass);
}
testcase TC_mt_success_rel_gsm() runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;
	f_init();
	pars := valueof(t_Pars);
	pars.g_cp := valueof(t_CallPars(false, false));
	vc_conn := f_start_handler(refers(f_TC_mt_success_rel_gsm), pars);
	vc_conn.done;
}
testcase TC_mt_success_rel_gsm_ipv6() runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;
	f_init();
	pars := valueof(t_Pars);
	pars.g_cp := valueof(t_CallPars(false, false));
	pars.g_cp.sip_rtp_addr := "::1";
	pars.g_cp.cn_rtp_addr := "::2";
	vc_conn := f_start_handler(refers(f_TC_mt_success_rel_gsm), pars);
	vc_conn.done;
}

/* Successful MT Call, which is subsequently released by SIP side */
private function f_TC_mt_success_rel_sip(charstring id) runs on ConnHdlr {
	var CallPars cp := g_pars.g_cp;
	f_CallPars_compute(cp);
	cp.comp.sip_body := "v=0\r\no=Osmocom 0 0 IN IP4 1.1.1.1\r\ns=GSM Call\r\nc=IN " &
			    f_mgcp_addr2addrtype(cp.sip_rtp_addr) & " " & cp.sip_rtp_addr &
			    "\r\nt=0 0\r\nm=audio " & int2str(cp.sip_rtp_port) &
			    " RTP/AVP 0\r\na=rtpmap:0 GSM/8000\r\n";
	f_sleep(3.0)

	f_establish_mt(cp);
	/* now call is fully established */
	f_sleep(2.0);
	f_release_sip(cp);
	setverdict(pass);
}
testcase TC_mt_success_rel_sip() runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;
	f_init();
	pars := valueof(t_Pars);
	pars.g_cp := valueof(t_CallPars(false, false));
	vc_conn := f_start_handler(refers(f_TC_mt_success_rel_sip), pars);
	vc_conn.done;
}


/* Successful MO Call, which is subsequently released by GSM side */
private function f_TC_mo_success_rel_gsm(charstring id) runs on ConnHdlr {
	var CallPars cp := g_pars.g_cp;
	f_CallPars_compute(cp);
	cp.comp.sip_body := "v=0\r\no=Osmocom 0 0 IN IP4 1.1.1.1\r\ns=GSM Call\r\nc=IN " &
			    f_mgcp_addr2addrtype(cp.sip_rtp_addr) & " " & cp.sip_rtp_addr &
			    "\r\nt=0 0\r\nm=audio " & int2str(cp.sip_rtp_port) &
			    " RTP/AVP 0\r\na=rtpmap:0 GSM/8000\r\n";
	f_sleep(3.0)

	f_establish_mo(cp);
	/* now call is fully established */
	f_sleep(2.0);
	f_release_mobile(cp);
	setverdict(pass);
}
testcase TC_mo_success_rel_gsm() runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;
	f_init();
	pars := valueof(t_Pars);
	pars.g_cp := valueof(t_CallPars(true, false));
	vc_conn := f_start_handler(refers(f_TC_mo_success_rel_gsm), pars);
	vc_conn.done;
}
testcase TC_mo_success_rel_gsm_ipv6() runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;
	f_init();
	pars := valueof(t_Pars);
	pars.g_cp := valueof(t_CallPars(true, false));
	pars.g_cp.sip_rtp_addr := "::1";
	pars.g_cp.cn_rtp_addr := "::2";
	vc_conn := f_start_handler(refers(f_TC_mo_success_rel_gsm), pars);
	vc_conn.done;
}

/* Successful MO Call, which is subsequently released by SIP side */
private function f_TC_mo_success_rel_sip(charstring id) runs on ConnHdlr {
	var CallPars cp := g_pars.g_cp;
	f_CallPars_compute(cp);
	cp.comp.sip_body := "v=0\r\no=Osmocom 0 0 IN IP4 1.1.1.1\r\ns=GSM Call\r\nc=IN " &
			    f_mgcp_addr2addrtype(cp.sip_rtp_addr) & " " & cp.sip_rtp_addr &
			    "\r\nt=0 0\r\nm=audio " & int2str(cp.sip_rtp_port) &
			    " RTP/AVP 0\r\na=rtpmap:0 GSM/8000\r\n";
	f_sleep(3.0)

	f_establish_mo(cp);
	/* now call is fully established */
	f_sleep(2.0);
	f_release_sip(cp);
	setverdict(pass);
}
testcase TC_mo_success_rel_sip() runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;
	f_init();
	pars := valueof(t_Pars);
	pars.g_cp := valueof(t_CallPars(is_mo := true, mncc_with_sdp := false));
	vc_conn := f_start_handler(refers(f_TC_mo_success_rel_sip), pars);
	vc_conn.done;
}

/* SETUP followed by DISC results in lingering B-leg (OS#3518)*/
private function f_TC_mo_setup_disc_late_rtp(charstring id) runs on ConnHdlr {
	var CallPars cp := g_pars.g_cp;
	f_CallPars_compute(cp);
	cp.comp.sip_body := "v=0\r\no=Osmocom 0 0 IN IP4 1.1.1.1\r\ns=GSM Call\r\nc=IN " &
			    f_mgcp_addr2addrtype(cp.sip_rtp_addr) & " " & cp.sip_rtp_addr &
			    "\r\nt=0 0\r\nm=audio " & int2str(cp.sip_rtp_port) &
			    " RTP/AVP 0\r\na=rtpmap:0 GSM/8000\r\n";
	f_sleep(3.0);

	var MNCC_number dst := valueof(ts_MNCC_number(cp.called, GSM48_TON_UNKNOWN));
	var MNCC_number src := valueof(ts_MNCC_number(cp.calling, GSM48_TON_UNKNOWN));
	var template SipAddr sip_addr_gsm := tr_SipAddr_from_val(cp.comp.sip_url_gsm);
	var template SipAddr sip_addr_ext := tr_SipAddr_from_val(cp.comp.sip_url_ext);

	f_create_sip_expect(cp.comp.sip_url_ext.addr.nameAddr.addrSpec);

	/* MSC -> OSC: MSC sends SETUP.ind after CC SETUP was received from MS */
	MNCC.send(ts_MNCC_SETUP_ind(cp.mncc_call_id, dst, src, "262420123456789"));

	/* MSC -> OSC: Simulate a CC DISCONNET from the MT user *before* responding to the RTP_CREATE */
	MNCC.send(ts_MNCC_DISC_ind(cp.mncc_call_id, ts_MNCC_cause(0)));

	/* MSC <- OSC: Create GSM side RTP socket (too late) */
	MNCC.receive(tr_MNCC_RTP_CREATE(cp.mncc_call_id)) {
		var MNCC_PDU mncc := valueof(ts_MNCC_RTP_CREATE(cp.mncc_call_id));
		mncc.u.rtp.payload_msg_type := oct2int('0300'O);
		mncc.u.rtp.is_ipv6 := f_addr_is_ipv6(cp.cn_rtp_addr);
		mncc.u.rtp.ip := f_addrstr2addr(cp.cn_rtp_addr);
		mncc.u.rtp.rtp_port := cp.cn_rtp_port;
		MNCC.send(mncc);
		}

	/* OSC -> SIP: We should never receive INVITE */
	timer T := 10.0;
	T.start;
	alt {
	[] SIP.receive(tr_SIP_INVITE(?, sip_addr_gsm, sip_addr_ext, ?, ?)) {
		setverdict(fail, "Received unexpected INVITE");
		}
	[] T.timeout {
		setverdict(pass);
		}
	}
}
testcase TC_mo_setup_disc_late_rtp() runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;
	f_init();
	pars := valueof(t_Pars);
	pars.g_cp := valueof(t_CallPars(is_mo := true, mncc_with_sdp := false));
	vc_conn := f_start_handler(refers(f_TC_mo_setup_disc_late_rtp), pars);
	vc_conn.done;
}

testcase TC_mt_with_sdp() runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;
	f_init();
	pars := valueof(t_Pars);
	pars.g_cp := valueof(t_CallPars(is_mo := false, mncc_with_sdp := true));
	vc_conn := f_start_handler(refers(f_TC_mt_success_rel_gsm), pars);
	vc_conn.done;
}

testcase TC_mo_with_sdp() runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;
	f_init();
	pars := valueof(t_Pars);
	pars.g_cp := valueof(t_CallPars(is_mo := true, mncc_with_sdp := true));
	vc_conn := f_start_handler(refers(f_TC_mo_success_rel_sip), pars);
	vc_conn.done;
}

control {
	execute( TC_mt_success_rel_gsm() );
	execute( TC_mt_success_rel_gsm_ipv6() );
	execute( TC_mt_success_rel_sip() );
	execute( TC_mo_success_rel_gsm() );
	execute( TC_mo_success_rel_gsm_ipv6() );
	execute( TC_mo_success_rel_sip() );
	execute( TC_mo_setup_disc_late_rtp() );
	execute( TC_mt_with_sdp() );
	execute( TC_mo_with_sdp() );
}



}
