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");
	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,
				 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() );
}



}
