module Asterisk_Tests {

/* Asterisk test suite in TTCN-3
 * (C) 2024 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
 * All rights reserved.
 * Author: Pau Espin Pedrol <pespin@sysmocom.de>
 *
 * 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 TCCOpenSecurity_Functions all;
import from General_Types all;
import from Osmocom_Types all;
import from Native_Functions all;
import from Misc_Helpers 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_sip_host := "127.0.0.2";
	integer mp_local_sip_port := 5060;
	charstring mp_remote_sip_host := "127.0.0.1";
	integer mp_remote_sip_port := 5060;
}

type port Coord_PT message
{
	inout charstring;
} with { extension "internal" };
private const charstring COORD_CMD_REGISTERED := "COORD_CMD_REGISTERED";
private const charstring COORD_CMD_START := "COORD_CMD_START";
private const charstring COORD_CMD_PICKUP := "COORD_CMD_PICKUP";
private const charstring COORD_CMD_CALL_ESTABLISHED := "COORD_CMD_CALL_ESTABLISHED";
private const charstring COORD_CMD_CALL_CANCELLED := "COORD_CMD_CALL_CANCELLED";
private const charstring COORD_CMD_HANGUP := "COORD_CMD_HANGUP";

type component test_CT {
	var SIP_Emulation_CT vc_SIP;
	port Coord_PT COORD;
}

type component ConnHdlr extends SIP_ConnHdlr {
	var charstring g_name;
	var ConnHdlrPars g_pars;
	timer g_Tguard;
	var PDU_SIP_Request g_rx_sip_req;
	var PDU_SIP_Response g_rx_sip_resp;

	port Coord_PT COORD;
}
type record of ConnHdlr ConnHdlrList;

const charstring broadcast_sip_extension := "0500";

type record ConnHdlrPars {
	float t_guard,
	charstring user,
	charstring display_name,
	charstring password,
	SipUrl registrar_sip_req_uri,
	SipAddr registrar_sip_record,
	CallidString registrar_sip_call_id,
	integer registrar_sip_seq_nr,
	Via local_via,
	SipUrl local_sip_url_ext,
	SipAddr local_sip_record,
	Contact local_contact,
	CallPars cp optional
}
type record of ConnHdlrPars ConnHdlrParsList;

template (value) ConnHdlrPars t_Pars(charstring user,
				     charstring display_name := "Anonymous",
				     charstring password := "secret",
				     template (value) CallPars cp := t_CallPars()) := {
	t_guard := 30.0,
	user := user,
	display_name := f_sip_str_quote(display_name),
	password := password,
	registrar_sip_req_uri := valueof(ts_SipUrlHost(mp_remote_sip_host)),
	registrar_sip_record := ts_SipAddr(ts_HostPort(mp_remote_sip_host),
					   ts_UserInfo(user),
					   f_sip_str_quote(display_name)),
	registrar_sip_call_id := hex2str(f_rnd_hexstring(15)) & "@" & mp_local_sip_host,
	registrar_sip_seq_nr := f_sip_rand_seq_nr(),
	local_via := ts_Via_from(ts_HostPort(mp_local_sip_host, mp_local_sip_port)),
	local_sip_url_ext := ts_SipUrl(ts_HostPort(mp_local_sip_host, mp_local_sip_port),
				       ts_UserInfo(user)),
	local_sip_record := ts_SipAddr(ts_HostPort(mp_local_sip_host),
				       ts_UserInfo(user)),
	local_contact := valueof(ts_Contact({
					ts_ContactAddress(
						ts_Addr_Union_SipUrl(ts_SipUrl(ts_HostPort(
										 mp_local_sip_host,
										 mp_local_sip_port),
									       ts_UserInfo(user))),
						omit)
				})),
	cp := cp
}

function f_init_ConnHdlrPars(integer idx := 1) runs on test_CT return ConnHdlrPars {
	var  template (value) CallPars cp := t_CallPars(idx := idx);
	var template (value) ConnHdlrPars pars := t_Pars("0" & int2str(str2int(broadcast_sip_extension) + idx),
							 cp := cp);
	return valueof(pars);
}

type record CallParsMT {
	/* Whether to wait for COORD.receive(COORD_CMD_PICKUP) before accepting the call. */
	boolean wait_coord_cmd_pickup,
	/* Whether to expect CANCEL instead of ACK as answer to our OK */
	boolean exp_cancel
}
private template (value) CallParsMT t_CallParsMT := {
	wait_coord_cmd_pickup := false,
	exp_cancel := false
}

type record CallPars {
	SipAddr calling optional,
	SipAddr called optional,

	SipAddr from_addr optional,
	SipAddr to_addr optional,

	CallidString sip_call_id,
	integer sip_seq_nr,
	charstring sip_body optional,

	charstring local_rtp_addr,
	uint16_t local_rtp_port,

	SDP_Message peer_sdp optional,
	CallParsMT mt
}

