/* Component implementing a IMS server towards Asterisk's IMS UE
 * (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 IMS_ConnectionHandler {

import from TCCEncoding_Functions all;
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;

/* the PIPE asp port allows us to interact with ip xfrm via stdin/stdout */
import from PIPEasp_PortType all;
import from PIPEasp_Types all;
import from PIPEasp_Templates 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_ipsec_setup_script_path := "./IMS_ipsec_setup.sh";
}

const char c_sip_server_name := "osmo-ttcn3-hacks/0.23";


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

const charstring IMS_COORD_CMD_REGISTERED := "COORD_CMD_REGISTERED";

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

	port IMSCoord_PT COORD;
	port PIPEasp_PT PIPE;
}
type record of IMS_ConnHdlr IMS_ConnHdlrList;

type record IMS_ConnHdlrSubscrPars {
	charstring remote_sip_host optional,
	uint16_t remote_sip_port optional,
	charstring imsi,
	charstring display_name,
	charstring password,
	charstring msisdn,
	/* Expected User-Location-Info in P-Access-Network-Info */
	charstring uli_str,
	octetstring rand,
	octetstring autn,
	charstring ipsec_auth_key,
	integer ipsec_local_spi_c,
	integer ipsec_local_spi_s,
	integer ipsec_remote_spi_c optional,
	integer ipsec_remote_spi_s optional,
	uint16_t ipsec_remote_port_c optional,
	uint16_t ipsec_remote_port_s optional,
	SipAddr registrar_sip_record,
	CallidString registrar_sip_call_id,
	integer registrar_sip_seq_nr,
	SipUrl local_sip_url_ext,
	SipAddr local_sip_record,
	Contact local_contact,
	IMS_CallPars cp optional
}
type record of IMS_ConnHdlrSubscrPars IMS_ConnHdlrSubscrParsList;


type record IMS_ConnHdlrPars {
	float t_guard,
	charstring realm,
	charstring local_sip_host,
	uint16_t local_sip_port,
	SipUrl registrar_sip_req_uri,
	Via local_via,
	IMS_ConnHdlrSubscrPars subscr optional
}
type record of IMS_ConnHdlrPars IMS_ConnHdlrParsList;

type record IMS_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) IMS_CallParsMT t_IMS_CallParsMT := {
	wait_coord_cmd_pickup := false,
	exp_cancel := false
}

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

	From from_addr optional,
	To 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,
	IMS_CallParsMT mt
}

template (value) IMS_CallPars t_IMS_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_IMS_CallParsMT
}

template (value) IMS_ConnHdlrSubscrPars t_IMS_SubscrPars(charstring local_sip_host,
						   uint16_t local_sip_port,
						   charstring imsi,
						   charstring msisdn := "90828",
						   charstring display_name := "Anonymous",
						   charstring password := "secret",
						   template (omit) IMS_CallPars cp := omit) := {
	remote_sip_host := omit,
	remote_sip_port := omit,
	imsi := imsi,
	display_name := f_sip_str_quote(display_name),
	password := password,
	msisdn := msisdn,
	uli_str := "2380100010000101",
	/* The Nonce field is the Base64 encoded version of the RAND value and concatenated with the AUTN: */
	rand := '14987631f65f8e3788a0798b6ebcd08e'O,
	autn := 'f6e19a7ccb028000a06b19c9544516e5'O,
	ipsec_auth_key := "0x5238297dfcca759bd05d48ff49bc63fa00000000",
	ipsec_local_spi_c := 4142,
	ipsec_local_spi_s := 4143,
	ipsec_remote_spi_c := omit,
	ipsec_remote_spi_s := omit,
	ipsec_remote_port_c := omit,
	ipsec_remote_port_s := omit,
	registrar_sip_record := ts_SipAddr(ts_HostPort(local_sip_host),
					   ts_UserInfo(imsi),
					   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_sip_url_ext := ts_SipUrl(ts_HostPort(local_sip_host, local_sip_port),
				       ts_UserInfo(imsi)),
	local_sip_record := ts_SipAddr(ts_HostPort(local_sip_host),
				       ts_UserInfo(imsi)),
	local_contact := valueof(ts_Contact({
					ts_ContactAddress(
						ts_Addr_Union_SipUrl(ts_SipUrl(ts_HostPort(
										 local_sip_host,
										 local_sip_port),
								     ts_UserInfo(imsi))),
						omit)
				})),
	cp := cp
}

template (value) IMS_ConnHdlrPars t_IMS_Pars(charstring local_sip_host,
					uint16_t local_sip_port,
					charstring imsi,
					template (omit) IMS_CallPars cp := omit) := {
	t_guard := 30.0,
	realm := local_sip_host,
	local_sip_host := local_sip_host,
	local_sip_port := local_sip_port,
	registrar_sip_req_uri := valueof(ts_SipUrlHost(local_sip_host)),
	local_via := ts_Via_from(ts_HostPort(local_sip_host, local_sip_port)),
	subscr := t_IMS_SubscrPars(local_sip_host, local_sip_port, imsi := imsi, cp := cp)
}

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

type function ims_void_fn(charstring id) runs on IMS_ConnHdlr;
function f_ims_handler_init(ims_void_fn fn, charstring id, IMS_ConnHdlrPars pars)
runs on IMS_ConnHdlr {
	g_name := id;
	g_pars := pars;
	g_Tguard.start(pars.t_guard);
	activate(as_Tguard());

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

private altstep as_SIP_fail_req(charstring exp_msg_str := "") runs on IMS_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 IMS_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));
	}
}

