/* 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 integer c_def_expires := 600000; /* 3GPP TS 24.229 5.1.1.2.1 e) */
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_AuthVector {
	OCT16 rand,
	OCT16 autn,
	OCT8 res,
	OCT16 ck,
	OCT16 ik
}

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,
	IMS_AuthVector auth,
	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",
	auth := {
		/* The Nonce field is the Base64 encoded version of the RAND value and concatenated with the AUTN: */
		rand := 'd5d5de2bce418d7865ed7fa6956618a2'O,
		autn := 'd42e61db5f15800067393a5b7691a227'O,
		res := '6f2556bbe4366ab1'O,
		ck := '0b389d08c833991734936bec55cac800'O,
		ik := '17141862125bd30c81c4224391a0909a'O
	},
	ipsec_auth_key := "0x17141862125bd30c81c4224391a0909a00000000",
	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)
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_Authorization_AKAv1MD5_Response(Authorization authorization, charstring method)
runs on IMS_ConnHdlr {
	f_sip_digest_validate_Authorization_AKAv1MD5(authorization, method, g_pars.subscr.auth.res);
}


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(?),
				expires := tr_Expires(int2str(c_def_expires)),
				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);

		/* 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.auth.rand,
										 g_pars.subscr.auth.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: */
		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));
		exp_req :=
		tr_SIP_REGISTER(g_pars.registrar_sip_req_uri,
				?,
				tr_From(),
				tr_To(),
				tr_Via_from(f_tr_HostPort(g_pars.subscr.remote_sip_host, g_pars.subscr.ipsec_remote_port_c)),
				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 Digest Response: */
		f_ims_validate_Authorization_AKAv1MD5_Response(g_rx_sip_req.msgHeader.authorization, "REGISTER");

		/* 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(f_tr_HostPort(g_pars.subscr.remote_sip_host, g_pars.subscr.ipsec_remote_port_c)),
				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.ipsec_remote_port_c)),
			      ?, ?);
	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.ipsec_remote_port_c)),
			   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);
}

}