private template (value) CallPars t_CallPars(integer idx := 1,
					     template (omit) SipAddr calling := omit,
					     template (omit) SipAddr called := omit) := {
	calling := calling,
	called := called,
	from_addr := omit,
	to_addr := omit,
	sip_call_id := hex2str(f_rnd_hexstring(15)),
	sip_seq_nr := f_sip_rand_seq_nr(),
	sip_body := omit,
	local_rtp_addr := mp_local_sip_host,
	local_rtp_port := 1234 + 2*idx,
	peer_sdp := omit,
	mt := t_CallParsMT
}

function f_init() runs on test_CT {
	f_init_sip(vc_SIP, "Asterisk_Test");
	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() & "-ConnHdlr-" & pars.user;

	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:COORD, self:COORD);

	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_name := id;
	g_pars := pars;
	g_Tguard.start(pars.t_guard);
	activate(as_Tguard());

	// Make sure the UA is deregistered before starting the test:
	// sends REGISTER with Contact = "*" and Expires = 0
	//f_SIP_deregister();

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

private altstep as_SIP_fail_req(charstring exp_msg_str := "") runs on ConnHdlr
{
	var PDU_SIP_Request sip_req;
	[] SIP.receive(PDU_SIP_Request:?) -> value sip_req {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
					log2str(g_name & ": Received unexpected SIP Req message := ", sip_req, "\nvs exp := ", exp_msg_str));
	}
}

private altstep as_SIP_fail_resp(charstring exp_msg_str := "") runs on ConnHdlr
{
	var PDU_SIP_Response sip_resp;
	[] SIP.receive(PDU_SIP_Response:?) -> value sip_resp {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
					log2str(g_name & ": Received unexpected SIP Resp message := ", sip_resp, "\nvs exp := ", exp_msg_str));
	}
}

altstep as_SIP_expect_req(template (present) PDU_SIP_Request sip_expect, boolean fail_others := true) runs on ConnHdlr
{
	var charstring sip_expect_str := log2str(sip_expect);
	[] SIP.receive(sip_expect) -> value g_rx_sip_req;
	[fail_others] as_SIP_fail_req(sip_expect_str);
	[fail_others] as_SIP_fail_resp(sip_expect_str);
}

altstep as_SIP_expect_resp(template (present) PDU_SIP_Response sip_expect, boolean fail_others := true) runs on ConnHdlr
{
	var charstring sip_expect_str := log2str(sip_expect);
	[] SIP.receive(sip_expect) -> value g_rx_sip_resp;
	[fail_others] as_SIP_fail_resp(sip_expect_str);
	[fail_others] as_SIP_fail_req(sip_expect_str);
}

altstep as_SIP_ignore_resp(template PDU_SIP_Response sip_expect := ?) runs on ConnHdlr
{
	[] SIP.receive(sip_expect) -> value g_rx_sip_resp {
		log("Ignoring ", g_rx_sip_resp);
		repeat;
	}
}

private function f_tr_Via_response(Via via_req) return template (present) Via {
	template (present) SemicolonParam_List via_resp_params := ?;

	/*via_resp_params := {
		{ id := "rport", paramValue := int2str(mp_remote_sip_port) },
		{ id := "received", paramValue := mp_remote_sip_host }
	}; */
	return 	tr_Via_from(via_req.viaBody[0].sentBy,
			    via_resp_params);
}

private function f_tr_To_response(template (value) SipAddr to_req) return template (present) SipAddr {
	return tr_SipAddr_from_val(to_req);
}

private function f_tr_From(template (value) SipAddr from_req) return template (present) SipAddr {
	return tr_SipAddr_from_val(from_req);
}

private function f_gen_sdp() runs on ConnHdlr return charstring {
	var charstring sdp :=
		"v=0\r\n" &
		"o=0502 2390 1824 IN IP4 " & g_pars.cp.local_rtp_addr & "\r\n" &
		"s=Talk\r\n" &
		"c=IN IP4 " & g_pars.cp.local_rtp_addr & "\r\n" &
		"t=0 0\r\n" &
		"a=rtcp-xr:rcvr-rtt=all:10000 stat-summary=loss,dup,jitt,TTL voip-metrics\r\n" &
		"a=record:off\r\n" &
		"m=audio " & int2str(g_pars.cp.local_rtp_port) & " RTP/AVP 96 97 98 0 8 18 99 100 101\r\n" &
		"a=rtpmap:96 opus/48000/2\r\n" &
		"a=fmtp:96 useinbandfec=1\r\n" &
		"a=rtpmap:97 speex/16000\r\n" &
		"a=fmtp:97 vbr=on\r\n" &
		"a=rtpmap:98 speex/8000\r\n" &
		"a=fmtp:98 vbr=on\r\n" &
		"a=fmtp:18 annexb=yes\r\n" &
		"a=rtpmap:99 telephone-event/48000\r\n" &
		"a=rtpmap:100 telephone-event/16000\r\n" &
		"a=rtpmap:101 telephone-event/8000\r\n" &
		"a=rtcp:" & int2str(g_pars.cp.local_rtp_port + 1) & "\r\n" &
		"a=rtcp-fb:* trr-int 1000\r\n" &
		"a=rtcp-fb:* ccm tmmbr\r\n";
	return sdp;
}

