/* 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 domain,
						   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(domain),
					   ts_UserInfo(imsi),
					   f_sip_str_quote(display_name)),
	registrar_sip_call_id := hex2str(f_rnd_hexstring(15)) & "@" & domain,
	registrar_sip_seq_nr := f_sip_rand_seq_nr(),
	local_sip_url_ext := ts_SipUrl(ts_HostPort(domain, local_sip_port),
				       ts_UserInfo(imsi)),
	local_sip_record := ts_SipAddr(ts_HostPort(domain),
				       ts_UserInfo(imsi)),
	local_contact := valueof(ts_Contact({
					ts_ContactAddress(
						ts_Addr_Union_SipUrl(ts_SipUrl(ts_HostPort(
										 domain,
										 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 domain,
					charstring imsi,
					template (omit) IMS_CallPars cp := omit) := {
	t_guard := 30.0,
	realm := domain,
	local_sip_host := local_sip_host,
	local_sip_port := local_sip_port,
	registrar_sip_req_uri := valueof(ts_SipUrlHost(domain)),
	local_via := ts_Via_from(ts_HostPort(local_sip_host, local_sip_port)),
	subscr := t_IMS_SubscrPars(local_sip_host, local_sip_port, domain := domain, 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)),
			      ?,
			      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);
}

}