private function f_nonce_from_rand_autn(octetstring rand, octetstring autn) return charstring {
	var octetstring concat := rand & autn;
	var charstring nonce := enc_MIME_Base64(concat);
	log("rand=", rand, " & autn=",autn, " => nonce=", nonce);
	return nonce;
}

/* HTTP Digest Authentication Using AKA (AKAv1-MD5): RFC 3310 */
function f_tr_Authorization_AKAv1MD5(WwwAuthenticate www_authenticate,
				     charstring username,
				     charstring uri,
				     integer nc_int := 1)
return template (present) Authorization {
	var CommaParam_List digestCln;
	var template (present) Authorization authorization;
	var template (present) Credentials cred;
	var template (omit) GenericParam rx_param;

	digestCln := www_authenticate.challenge[0].digestCln;

	var charstring algorithm := f_sip_param_get_value_present_or_fail(digestCln, "algorithm");
	var charstring realm := f_sip_param_get_value_present_or_fail(digestCln, "realm");
	var charstring nonce := f_sip_param_get_value_present_or_fail(digestCln, "nonce");

	var template (present) CommaParam_List digestResponse := superset(
		tr_Param("username", f_sip_str_quote(username)),
		tr_Param("realm", f_sip_str_quote(realm)),
		tr_Param("nonce", f_sip_str_quote(nonce)),
		tr_Param("uri", f_sip_str_quote(uri)),
		tr_Param("response", ?),
		tr_Param("algorithm", algorithm),
		tr_Param("qop", "auth"),
		tr_Param("cnonce", ?),
		tr_Param("nc", ?)
	);
	cred := tr_Credentials_DigestResponse(digestResponse);
	authorization := tr_Authorization(cred);
	return authorization;
}

private function f_ims_validate_register_contact(Contact rx_contact)
{
/* IMS contact shows up like this:
 * Contact: <sip:8adf9f3d-9342-4060-aa4f-a909f37fd6f6@192.168.101.2:5060>;+g.3gpp.accesstype="cellular2";video;audio;+g.3gpp.smsip;+g.3gpp.nw-init-ussi;+g.3gpp.icsi-ref="urn%3Aurn-7%3A3gpp-service.ims.icsi.mmtel";+sip.instance="<urn:gsma:imei:35589811-338445-0>"
 */
 /* TODO: "that the UE must include the IMS Communication Service Identifier (ICSI)
in the contact: header to indicate IMS Multimedia Telephony." */
 /* TODO: "The UE must include an IMEI URN in the +sip.instance header field
parameter of the contact: header." */
 /* TODO: "If the UE supports SMS over IP, it must include the feature tag
“+g.3gpp.smsip” in the contact: header." */
 /* TODO: "If the UE supports conversational audio and video service, then this must
be indicated by adding a “video” media feature tag to the contact: header." */
}

/* Validate P-Access-Network-Info: RFC7315 6.4 */
private function f_ims_validate_register_P_Access_Network_info(PDU_SIP_Request req,
							       boolean exp_present := true) runs on IMS_ConnHdlr