private function f_SIP_register() runs on ConnHdlr return PDU_SIP_Response
{
	var template (present) PDU_SIP_Response exp;
	var Authorization authorization;
	var Via via := g_pars.local_via;
	var SipAddr from_sipaddr := g_pars.registrar_sip_record;
	var charstring branch_value;

	branch_value := f_sip_gen_branch(f_sip_SipAddr_to_str(g_pars.registrar_sip_record),
					 f_sip_SipAddr_to_str(g_pars.registrar_sip_record),
					 g_pars.registrar_sip_call_id,
					 g_pars.registrar_sip_seq_nr);

	via.viaBody[0].viaParams := f_sip_param_set(via.viaBody[0].viaParams, "branch", branch_value);
	from_sipaddr.params := f_sip_param_set(from_sipaddr.params, "tag", f_sip_rand_tag());
	SIP.send(ts_SIP_REGISTER(g_pars.registrar_sip_req_uri,
				 g_pars.registrar_sip_call_id,
				 from_sipaddr,
				 g_pars.registrar_sip_record,
				 via,
				 g_pars.registrar_sip_seq_nr,
				 g_pars.local_contact,
				 ts_Expires("7200")));

	exp := tr_SIP_Response_Unauthorized(
			g_pars.registrar_sip_call_id,
			from_sipaddr,
			f_tr_To_response(g_pars.registrar_sip_record),
			f_tr_Via_response(via),
			*,
			tr_WwwAuthenticate({tr_Challenge_digestCln(?)}),
			g_pars.registrar_sip_seq_nr);
	as_SIP_expect_resp(exp);

	/* Digest Auth: RFC 2617 */
	authorization := f_sip_digest_gen_Authorization(g_rx_sip_resp.msgHeader.wwwAuthenticate,
							g_pars.user, g_pars.password,
							"REGISTER",
							f_sip_SipUrl_to_str(g_pars.registrar_sip_req_uri))

	/* New transaction: */
	g_pars.registrar_sip_seq_nr := g_pars.registrar_sip_seq_nr + 1;
	branch_value := f_sip_gen_branch(f_sip_SipAddr_to_str(g_pars.registrar_sip_record),
					 f_sip_SipAddr_to_str(g_pars.registrar_sip_record),
					 g_pars.registrar_sip_call_id,
					 g_pars.registrar_sip_seq_nr);
	via.viaBody[0].viaParams := f_sip_param_set(via.viaBody[0].viaParams, "branch", branch_value);

	SIP.send(ts_SIP_REGISTER(g_pars.registrar_sip_req_uri,
				g_pars.registrar_sip_call_id,
				from_sipaddr,
				g_pars.registrar_sip_record,
				via,
				g_pars.registrar_sip_seq_nr,
				g_pars.local_contact,
				ts_Expires("7200"),
				authorization := authorization));

	/* Wait for OK answer */
	exp := tr_SIP_Response(
			g_pars.registrar_sip_call_id,
			from_sipaddr,
			f_tr_To_response(g_pars.registrar_sip_record),
			f_tr_Via_response(via),
			*,
			"REGISTER", 200,
			g_pars.registrar_sip_seq_nr, "OK");
	as_SIP_expect_resp(exp);

	/* Prepare for next use: */
	g_pars.registrar_sip_seq_nr := g_pars.registrar_sip_seq_nr + 1;
	return g_rx_sip_resp;
}

