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_CALL_ESTABLISHED := "COORD_CMD_CALL_ESTABLISHED";
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 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
}

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(500 + idx),
							 cp := cp);
	return valueof(pars);
}

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
}

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
}

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

/* 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;

		f_SDP_decodeMessage(g_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 := g_rx_sip_req.msgHeader.callId.callid;
		g_pars.cp.from_addr := valueof(ts_SipAddr_from_Addr_Union(g_rx_sip_req.msgHeader.fromField.addressField,
									g_rx_sip_req.msgHeader.fromField.fromParams));
		g_pars.cp.to_addr := valueof(ts_SipAddr_from_Addr_Union(g_rx_sip_req.msgHeader.toField.addressField,
									g_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 := g_rx_sip_req.msgHeader.cSeq.seqNumber;
		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);

		/* 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);

}

/* 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);

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

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


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

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

control {
	execute( TC_internal_registration() );
	execute( TC_internal_call_momt() );
}

}