{
	if (not exp_present) {
		if (ispresent(g_rx_sip_req.msgHeader.p_access_network_info)) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
						log2str(g_name & ": Received unexpected [rfc7315 6.4] P-Access-Info := ",
						g_rx_sip_req.msgHeader.p_access_network_info));
		}
		return;
	}

	/* exp_present: */
	var template (present) P_Access_Network_Info expl_tmpl :=
		tr_P_Access_Network_Info({ tr_Access_net_spec_EUTRAN(g_pars.subscr.uli_str) });

	if (not ispresent(g_rx_sip_req.msgHeader.p_access_network_info)) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
					log2str(g_name & ": Received no P-Access-Info vs exp := ",
					expl_tmpl));
	}
	if (not match(g_rx_sip_req.msgHeader.p_access_network_info, expl_tmpl)) {
				Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
							log2str(g_name & ": Received unexpected P-Access-Info := ",
							g_rx_sip_req.msgHeader.p_access_network_info,
							"\nvs exp := ", expl_tmpl));
	}
}

private function f_ims_parse_security_client(Security_client security_client) runs on IMS_ConnHdlr
{
	var boolean found := false;
	for (var integer i := 0; i < lengthof(security_client.sec_mechanism_list); i := i + 1) {
		var Security_mechanism sec_mec := security_client.sec_mechanism_list[i];
		if (sec_mec.mechanism_name != "ipsec-3gpp") {
			log("Skipping Security Mechansim: ", sec_mec.mechanism_name);
			continue;
		}
		var SemicolonParam_List sec_pars := sec_mec.mechanism_params;
		var charstring par_val;
		par_val := f_sip_param_get_value_present_or_fail(sec_pars, "alg");
		if (par_val != "hmac-sha-1-96") {
			log("Skipping Security Mechansim Algo: ", par_val);
			continue;
		}
		par_val := f_sip_param_get_value_present_or_fail(sec_pars, "spi-c");
		g_pars.subscr.ipsec_remote_spi_c := str2int(par_val);
		par_val := f_sip_param_get_value_present_or_fail(sec_pars, "spi-s");
		g_pars.subscr.ipsec_remote_spi_s := str2int(par_val);
		par_val := f_sip_param_get_value_present_or_fail(sec_pars, "port-c");
		g_pars.subscr.ipsec_remote_port_c := str2int(par_val);
		par_val := f_sip_param_get_value_present_or_fail(sec_pars, "port-s");
		g_pars.subscr.ipsec_remote_port_s := str2int(par_val);
		found := true;
		break;
	}

	if (not found) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
					log2str(g_name & "alg=hmac-sha-1-96 not found: ", security_client));
	}

	log("ipsec: remote_spi_c=", g_pars.subscr.ipsec_remote_spi_c, " remote_spi_s=", g_pars.subscr.ipsec_remote_spi_s,
	    "local_spi_c=", g_pars.subscr.ipsec_local_spi_c, " local_spi_s=", g_pars.subscr.ipsec_local_spi_s);
}

private function f_IMS_exec_sync(charstring cmdline, template (present) integer rc := 0)
		runs on IMS_ConnHdlr return ASP_PResult {
	var ASP_PResult res;

	map(self:PIPE, system:PIPE);
	res := f_PIPEasp_exec_sync_PResult(PIPE, cmdline, tr_PResult(?, ?, rc));
	unmap(self:PIPE, system:PIPE);

	return res;
}

private function f_ims_setup_ipsec() runs on IMS_ConnHdlr
{
	var ASP_PResult res;

	var charstring cmd := mp_ipsec_setup_script_path & " " &
		g_pars.local_sip_host & " " &
		int2str(g_pars.local_sip_port) & " " & int2str(g_pars.subscr.ipsec_local_spi_c) & " " &
		int2str(g_pars.local_sip_port) & " " & int2str(g_pars.subscr.ipsec_local_spi_s) & " " &
		g_pars.subscr.remote_sip_host & " " &
		int2str(g_pars.subscr.ipsec_remote_port_c) & " " & int2str(g_pars.subscr.ipsec_remote_spi_c) & " " &
		int2str(g_pars.subscr.ipsec_remote_port_s) & " " & int2str(g_pars.subscr.ipsec_remote_spi_s) & " " &
		g_pars.subscr.ipsec_auth_key;

	res := f_IMS_exec_sync(cmd);

	/* Debug applied rules: */
	/*
	res := f_IMS_exec_sync("ip xfrm state");
	log("ip-xfrm-state Result-Stdout: " & res.stdout);

	res := f_IMS_exec_sync("ip xfrm policy");
	log("ip-xfrm-policy Result-Stdout: " & res.stdout);
	*/
}

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.subscr.remote_sip_port.subscr.remote_sip_port) },
		{ id := "received", paramValue := g_pars.subscr.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_From(template (value) SipAddr from_req) return template (present) SipAddr {
	return tr_SipAddr_from_val(from_req);
}

private altstep as_SIP_expect_req(template (present) PDU_SIP_Request sip_expect, boolean fail_others := true) runs on IMS_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);
}