private function f_SIP_mo_call_setup() runs on ConnHdlr
{
	var template (value) PDU_SIP_Request req;
	var template (present) PDU_SIP_Response exp;
	var Via via;
	var charstring tx_sdp := f_gen_sdp();
	var default d_trying, d_ringing;
	var charstring branch_value;

	/* RFC 3261 8.1.1.3 From */
	g_pars.cp.from_addr := g_pars.cp.calling;
	g_pars.cp.from_addr.params := f_sip_param_set(g_pars.cp.from_addr.params, "tag", f_sip_rand_tag());
	g_pars.cp.to_addr := g_pars.cp.called;
	branch_value := f_sip_gen_branch(f_sip_SipAddr_to_str(g_pars.cp.from_addr),
					 f_sip_SipAddr_to_str(valueof(g_pars.cp.to_addr)),
					 g_pars.cp.sip_call_id,
					 g_pars.cp.sip_seq_nr);
	via := g_pars.local_via;
	via.viaBody[0].viaParams := f_sip_param_set(via.viaBody[0].viaParams, "branch", branch_value);

	req := ts_SIP_INVITE(g_pars.cp.sip_call_id,
			     g_pars.cp.from_addr,
			     g_pars.cp.to_addr,
			     via,
			     g_pars.local_contact,
			     g_pars.cp.sip_seq_nr,
			     body := tx_sdp);

	SIP.send(req);

	/* RFC 3261 22.2: */
	exp := tr_SIP_Response_Unauthorized(
			g_pars.cp.sip_call_id,
			f_tr_From(g_pars.cp.from_addr),
			f_tr_To_response(g_pars.cp.to_addr),
			f_tr_Via_response(via),
			*,
			tr_WwwAuthenticate({tr_Challenge_digestCln(?)}),
			g_pars.cp.sip_seq_nr, "INVITE");
	as_SIP_expect_resp(exp);

	/* Digest Auth: RFC 2617 */
	req.msgHeader.authorization := f_sip_digest_gen_Authorization(
						g_rx_sip_resp.msgHeader.wwwAuthenticate,
						g_pars.user, g_pars.password,
						"INVITE",
						f_sip_SipUrl_to_str(g_pars.registrar_sip_req_uri))
	g_pars.cp.sip_seq_nr := g_pars.cp.sip_seq_nr + 1;
	f_sip_Request_inc_seq_nr(req);
	SIP.send(req);

	/* Conditionally match and accept 100 Trying. */
	exp := tr_SIP_Response_Trying(g_pars.cp.sip_call_id,
			g_pars.cp.from_addr,
			f_tr_To_response(g_pars.cp.to_addr),
			f_tr_Via_response(via),
			g_pars.cp.sip_seq_nr, "INVITE");
	d_trying := activate(as_SIP_ignore_resp(exp));

	/* Conditionally match and accept 180 Ringing */
	exp := tr_SIP_Response_Ringing(g_pars.cp.sip_call_id,
			g_pars.cp.from_addr,
			f_tr_To_response(g_pars.cp.to_addr),
			f_tr_Via_response(via),
			g_pars.cp.sip_seq_nr, "INVITE");
	d_ringing := activate(as_SIP_ignore_resp(exp));

	/* Wait for OK answer */
	exp := tr_SIP_Response(
			g_pars.cp.sip_call_id,
			g_pars.cp.from_addr,
			f_tr_To_response(g_pars.cp.to_addr),
			f_tr_Via_response(via),
			*,
			"INVITE", 200,
			g_pars.cp.sip_seq_nr, "OK",
			body := ?);
	as_SIP_expect_resp(exp, fail_others := false);

	deactivate(d_trying);
	deactivate(d_ringing);

	/* Update To with the tags received from peer: */
	g_pars.cp.to_addr := valueof(ts_SipAddr_from_Addr_Union(g_rx_sip_resp.msgHeader.toField.addressField,
								g_rx_sip_resp.msgHeader.toField.toParams));

	/* Transmit ACK */
	g_pars.cp.sip_seq_nr := g_pars.cp.sip_seq_nr + 1;
	req := ts_SIP_ACK(g_pars.cp.sip_call_id,
			  g_pars.cp.from_addr,
			  g_pars.cp.to_addr,
			  via,
			  g_pars.cp.sip_seq_nr,
			  omit);
	SIP.send(req);
	g_pars.cp.sip_seq_nr := g_pars.cp.sip_seq_nr + 1;
}

private function f_ConnHdlr_parse_initial_SIP_INVITE(PDU_SIP_Request rx_sip_req) runs on ConnHdlr
{
	f_SDP_decodeMessage(rx_sip_req.messageBody, g_pars.cp.peer_sdp);
	log("Rx Initial MT INVITE decoded SDP: ", g_pars.cp.peer_sdp);

	/* Obtain params: */
	g_pars.cp.sip_call_id := rx_sip_req.msgHeader.callId.callid;
	g_pars.cp.from_addr := valueof(ts_SipAddr_from_Addr_Union(rx_sip_req.msgHeader.fromField.addressField,
								rx_sip_req.msgHeader.fromField.fromParams));
	g_pars.cp.to_addr := valueof(ts_SipAddr_from_Addr_Union(rx_sip_req.msgHeader.toField.addressField,
								rx_sip_req.msgHeader.toField.toParams));
	g_pars.cp.to_addr.params := f_sip_param_set(g_pars.cp.to_addr.params, "tag", f_sip_rand_tag());
	g_pars.cp.sip_seq_nr := rx_sip_req.msgHeader.cSeq.seqNumber;
}

