/* 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 TCCOpenSecurity_Functions all;
import from General_Types all;
import from Osmocom_Types all;
import from Native_Functions all;
import from Misc_Helpers all;

import from SDP_Types all;
import from SDP_Templates all;

import from SIP_Emulation all;
import from SIPmsg_Types all;
import from SIP_Templates all;

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;
}
type record of IMS_ConnHdlr IMS_ConnHdlrList;

type record IMS_ConnHdlrPars {
	float t_guard,
	charstring realm,
	charstring local_sip_host,
	uint16_t local_sip_port,
	charstring remote_sip_host optional,
	uint16_t remote_sip_port optional,
	charstring user,
	charstring display_name,
	charstring password,
	integer ipsec_local_spi_c,
	integer ipsec_local_spi_s,
	integer ipsec_remote_spi_c optional,
	integer ipsec_remote_spi_s optional,
	SipUrl registrar_sip_req_uri,
	SipAddr registrar_sip_record,
	CallidString registrar_sip_call_id,
	integer registrar_sip_seq_nr,
	Via local_via,
	SipUrl local_sip_url_ext,
	SipAddr local_sip_record,
	Contact local_contact,
	IMS_CallPars cp 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,

	SipAddr from_addr optional,
	SipAddr to_addr optional,

	CallidString sip_call_id,
	integer sip_seq_nr,
	charstring sip_body optional,

	charstring local_rtp_addr,
	uint16_t local_rtp_port,

	SDP_Message peer_sdp optional,
	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_ConnHdlrPars t_IMS_Pars(charstring local_sip_host,
					uint16_t local_sip_port,
					charstring user,
					charstring display_name := "Anonymous",
					charstring password := "secret",
					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,
	remote_sip_host := omit,
	remote_sip_port := omit,
	user := user,
	display_name := f_sip_str_quote(display_name),
	password := password,
	ipsec_local_spi_c := 4142,
	ipsec_local_spi_s := 4143,
	ipsec_remote_spi_c := omit,
	ipsec_remote_spi_s := omit,
	registrar_sip_req_uri := valueof(ts_SipUrlHost(local_sip_host)),
	registrar_sip_record := ts_SipAddr(ts_HostPort(local_sip_host),
					   ts_UserInfo(user),
					   f_sip_str_quote(display_name)),
	registrar_sip_call_id := hex2str(f_rnd_hexstring(15)) & "@" & local_sip_host,
	registrar_sip_seq_nr := f_sip_rand_seq_nr(),
	local_via := ts_Via_from(ts_HostPort(local_sip_host, local_sip_port)),
	local_sip_url_ext := ts_SipUrl(ts_HostPort(local_sip_host, local_sip_port),
				       ts_UserInfo(user)),
	local_sip_record := ts_SipAddr(ts_HostPort(local_sip_host),
				       ts_UserInfo(user)),
	local_contact := valueof(ts_Contact({
					ts_ContactAddress(
						ts_Addr_Union_SipUrl(ts_SipUrl(ts_HostPort(
										 local_sip_host,
										 local_sip_port),
								     ts_UserInfo(user))),
						omit)
				})),
	cp := cp
}

private altstep as_Tguard() runs on 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_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." */
}

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.ipsec_remote_spi_c := str2int(par_val);
		par_val := f_sip_param_get_value_present_or_fail(sec_pars, "spi-s");
		g_pars.ipsec_remote_spi_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.ipsec_remote_spi_c, " remote_spi_s=", g_pars.ipsec_remote_spi_s,
	    "local_spi_c=", g_pars.ipsec_local_spi_c, " local_spi_s=", g_pars.ipsec_local_spi_s);
}

private function f_ims_setup_ipsec(PDU_SIP_Request req_req) runs on IMS_ConnHdlr
{
	var Security_client security_client := req_req.msgHeader.security_client;
	f_ims_parse_security_client(security_client);
}

