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

}