/* Peer is calling us, accept it: */
private altstep as_SIP_mt_call_accept(boolean exp_update_to_direct_rtp := true,
				      boolean fail_others := true) runs on ConnHdlr
{
	var template (present) PDU_SIP_Request exp_req :=
		tr_SIP_INVITE(f_tr_SipUrl_opt_defport(g_pars.local_sip_url_ext),
			      ?,
			      f_tr_From(g_pars.cp.calling),
			      g_pars.cp.called,
			      tr_Via_from(f_tr_HostPort(mp_remote_sip_host, mp_remote_sip_port)),
			      ?, ?);
	var charstring sip_expect_str := log2str(exp_req);

	[] SIP.receive(exp_req) -> value g_rx_sip_req {
		var template (value) PDU_SIP_Response tx_resp;
		var Via via;
		var charstring tx_sdp;

		/* Obtain params: */
		f_ConnHdlr_parse_initial_SIP_INVITE(g_rx_sip_req);
		via := g_rx_sip_req.msgHeader.via;


		/* Tx 180 Ringing */
		tx_resp := ts_SIP_Response_Ringing(g_pars.cp.sip_call_id,
						g_pars.cp.from_addr,
						g_pars.cp.to_addr,
						via,
						g_pars.cp.sip_seq_nr);
		SIP.send(tx_resp);

		if (g_pars.cp.mt.wait_coord_cmd_pickup) {
			COORD.receive(COORD_CMD_PICKUP);
		}

		/* Tx 200 OK */
		tx_sdp := f_gen_sdp();
		tx_resp := ts_SIP_Response(g_pars.cp.sip_call_id,
					g_pars.cp.from_addr,
					g_pars.cp.to_addr,
					"INVITE", 200,
					g_pars.cp.sip_seq_nr,
					"OK",
					via,
					body := tx_sdp);
		SIP.send(tx_resp);

		/* Wait for ACK */
		exp_req := tr_SIP_ACK(f_tr_SipUrl_opt_defport(g_pars.local_sip_url_ext),
				g_pars.cp.sip_call_id,
				g_pars.cp.from_addr,
				g_pars.cp.to_addr,
				f_tr_Via_response(via),
				g_pars.cp.sip_seq_nr, *);
		as_SIP_expect_req(exp_req);

		if (exp_update_to_direct_rtp) {
			/* Asterisk will now update the session to connect us to MO directly: */
			/* Via is not kept since anyway "branch" will change upon following INVITE. */
			as_SIP_exp_call_update(g_pars.cp.sip_seq_nr + 1);
		}
	}
	[fail_others] as_SIP_fail_resp(sip_expect_str);
	[fail_others] as_SIP_fail_req(sip_expect_str);

}

/* Peer is calling us, but cancells it during ringing: */
private altstep as_SIP_mt_call_cancelled(boolean fail_others := true) runs on ConnHdlr
{
	var template (present) PDU_SIP_Request exp_req :=
		tr_SIP_INVITE(f_tr_SipUrl_opt_defport(g_pars.local_sip_url_ext),
			      ?,
			      f_tr_From(g_pars.cp.calling),
			      g_pars.cp.called,
			      tr_Via_from(f_tr_HostPort(mp_remote_sip_host, mp_remote_sip_port)),
			      ?, ?);
	var charstring sip_expect_str := log2str(exp_req);

	[] SIP.receive(exp_req) -> value g_rx_sip_req {
		var template (value) PDU_SIP_Response tx_resp;
		var Via via;
		var template (present) SipAddr exp_to_addr;
		var charstring tx_sdp;

		/* Obtain params: */
		f_ConnHdlr_parse_initial_SIP_INVITE(g_rx_sip_req);
		via := g_rx_sip_req.msgHeader.via;


		/* Tx 180 Ringing */
		tx_resp := ts_SIP_Response_Ringing(g_pars.cp.sip_call_id,
						g_pars.cp.from_addr,
						g_pars.cp.to_addr,
						via,
						g_pars.cp.sip_seq_nr);
		SIP.send(tx_resp);

		if (g_pars.cp.mt.wait_coord_cmd_pickup) {
			COORD.receive(COORD_CMD_PICKUP);
		}

		/* Wait for CANCEL */
		/* Cancel may come even before we send Ringing, hence To's "tag"
		 * may not be known by peer, so g_pars.to_addr can't be used here: */
		exp_to_addr := ts_SipAddr_from_Addr_Union(g_rx_sip_req.msgHeader.toField.addressField,
							  g_rx_sip_req.msgHeader.toField.toParams);
		exp_req := tr_SIP_CANCEL(f_tr_SipUrl_opt_defport(g_pars.local_sip_url_ext),
					 g_pars.cp.sip_call_id,
					 g_pars.cp.from_addr,
					 exp_to_addr,
					 f_tr_Via_response(via),
					 g_pars.cp.sip_seq_nr, *);
		as_SIP_expect_req(exp_req);

		/* Tx 200 OK */
		tx_sdp := f_gen_sdp();
		tx_resp := ts_SIP_Response(g_pars.cp.sip_call_id,
					   g_pars.cp.from_addr,
					   g_pars.cp.to_addr,
					   "CANCEL", 200,
					   g_pars.cp.sip_seq_nr,
					   "OK",
					   via,
					   body := omit);
		SIP.send(tx_resp);
	}
	[fail_others] as_SIP_fail_resp(sip_expect_str);
	[fail_others] as_SIP_fail_req(sip_expect_str);

}