private function f_gen_sdp() runs on IMS_ConnHdlr return charstring {
	var charstring sdp :=
		"v=0\r\n" &
		"o=0502 2390 1824 IN IP4 " & g_pars.subscr.cp.local_rtp_addr & "\r\n" &
		"s=Talk\r\n" &
		"c=IN IP4 " & g_pars.subscr.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.subscr.cp.local_rtp_port) & " RTP/AVP 8 96 97 98 0 18 99 100 101\r\n" &
		"a=rtpmap:8 PCMA/8000\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.subscr.cp.local_rtp_port + 1) & "\r\n" &
		"a=rtcp-fb:* trr-int 1000\r\n" &
		"a=rtcp-fb:* ccm tmmbr\r\n";
	return sdp;
}

/* Peer is calling us, accept it: */
altstep as_IMS_register(boolean exp_update_to_direct_rtp := true,
			boolean fail_others := true) runs on IMS_ConnHdlr
{
	var template (present) PDU_SIP_Request exp_req :=
		tr_SIP_REGISTER(g_pars.registrar_sip_req_uri,
				?,
				tr_From(),
				tr_To(),
				tr_Via_from(?),
				require := tr_Require(superset("sec-agree")),
				security_client := tr_Security_client(superset(tr_Security_mechanism("ipsec-3gpp",
												     superset(tr_Param("alg","hmac-sha-1-96"))))),
				supported := tr_Supported(superset("path", "sec-agree")));
	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 CallidString sip_call_id;
		var Contact contact;
		var template (value) From from_addr;
		var template (value) To to_addr;
		var template (value) CommaParam_List digestCln ;
		var template (value) WwwAuthenticate wwwAuthenticate;
		var template (value) P_Associated_Uri p_associated_uri := ts_P_Associated_Uri({});
		var template (value) Security_server security_server;
		var template (value) Server server_name := ts_Server({c_sip_server_name});
		var template (value) Require require := ts_Require({"sec-agree"});
		var template (value) Supported supported := ts_Supported({"sec-agree"});
		var template (present) Authorization authorization;
		var integer sip_seq_nr;
		var charstring tx_sdp;

		sip_call_id := g_rx_sip_req.msgHeader.callId.callid;
		via := g_rx_sip_req.msgHeader.via;
		via.viaBody[0].viaParams := f_sip_param_set(via.viaBody[0].viaParams, "rport", "1234"); /* TODO: set remote src port of the REGISTER */
		from_addr := g_rx_sip_req.msgHeader.fromField;
		to_addr := g_rx_sip_req.msgHeader.toField;
		sip_seq_nr := g_rx_sip_req.msgHeader.cSeq.seqNumber;

		contact := g_rx_sip_req.msgHeader.contact;
		f_ims_validate_register_contact(contact);

		/* Validate P-Access-Network-Info: rfc7315 6.4:
		 * "3GPP will use the P-Access-Network-Info header field to
		 * carry relatively sensitive information like the cell ID.  Therefore,
		 * the information MUST NOT be sent outside of the 3GPP domain.""
		 * [...] "the sensitive information carried in the
		 * P-Access-Network-Info header field MUST NOT be sent in any initial
		 * unauthenticated and unprotected requests (e.g., REGISTER)."
		 */
		f_ims_validate_register_P_Access_Network_info(g_rx_sip_req, exp_present := false);

		/* TODO: Validate "Expires" is 600000 */

		/* Tx 100 Tyring */
		tx_resp := ts_SIP_Response_Trying(sip_call_id,
					from_addr,
					to_addr,
					via,
					sip_seq_nr,
					"REGISTER",
					allow := omit,
					server := server_name,
					userAgent := omit);
		SIP.send(tx_resp);

		var HostPort hp := valueof(contact.contactBody.contactAddresses[0].addressField.nameAddr.addrSpec.hostPort);
		g_pars.subscr.remote_sip_host := hp.host;
		if (ispresent(hp.portField)) {
			g_pars.subscr.remote_sip_port := hp.portField;
		} else {
			g_pars.subscr.remote_sip_port := 5060;
		}
		f_ims_parse_security_client(g_rx_sip_req.msgHeader.security_client);
		f_ims_setup_ipsec();

		to_addr.toParams := f_sip_param_set(to_addr.toParams, "tag", f_sip_rand_tag());

		digestCln := {
			ts_Param("realm", f_sip_str_quote(g_pars.realm)),
			ts_Param("qop", f_sip_str_quote("auth")),
			ts_Param("algorithm", "AKAv1-MD5"),
			ts_Param("nonce", f_sip_str_quote(f_nonce_from_rand_autn(g_pars.subscr.rand, g_pars.subscr.autn)))
			/* "opaque not needed in IMS "*/
		};
		wwwAuthenticate := ts_WwwAuthenticate( { ts_Challenge_digestCln(digestCln) } )

		/* Security-Server: ipsec-3gpp;q=0.1;prot=esp;mod=trans;spi-c=4096;spi-s=4097;port-c=5104;port-s=6104;alg=hmac-sha-1-96;ealg=null */
		var template (value) SemicolonParam_List sec_params := {
			ts_Param("q", "0.1"),
			ts_Param("prot", "esp"),
			ts_Param("mod", "trans"),
			ts_Param("spi-c", int2str(g_pars.subscr.ipsec_local_spi_c)),
			ts_Param("spi-s", int2str(g_pars.subscr.ipsec_local_spi_s)),
			ts_Param("port-c", int2str(g_pars.local_sip_port)),
			ts_Param("port-s", int2str(g_pars.local_sip_port)),
			ts_Param("alg", "hmac-sha-1-96"),
			ts_Param("ealg", "null")
		};
		security_server := ts_Security_server({
			ts_Security_mechanism("ipsec-3gpp", sec_params)
		});

		/* Tx 401 Unauthorized */
		tx_resp := ts_SIP_Response_Unauthorized(sip_call_id,
					from_addr,
					to_addr,
					via,
					wwwAuthenticate,
					sip_seq_nr,
					"REGISTER",
					p_associated_uri := p_associated_uri,
					security_server := security_server,
					server := server_name,
					supported := supported,
					userAgent := omit);
		SIP.send(tx_resp);

		/* Now we should receive a new REGISTER over ipsec: */

		/* TODO: Generate expected Authoritzation based on AKAv1-MD5: */
		/*authorization := f_sip_digest_gen_Authorization(valueof(wwwAuthenticate),
								g_pars.user, g_pars.subscr.password,
								"REGISTER",
								f_sip_SipUrl_to_str(g_pars.subscr.registrar_sip_record.addr.nameAddr.addrSpec))
		*/
		authorization := f_tr_Authorization_AKAv1MD5(valueof(wwwAuthenticate),
							     g_pars.subscr.imsi & "@" & g_pars.realm,
							     f_sip_SipUrl_to_str(g_pars.registrar_sip_req_uri));
		/* TODO: match Authorization from above: */
		exp_req :=
		tr_SIP_REGISTER(g_pars.registrar_sip_req_uri,
				?,
				tr_From(),
				tr_To(),
				tr_Via_from(?),
				authorization := authorization);
		SIP.receive(exp_req) -> value g_rx_sip_req;

		sip_call_id := g_rx_sip_req.msgHeader.callId.callid;
		via := g_rx_sip_req.msgHeader.via;
		from_addr := g_rx_sip_req.msgHeader.fromField;
		to_addr := g_rx_sip_req.msgHeader.toField;
		sip_seq_nr := g_rx_sip_req.msgHeader.cSeq.seqNumber;

		/* Tx 100 Trying */
		tx_resp := ts_SIP_Response_Trying(sip_call_id,
					from_addr,
					to_addr,
					via,
					sip_seq_nr,
					"REGISTER",
					allow := omit,
					server := server_name,
					userAgent := omit);
		SIP.send(tx_resp);

		/* Validate P-Access-Network-Info: */
		f_ims_validate_register_P_Access_Network_info(g_rx_sip_req, exp_present := true);

		p_associated_uri := ts_P_Associated_Uri({
				ts_P_Assoc_uri_spec(ts_NameAddr(ts_SipUrl(ts_HostPort(g_pars.realm),
									  ts_UserInfo(g_pars.subscr.msisdn),
									  scheme := "sip"))),
				ts_P_Assoc_uri_spec(ts_NameAddr(ts_SipUrl(ts_HostPort(g_pars.subscr.msisdn),
									  omit,
									  scheme := "tel"))),
				ts_P_Assoc_uri_spec(g_rx_sip_req.msgHeader.toField.addressField.nameAddr)
			});

		/* Tx 200 OK */
		to_addr.toParams := f_sip_param_set(to_addr.toParams, "tag", f_sip_rand_tag());
		tx_resp := ts_SIP_Response(sip_call_id,
			from_addr,
			to_addr,
			"REGISTER", 200,
			sip_seq_nr,
			"OK",
			via,
			p_associated_uri := p_associated_uri,
			require := require,
			server := server_name,
			supported := supported,
			userAgent := omit);
		SIP.send(tx_resp);
	}
	[fail_others] as_SIP_fail_resp(sip_expect_str);
	[fail_others] as_SIP_fail_req(sip_expect_str);

}

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

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

