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 SDP_Templates 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(ts_HostPort(mp_local_host, 5060),
							  ts_UserInfo(cp.called)));
		cp.comp.sip_url_gsm := valueof(ts_SipAddr(ts_HostPort(mp_osmosip_host, 5060),
							  ts_UserInfo(cp.calling)));
		cp.mncc_call_id := f_sip_rand_seq_nr();
	} else {
		cp.comp.sip_url_ext := valueof(ts_SipAddr(ts_HostPort(mp_local_host, 5060),
							  ts_UserInfo(cp.calling)));
		cp.comp.sip_url_gsm := valueof(ts_SipAddr(ts_HostPort(mp_osmosip_host, 5060),
							  ts_UserInfo(cp.called)));
		cp.comp.sip_call_id := hex2str(f_rnd_hexstring(15));
	}
	cp.comp.sip_seq_nr := f_sip_rand_seq_nr();
	cp.comp.sip_body := "";
}

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) alive;
	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_SIP_EMU");
	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) alive;

	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,
			       ts_Via_from(cp.comp.sip_url_ext.addr.nameAddr.addrSpec.hostPort),
			       ts_Contact_SipAddr(cp.comp.sip_url_ext),
			       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,
					   tr_Via_from(f_tr_HostPort_opt_defport(sip_addr_ext.addr.nameAddr.addrSpec.hostPort)),
					   *,
					   "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,
				    ts_Via_from(cp.comp.sip_url_ext.addr.nameAddr.addrSpec.hostPort),
				    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_sdp_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,
					   tr_Via_from(f_tr_HostPort_opt_defport(sip_addr_ext.addr.nameAddr.addrSpec.hostPort)),
					   *,
					   "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,
					   tr_Via_from(f_tr_HostPort_opt_defport(sip_addr_ext.addr.nameAddr.addrSpec.hostPort)),
					   contact := ?,
					   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,
			    ts_Via_from(cp.comp.sip_url_ext.addr.nameAddr.addrSpec.hostPort),
			    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_sdp_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_ext.addr.nameAddr.addrSpec, ?,
						  sip_addr_gsm, sip_addr_ext,
						  tr_Via_from(f_tr_HostPort_opt_defport(sip_addr_gsm.addr.nameAddr.addrSpec.hostPort)),
						  ?, 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,
				 body := 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(sip_addr_ext.addr.nameAddr.addrSpec,
			       cp.comp.sip_call_id,
			       sip_addr_gsm,
			       sip_addr_ext,
			       tr_Via_from(f_tr_HostPort_opt_defport(sip_addr_gsm.addr.nameAddr.addrSpec.hostPort)),
			       ?, 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(sip_addr_ext.addr.nameAddr.addrSpec,
					       cp.comp.sip_call_id, sip_addr_gsm, sip_addr_ext,
					       tr_Via_from(f_tr_HostPort_opt_defport(sip_addr_gsm.addr.nameAddr.addrSpec.hostPort)),
					       ?, *));
	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,
			    ts_Via_from(cp.comp.sip_url_ext.addr.nameAddr.addrSpec.hostPort),
			    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,
					   tr_Via_from(f_tr_HostPort_opt_defport(sip_addr_ext.addr.nameAddr.addrSpec.hostPort)),
					   *,
					   "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_sdp_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_sdp_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_sdp_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_sdp_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_sdp_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_ext.addr.nameAddr.addrSpec, ?,
				     sip_addr_gsm, sip_addr_ext,
				     tr_Via_from(f_tr_HostPort_opt_defport(sip_addr_gsm.addr.nameAddr.addrSpec.hostPort)),
				     ?, ?)) {
		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() );
}



}