/* 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_SipAddr(),
				tr_SipAddr(),
				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) SipAddr from_addr;
		var template (value) SipAddr 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) Supported supported := ts_Supported({"sec-agree"});
		var 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 := ts_SipAddr_from_Addr_Union(g_rx_sip_req.msgHeader.fromField.addressField,
							g_rx_sip_req.msgHeader.fromField.fromParams);
		to_addr := ts_SipAddr_from_Addr_Union(g_rx_sip_req.msgHeader.toField.addressField,
						      g_rx_sip_req.msgHeader.toField.toParams);
		sip_seq_nr := g_rx_sip_req.msgHeader.cSeq.seqNumber;

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

		/* TODO: Validate "Expires" is 600000 */
		/* TODO: validate presence of:
		 * Security-Client: ipsec-3gpp; alg=hmac-md5-96; ealg=des-ede3-cbc; spi-c=431842084; spi-s=650017092; port-c=41271; port-s=41718,ipsec-3gpp; alg=hmac-md5-96; ealg=aes-cbc; spi-c=431842084; spi-s=650017092; port-c=41271; port-s=41718,ipsec-3gpp; alg=hmac-md5-96; ealg=null; spi-c=431842084; spi-s=650017092; port-c=41271; port-s=41718,ipsec-3gpp; alg=hmac-sha-1-96; ealg=des-ede3-cbc; spi-c=431842084; spi-s=650017092; port-c=41271; port-s=41718,ipsec-3gpp; alg=hmac-sha-1-96; ealg=aes-cbc; spi-c=431842084; spi-s=650017092; port-c=41271; port-s=41718,ipsec-3gpp; alg=hmac-sha-1-96; ealg=null; spi-c=431842084; spi-s=650017092; port-c=41271; port-s=41718
		 */

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

		f_ims_setup_ipsec(g_rx_sip_req);

		to_addr.params := f_sip_param_set(to_addr.params, "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("FJh2MfZfjjeIoHmLbrzQjvbhmnzLAoAAoGsZyVRFFuU="))
			/* "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.ipsec_local_spi_c)),
			ts_Param("spi-s", int2str(g_pars.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
		 * TODO: with IMS params */
		tx_resp := ts_SIP_Response_Unauthorized(sip_call_id,
					from_addr,
					to_addr,
					via,
					wwwAuthenticate,
					sip_seq_nr,
					"REGISTER",
					security_server := security_server,
					server := server_name,
					supported := supported,
					userAgent := omit);
		SIP.send(tx_resp);

		/* TODO: Generate expected Authoritzation based on AKAv1-MD5: */
		/*authorization := f_sip_digest_gen_Authorization(valueof(wwwAuthenticate),
								g_pars.user, g_pars.password,
								"REGISTER",
								f_sip_SipUrl_to_str(g_pars.registrar_sip_record.addr.nameAddr.addrSpec))
		*/
		/* TODO: match Authorization from above: */
		exp_req :=
		tr_SIP_REGISTER(g_pars.registrar_sip_req_uri,
				?,
				tr_SipAddr(),
				tr_SipAddr(),
				tr_Via_from(?));
		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 := ts_SipAddr_from_Addr_Union(g_rx_sip_req.msgHeader.fromField.addressField,
							g_rx_sip_req.msgHeader.fromField.fromParams);
		to_addr := ts_SipAddr_from_Addr_Union(g_rx_sip_req.msgHeader.toField.addressField,
						      g_rx_sip_req.msgHeader.toField.toParams);
		to_addr.params := f_sip_param_set(to_addr.params, "tag", f_sip_rand_tag());
		sip_seq_nr := g_rx_sip_req.msgHeader.cSeq.seqNumber;

		/* TODO: Add following fields:
		 * Supported: sec-agree
		 * 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
		 * */

		tx_resp := ts_SIP_Response(sip_call_id,
			from_addr,
			to_addr,
			"REGISTER", 200,
			sip_seq_nr,
			"OK",
			via);
		SIP.send(tx_resp);
	}
	[fail_others] as_SIP_fail_resp(sip_expect_str);
	[fail_others] as_SIP_fail_req(sip_expect_str);

}

}