/* New INVITE arrives after MT call is established. Accept it: */
private altstep as_SIP_exp_call_update(template (present) integer exp_seq_nr := ?, boolean fail_others := true) runs on ConnHdlr
{
	var template (present) PDU_SIP_Request exp_req :=
		tr_SIP_INVITE(f_tr_SipUrl_opt_defport(g_pars.local_sip_url_ext),
				 		      g_pars.cp.sip_call_id,
				 		      g_pars.cp.from_addr,
				 		      g_pars.cp.to_addr,
				 		      tr_Via_from(f_tr_HostPort(mp_remote_sip_host, mp_remote_sip_port)),
				 		      exp_seq_nr,
				 		      ?);
	var charstring sip_expect_str := log2str(exp_req);

	[] SIP.receive(exp_req) -> value g_rx_sip_req {
		var template (value) PDU_SIP_Response tx_resp;
		var charstring tx_sdp;
		var Via via;

		f_SDP_decodeMessage(g_rx_sip_req.messageBody, g_pars.cp.peer_sdp);
		log("Rx Update MT INVITE decoded SDP: ", g_pars.cp.peer_sdp);

		/* Update parameters: */
		g_pars.cp.sip_seq_nr := g_rx_sip_req.msgHeader.cSeq.seqNumber;
		/* "branch" has changed: */
		via := g_rx_sip_req.msgHeader.via;

		/* Tx 200 OK */
		tx_sdp := f_gen_sdp();
		tx_resp := ts_SIP_Response(g_pars.cp.sip_call_id,
					g_pars.cp.from_addr,
					g_pars.cp.to_addr,
					"INVITE", 200,
					g_pars.cp.sip_seq_nr,
					"OK",
					via,
					body := tx_sdp);
		SIP.send(tx_resp);

		/* Wait for ACK */
		exp_req := tr_SIP_ACK(f_tr_SipUrl_opt_defport(g_pars.local_sip_url_ext),
				g_pars.cp.sip_call_id,
				g_pars.cp.from_addr,
				g_pars.cp.to_addr,
				f_tr_Via_response(via),
				g_pars.cp.sip_seq_nr, *);
		as_SIP_expect_req(exp_req);
	}
	[fail_others] as_SIP_fail_resp(sip_expect_str);
	[fail_others] as_SIP_fail_req(sip_expect_str);
}

/* Tx BYE: */
private function f_SIP_do_call_hangup() runs on ConnHdlr
{
	var template (value) PDU_SIP_Request req;
	var template (present) PDU_SIP_Response exp_resp;
	var Via via;
	var charstring branch_value;

	branch_value := f_sip_gen_branch(f_sip_SipAddr_to_str(g_pars.cp.from_addr),
					 f_sip_SipAddr_to_str(valueof(g_pars.cp.to_addr)),
					 g_pars.cp.sip_call_id,
					 g_pars.cp.sip_seq_nr);

	via := g_pars.local_via;
	via.viaBody[0].viaParams := f_sip_param_set(via.viaBody[0].viaParams, "branch", branch_value);

	/* Transmit ACK */
	req := ts_SIP_BYE(g_pars.cp.sip_call_id,
			  g_pars.cp.from_addr,
			  g_pars.cp.to_addr,
			  via,
			  g_pars.cp.sip_seq_nr,
			  omit);
	SIP.send(req);

	/* Wait for OK answer */
	exp_resp := tr_SIP_Response(
			g_pars.cp.sip_call_id,
			g_pars.cp.from_addr,
			f_tr_To_response(g_pars.cp.to_addr),
			f_tr_Via_response(via),
			*,
			"BYE", 200,
			g_pars.cp.sip_seq_nr, "OK");
	as_SIP_expect_resp(exp_resp);

	g_pars.cp.sip_seq_nr := g_pars.cp.sip_seq_nr + 1;
}

