/* Component implementing a SIP UA towards Asterisk
 * (C) 2024 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
 * Author: Pau Espin Pedrol <pespin@sysmocom.de>
 * 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
 */
module SIP_ConnectionHandler {

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;

type port Coord_PT message
{
	inout charstring;
} with { extension "internal" };

const charstring COORD_CMD_REGISTERED := "COORD_CMD_REGISTERED";
const charstring COORD_CMD_START := "COORD_CMD_START";
const charstring COORD_CMD_PICKUP := "COORD_CMD_PICKUP";
const charstring COORD_CMD_CALL_ESTABLISHED := "COORD_CMD_CALL_ESTABLISHED";
const charstring COORD_CMD_CALL_CANCELLED := "COORD_CMD_CALL_CANCELLED";
const charstring COORD_CMD_HANGUP := "COORD_CMD_HANGUP";

type component SIPConnHdlr extends SIP_ConnHdlr {
	var charstring g_name;
	var SIPConnHdlrPars 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 SIPConnHdlr SIPConnHdlrList;

type record SIPConnHdlrPars {
	float t_guard,
	charstring remote_sip_host,
	uint16_t remote_sip_port,
	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 SIPConnHdlrPars SIPConnHdlrParsList;

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

template (value) CallPars t_CallPars(charstring local_rtp_addr,
				     uint16_t local_rtp_port := 0,
				     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 := local_rtp_addr,
	local_rtp_port := local_rtp_port,
	peer_sdp := omit,
	mt := t_CallParsMT
}

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

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

type function void_fn(charstring id) runs on SIPConnHdlr;
function f_handler_init(void_fn fn, charstring id, SIPConnHdlrPars pars)
runs on SIPConnHdlr {
	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 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(g_pars.remote_sip_port) },
		{ id := "received", paramValue := g_pars.remote_sip_host }
	}; */
	return 	tr_Via_from(via_req.viaBody[0].sentBy,
			    via_req.viaBody[0].sentProtocol.transport,
			    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 altstep as_SIP_fail_req(charstring exp_msg_str := "") runs on SIPConnHdlr
{
	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 SIPConnHdlr
{
	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 SIPConnHdlr
{
	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 SIPConnHdlr
{
	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 SIPConnHdlr
{
	[] SIP.receive(sip_expect) -> value g_rx_sip_resp {
		log("Ignoring ", g_rx_sip_resp);
		repeat;
	}
}

private function f_gen_sdp() runs on SIPConnHdlr 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;
}

function f_SIP_register() runs on SIPConnHdlr 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;
}

function f_SIP_mo_call_setup() runs on SIPConnHdlr
{
	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 SIPConnHdlr
{
	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: */
altstep as_SIP_mt_call_accept(boolean exp_update_to_direct_rtp := true,
			      boolean fail_others := true) runs on SIPConnHdlr
{
	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(g_pars.remote_sip_host, g_pars.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: */
altstep as_SIP_mt_call_cancelled(boolean fail_others := true) runs on SIPConnHdlr
{
	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(g_pars.remote_sip_host, g_pars.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: */
altstep as_SIP_exp_call_update(template (present) integer exp_seq_nr := ?, boolean fail_others := true) runs on SIPConnHdlr
{
	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(g_pars.remote_sip_host, g_pars.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: */
function f_SIP_do_call_hangup() runs on SIPConnHdlr
{
	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: */
altstep as_SIP_exp_call_hangup(template (present) integer exp_seq_nr := ?, boolean fail_others := true) runs on SIPConnHdlr
{
	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(g_pars.remote_sip_host, g_pars.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);
}

}