/* Peer is calling us, accept it: */
altstep as_IMS_mo_call_accept(boolean exp_update_to_direct_rtp := false,
			      boolean fail_others := true) runs on IMS_ConnHdlr
{
	var template (present) PDU_SIP_Request exp_req :=
		tr_SIP_INVITE(f_tr_SipUrl_opt_defport(ts_SipUrl_from_Addr_Union(g_pars.subscr.cp.called.addr)),
			      ?,
			      ( /* FIXME: We should be sending with MSISDN here, aka 2nd option below, but we receive IMSI (first opt): */
			        tr_From(tr_Addr_Union_from_val(g_pars.subscr.local_sip_record.addr), *),
			        tr_From(tr_Addr_Union_from_val(g_pars.subscr.cp.calling.addr), *)
			      ),
			      tr_To(tr_Addr_Union_from_val(g_pars.subscr.cp.called.addr), *),
			      tr_Via_from(f_tr_HostPort(g_pars.subscr.remote_sip_host, g_pars.subscr.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.subscr.cp.sip_call_id,
						   g_pars.subscr.cp.from_addr,
						   g_pars.subscr.cp.to_addr,
						   via,
						   g_pars.subscr.cp.sip_seq_nr);
		SIP.send(tx_resp);

		/* Tx 200 OK */
		tx_sdp := f_gen_sdp();
		tx_resp := ts_SIP_Response(g_pars.subscr.cp.sip_call_id,
					   g_pars.subscr.cp.from_addr,
					   g_pars.subscr.cp.to_addr,
					   "INVITE", 200,
					   g_pars.subscr.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(ts_SipUrl_from_Addr_Union(g_pars.subscr.cp.called.addr)),
				      g_pars.subscr.cp.sip_call_id,
				      g_pars.subscr.cp.from_addr,
				      g_pars.subscr.cp.to_addr,
				      f_tr_Via_response(via),
				      g_pars.subscr.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);

}

/* Call is terminated by peer: */
altstep as_IMS_exp_call_hangup(template (present) integer exp_seq_nr := ?, boolean fail_others := true) runs on IMS_ConnHdlr
{
	var template (present) PDU_SIP_Request exp_req :=
		tr_SIP_BYE(f_tr_SipUrl_opt_defport(ts_SipUrl_from_Addr_Union(g_pars.subscr.cp.called.addr)),
			   g_pars.subscr.cp.sip_call_id,
			   g_pars.subscr.cp.from_addr,
			   g_pars.subscr.cp.to_addr,
			   tr_Via_from(f_tr_HostPort(g_pars.subscr.remote_sip_host, g_pars.subscr.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.subscr.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.subscr.cp.sip_call_id,
					g_pars.subscr.cp.from_addr,
					g_pars.subscr.cp.to_addr,
					"BYE", 200,
					g_pars.subscr.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);
}

}