/* Call is terminated by peer: */
private altstep as_SIP_exp_call_hangup(template (present) integer exp_seq_nr := ?, boolean fail_others := true) runs on ConnHdlr
{
	var template (present) PDU_SIP_Request exp_req :=
		tr_SIP_BYE(f_tr_SipUrl_opt_defport(g_pars.local_sip_url_ext),
				 		   g_pars.cp.sip_call_id,
				 		   g_pars.cp.from_addr,
				 		   g_pars.cp.to_addr,
				 		   tr_Via_from(f_tr_HostPort(mp_remote_sip_host, mp_remote_sip_port)),
				 		   exp_seq_nr);
	var charstring sip_expect_str := log2str(exp_req);

	[] SIP.receive(exp_req) -> value g_rx_sip_req {
		var template (value) PDU_SIP_Response tx_resp;
		var charstring tx_sdp;
		var Via via;

		/* Update parameters: */
		g_pars.cp.sip_seq_nr := g_rx_sip_req.msgHeader.cSeq.seqNumber;
		/* "branch" has changed: */
		via := g_rx_sip_req.msgHeader.via;

		/* Tx 200 OK */
		tx_sdp := f_gen_sdp();
		tx_resp := ts_SIP_Response(g_pars.cp.sip_call_id,
					g_pars.cp.from_addr,
					g_pars.cp.to_addr,
					"BYE", 200,
					g_pars.cp.sip_seq_nr,
					"OK",
					via,
					body := tx_sdp);
		SIP.send(tx_resp);
	}
	[fail_others] as_SIP_fail_resp(sip_expect_str);
	[fail_others] as_SIP_fail_req(sip_expect_str);
}

/* Test SIP registration of local clients */
private function f_TC_internal_registration(charstring id) runs on ConnHdlr {

	f_SIP_register();
	// f_SIP_deregister();
	setverdict(pass);
}
testcase TC_internal_registration() runs on test_CT {
	var ConnHdlrPars pars;
	var ConnHdlr vc_conn;
	f_init();
	pars := f_init_ConnHdlrPars();
	vc_conn := f_start_handler(refers(f_TC_internal_registration), pars);
	vc_conn.done;
}

/* Successful SIP MO-MT Call between local clients: */
private function f_TC_internal_call_mo(charstring id) runs on ConnHdlr {

	f_SIP_register();
	COORD.send(COORD_CMD_REGISTERED);

	COORD.receive(COORD_CMD_START);
	f_SIP_mo_call_setup();
	COORD.send(COORD_CMD_CALL_ESTABLISHED);

	COORD.receive(COORD_CMD_HANGUP);
	f_SIP_do_call_hangup();

	setverdict(pass);
}
private function f_TC_internal_call_mt(charstring id) runs on ConnHdlr {

	f_create_sip_expect(valueof(ts_SipUrl_from_Addr_Union(g_pars.cp.called.addr)));

	f_SIP_register();
	COORD.send(COORD_CMD_REGISTERED);

	if (g_pars.cp.mt.exp_cancel) {
		as_SIP_mt_call_cancelled();
		COORD.send(COORD_CMD_CALL_CANCELLED);
		setverdict(pass);
		return;
	}

	as_SIP_mt_call_accept();
	COORD.send(COORD_CMD_CALL_ESTABLISHED);

	/* Once MO hangs up, Asterisk updates us to point RTP to it: */
	as_SIP_exp_call_update(g_pars.cp.sip_seq_nr + 1);
	as_SIP_exp_call_hangup(g_pars.cp.sip_seq_nr + 1);

	setverdict(pass);
}
testcase TC_internal_call_momt() runs on test_CT {
	var ConnHdlrPars pars[2];
	var ConnHdlr vc_conn[2];

	f_init();

	pars[0] := f_init_ConnHdlrPars(idx := 1);
	pars[1] := f_init_ConnHdlrPars(idx := 2);

	pars[0].cp.calling := pars[0].registrar_sip_record;
	pars[0].cp.called := pars[1].registrar_sip_record;

	pars[1].cp.calling := pars[0].registrar_sip_record;
	pars[1].cp.called := pars[1].local_sip_record;

	vc_conn[0] := f_start_handler(refers(f_TC_internal_call_mo), pars[0]);
	vc_conn[1] := f_start_handler(refers(f_TC_internal_call_mt), pars[1]);

	interleave {
	[] COORD.receive(COORD_CMD_REGISTERED) from vc_conn[0];
	[] COORD.receive(COORD_CMD_REGISTERED) from vc_conn[1];
	}

	COORD.send(COORD_CMD_START) to vc_conn[0];

	interleave {
	[] COORD.receive(COORD_CMD_CALL_ESTABLISHED) from vc_conn[0];
	[] COORD.receive(COORD_CMD_CALL_ESTABLISHED) from vc_conn[1];
	}

	/* Call on-going */
	f_sleep(1.0);

	COORD.send(COORD_CMD_HANGUP) to vc_conn[0];


	vc_conn[0].done;
	vc_conn[1].done;
}

