/* 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,
	P_Associated_Uri p_associated_uri,
	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)
				})),
	p_associated_uri := ts_P_Associated_Uri({}),
	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 issuing 1st register, accept it: */
altstep as_IMS_register(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) 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 := g_pars.subscr.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);

		g_pars.subscr.p_associated_uri := valueof(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 := g_pars.subscr.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);

}

/* Peer wants to unregister, accept it: */
altstep as_IMS_unregister(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(?),
				expires := tr_Expires(int2str(0)),
				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) 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: */
		f_ims_validate_register_P_Access_Network_info(g_rx_sip_req, exp_present := true);

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

		/* Change all Contact parameters to expires=0: */
		for (var integer i := 0; i < lengthof(contact.contactBody.contactAddresses); i := i + 1) {
			contact.contactBody.contactAddresses[i].contactParams := valueof({ ts_Param("expires", "0") });
		}
		/* 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,
			contact := contact,
			p_associated_uri := g_pars.subscr.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);
}

}