/* One of the users calls (INVITE) shared extension, which makes all other user
 * equipments ring (INVITE). The first one to pick up the call (OK 200) gets the
 * call established (ACK), others get a CANCEL event. */
private function TC_internal_call_all_Nregistered(integer num_conns := 2) runs on test_CT {
	var ConnHdlrList vc_conn_list := {};
	const integer vc_conn_mo_idx := 0; /* Index of MO leg in vc_conn_list */
	const integer vc_conn_mt_idx := 1; /* Index of MT leg in vc_conn_list, peer picking up first the call */
	var SipAddr broadcast_sip_record;
	var ConnHdlrPars pars_mo;

	f_init();

	broadcast_sip_record := valueof(ts_SipAddr(ts_HostPort(mp_local_sip_host),
					ts_UserInfo(broadcast_sip_extension)));

	for (var integer i := 0; i < num_conns; i := i + 1) {
		var ConnHdlrPars pars;
		var ConnHdlr vc_conn;
		pars := f_init_ConnHdlrPars(idx := i + 1);
		if (i == vc_conn_mo_idx) { /* MO */
			pars.cp.calling := pars.registrar_sip_record;
			pars.cp.called := broadcast_sip_record;
			vc_conn := f_start_handler(refers(f_TC_internal_call_mo), pars);
			pars_mo := pars;
		} else { /* MT */
			pars.cp.calling := pars_mo.registrar_sip_record;
			pars.cp.called := pars.local_sip_record;
			pars.cp.mt.wait_coord_cmd_pickup := true;
			if (i != vc_conn_mt_idx) {
				/* Only first MT picking up (OK 200 INVITE) will be ACKed, others CANCELed: */
				pars.cp.mt.exp_cancel := true;
			}
			vc_conn := f_start_handler(refers(f_TC_internal_call_mt), pars);
		}
		vc_conn_list := vc_conn_list & { vc_conn };
	}

	/* Wait all users are registered: */
	for (var integer i := 0; i < num_conns; i := i + 1) {
		/* Note: "from vc_conn_list[i]" can't be used since they may arrive from components in any order: */
		COORD.receive(COORD_CMD_REGISTERED);
	}

	/* Ask MO user to start the call: */
	COORD.send(COORD_CMD_START) to vc_conn_list[vc_conn_mo_idx];

	/* Make sure the desired MT is the one picking up first the call: */
	COORD.send(COORD_CMD_PICKUP) to vc_conn_list[vc_conn_mt_idx];
	interleave {
	[] COORD.receive(COORD_CMD_CALL_ESTABLISHED) from vc_conn_list[vc_conn_mo_idx];
	[] COORD.receive(COORD_CMD_CALL_ESTABLISHED) from vc_conn_list[vc_conn_mt_idx];
	}

	/* Pick up from other phone calls and expect CANCEL: */
	for (var integer i := 0; i < num_conns; i := i + 1) {
		if (i != vc_conn_mo_idx and i != vc_conn_mt_idx) {
			COORD.send(COORD_CMD_PICKUP) to vc_conn_list[i];
			COORD.receive(COORD_CMD_CALL_CANCELLED) from vc_conn_list[i];
		}
	}

	/* Call on-going */
	f_sleep(1.0);

	COORD.send(COORD_CMD_HANGUP) to vc_conn_list[vc_conn_mo_idx];

	for (var integer i := 0; i < num_conns; i := i + 1) {
		vc_conn_list[i].done;
	}
}
testcase TC_internal_call_all_2registered() runs on test_CT {
	TC_internal_call_all_Nregistered(2);
}
testcase TC_internal_call_all_3registered() runs on test_CT {
	TC_internal_call_all_Nregistered(3);
}
testcase TC_internal_call_all_4registered() runs on test_CT {
	TC_internal_call_all_Nregistered(4);
}

testcase TC_selftest() runs on test_CT {
	f_sip_digest_selftest();
	setverdict(pass);
}

control {
	execute( TC_internal_registration() );
	execute( TC_internal_call_momt() );
	execute( TC_internal_call_all_2registered() );
	execute( TC_internal_call_all_3registered() );
	execute( TC_internal_call_all_4registered() );
}

}
