module HNBGW_ConnectionHandler {

/* HNBGW Connection Handler of HNB_Tests in TTCN-3
 * (C) 2021 by sysmocom - s.f.m.c. GmbH <info@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
 */

import from Misc_Helpers all;
import from General_Types all;
import from Osmocom_Types all;
import from IPL4asp_Types all;
import from Native_Functions all;

import from SDP_Types all;

import from StatsD_Checker all;

import from TELNETasp_PortType all;
import from Osmocom_VTY_Functions all;

import from HNBAP_Templates all;

import from Iuh_Emulation all;

import from RTP_Types all;
import from RTP_Emulation all;

import from HNBLLIF_CodecPort all;
import from HNBLLIF_Types all;
import from HNBLLIF_Templates all;

import from GTP_Emulation all;
import from GTPv1U_Templates all;
import from GTPv1U_CodecPort all;
import from GTPU_Types all;

/* this component represents a single Iuh connection at the HNBGW. */
type component HNBGW_ConnHdlr extends Iuh_ConnHdlr, GTP_ConnHdlr, StatsD_ConnHdlr {
	port TELNETasp_PT HNBVTY;
	/* HNBLLIF Interface of HNodeB */
	port HNBLLIF_CODEC_PT LLSK;
	var integer g_llsk_conn_id;

	var RTP_Emulation_CT vc_RTPEM;
	port RTPEM_CTRL_PT RTPEM_CTRL;
	port RTPEM_DATA_PT RTPEM_DATA;

	var GTP_Emulation_CT vc_GTP;


	var TestHdlrParams g_pars;

	var boolean g_vty_initialized := false;
}

function f_HNBGW_ConnHdlr_init_vty() runs on HNBGW_ConnHdlr {
	if (not g_vty_initialized) {
		map(self:HNBVTY, system:HNBVTY);
		f_vty_set_prompts(HNBVTY);
		f_vty_transceive(HNBVTY, "enable");
		g_vty_initialized := true;
	}
}

private function f_HNBGW_ConnHdlr_init_iuh(charstring id) runs on HNBGW_ConnHdlr {
	var Iuh_Emulation_CT vc_Iuh;
	vc_Iuh := Iuh_Emulation_CT.create(id & "-HNBGW") alive;
	connect(self:HNBAP, vc_Iuh:HNBAP);
	connect(self:RUA, vc_Iuh:RUA);

	var Iuh_conn_parameters iuh_pars;
	iuh_pars.remote_ip := g_pars.hnodeb_addr;
	iuh_pars.remote_sctp_port := -1;
	iuh_pars.local_ip := g_pars.hnbgw_addr;
	iuh_pars.local_sctp_port  := g_pars.hnbgw_port;
	vc_Iuh.start(Iuh_Emulation.main(iuh_pars, id & "-Iuh"));
}

private function f_HNBGW_ConnHdlr_init_gtp(charstring id) runs on HNBGW_ConnHdlr {
	id := id & "-GTP";

	var GtpEmulationCfg gtp_cfg := {
		gtpc_bind_ip := g_pars.hnbgw_addr,
		gtpc_bind_port := GTP1C_PORT,
		gtpu_bind_ip :=  g_pars.hnbgw_addr,
		gtpu_bind_port := GTP1U_PORT,
		sgsn_role := false
	};

	vc_GTP := GTP_Emulation_CT.create(id) alive;
	connect(self:GTP, vc_GTP:CLIENT);
	connect(self:GTP_PROC, vc_GTP:CLIENT_PROC);
	vc_GTP.start(GTP_Emulation.main(gtp_cfg));
}

/* initialize all parameters */
function f_HNBGW_ConnHdlr_init(charstring id, TestHdlrParams pars) runs on HNBGW_ConnHdlr {
	g_pars := valueof(pars);
	f_HNBGW_ConnHdlr_init_iuh(id);
	f_HNBGW_ConnHdlr_init_gtp(id);
	f_HNBGW_ConnHdlr_init_vty();

	/* Connect to HNB on LLSK and do HELLO ping-pong  */
	f_start_hnbllif(LLSK, id & "-LLSK", g_pars,  g_llsk_conn_id);
}


function f_start_hnbllif(HNBLLIF_CODEC_PT pt, charstring id, TestHdlrParams pars,
		out integer hnbllif_conn_id) {
	timer T := 2.0;
	var HNBLLIF_send_data sd;
	var HNBLLIF_Message last_hello_cnf;
	if (pars.hnbllif_sk_path == "") {
		hnbllif_conn_id := -1;
		return;
	}
	hnbllif_conn_id := f_hnbllif_connect(pt, pars.hnbllif_sk_path);

	T.start;
	pt.send(t_SD_HNBLLIF(hnbllif_conn_id, ts_HNBLLIF_CTL_HELLO_REQ(HNBLL_IF_SAPI_CTL, HNBLLIF_Types.mp_hnbllif_version)));
	alt {
	[] as_hnbllif_hello_cnf(pt, hnbllif_conn_id, last_hello_cnf, HNBLL_IF_SAPI_CTL, HNBLLIF_Types.mp_hnbllif_version);
	[] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for HNBLLIF HELLO.REQ SAPI=CTL");
		}
	}
	pt.send(t_SD_HNBLLIF(hnbllif_conn_id, ts_HNBLLIF_CTL_HELLO_REQ(HNBLL_IF_SAPI_IUH, pars.hnbllif_sapi_iuh_version)));
	alt {
	[] as_hnbllif_hello_cnf(pt, hnbllif_conn_id, last_hello_cnf, HNBLL_IF_SAPI_IUH, pars.hnbllif_sapi_iuh_version);
	[] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for HNBLLIF HELLO.REQ SAPI=IUH");
		}
	}
	pt.send(t_SD_HNBLLIF(hnbllif_conn_id, ts_HNBLLIF_CTL_HELLO_REQ(HNBLL_IF_SAPI_AUDIO, pars.hnbllif_sapi_audio_version)));
	alt {
	[] as_hnbllif_hello_cnf(pt, hnbllif_conn_id, last_hello_cnf, HNBLL_IF_SAPI_AUDIO, pars.hnbllif_sapi_audio_version);
	[] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for HNBLLIF HELLO.REQ SAPI=AUDIO");
		}
	}
	pt.send(t_SD_HNBLLIF(hnbllif_conn_id, ts_HNBLLIF_CTL_HELLO_REQ(HNBLL_IF_SAPI_GTP, pars.hnbllif_sapi_gtp_version)));
	alt {
	[] as_hnbllif_hello_cnf(pt, hnbllif_conn_id, last_hello_cnf, HNBLL_IF_SAPI_GTP, pars.hnbllif_sapi_gtp_version);
	[] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for HNBLLIF HELLO.REQ SAPI=GTP");
		}
	}
}

type record TestHdlrParams {
	charstring hnbllif_sk_path, /* "" means don't connect */
	uint16_t hnbllif_sapi_iuh_version,
	uint16_t hnbllif_sapi_gtp_version,
	uint16_t hnbllif_sapi_audio_version,
	charstring hnbgw_addr,
	charstring hnodeb_addr,
	integer hnbgw_port,
	integer hnbgw_rtp_port,
	uint16_t rnc_id,
	charstring hNB_Identity_Info,
	uint16_t mcc,
	uint16_t mnc,
	uint32_t cell_identity,
	uint16_t lac,
	uint8_t rac,
	uint8_t sac
};

/* Note: Do not use valueof() to get a value of this template, use
 * f_gen_test_hdlr_pars() instead in order to get a configuration. */
template (value) TestHdlrParams t_def_TestHdlrPars := {
	hnbllif_sk_path := HNBLL_SOCK_DEFAULT,
	hnbllif_sapi_iuh_version := 0,
	hnbllif_sapi_gtp_version := 0,
	hnbllif_sapi_audio_version := 1,
	hnbgw_addr := "127.0.0.1",
	hnodeb_addr := "127.0.0.1",
	hnbgw_port := 29169,
	hnbgw_rtp_port := 9000,
	rnc_id := 23,
	hNB_Identity_Info := "OsmoHNodeB",
	mcc := 1,
	mnc := 1,
	cell_identity := 1,
	lac := 2,
	rac := 3,
	sac := 4
}

template (value) Gtp1uPeer ts_GtpPeerU(charstring ip) := {
	connId := 1,
	remName := ip,
	remPort := GTP1U_PORT
}

function f_gtpu_send(uint32_t tei, octetstring payload) runs on HNBGW_ConnHdlr {
	var Gtp1uPeer peer := valueof(ts_GtpPeerU(g_pars.hnodeb_addr));
	GTP.send(ts_GTP1U_GPDU(peer, 0 /*seq*/, int2oct(tei, 4),  payload));
}

/* HNBLLIF socket may at any time receive a new INFO.ind */
altstep as_hnbllif_hello_cnf(HNBLLIF_CODEC_PT pt, integer hnbllif_conn_id,
				out HNBLLIF_Message last_hello_cnf,
				template (present) HNBLLIF_Sapi exp_sapi := ?,
				template (present) uint16_t exp_version := ?) {
	var HNBLLIF_send_data sd;
	[] pt.receive(t_SD_HNBLLIF(hnbllif_conn_id, tr_HNBLLIF_CTL_HELLO_CNF(exp_sapi, exp_version))) -> value sd {
		last_hello_cnf := sd.data;
		}
	[] pt.receive(t_SD_HNBLLIF(hnbllif_conn_id, tr_HNBLLIF_CTL_HELLO_CNF(?))) -> value sd {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Invalid API_VERSION received");
		}
}

function f_llsk_rx(template (present) HNBLLIF_Message exp_tmpl) runs on HNBGW_ConnHdlr
return template (present) HNBLLIF_send_data {
	return t_SD_HNBLLIF(g_llsk_conn_id, exp_tmpl);
}

function f_llsk_tx(template (value) HNBLLIF_Message tx_msg) runs on HNBGW_ConnHdlr
return template (value) HNBLLIF_send_data {
	return ts_SD_HNBLLIF(g_llsk_conn_id, tx_msg);
}

function f_enc_mcc_mnc(uint16_t mcc_uint, uint16_t mnc_uint) return OCT3 {
	var hexstring mnc;
	var hexstring mcc := int2hex(mcc_uint, 3);

	if (mnc_uint < 100) {
		mnc := int2hex(mnc_uint, 2);
		return hex2oct(mcc[1] & mcc[0] & 'F'H & mcc[2] & mnc[1] & mnc[0]);
	} else {
		mnc := int2hex(mnc_uint, 3);
		return hex2oct(mcc[1] & mcc[0] & mnc[2] & mcc[2] & mnc[1] & mnc[0]);
	}
}

function f_handle_hnbap_hnb_register_req()
runs on HNBGW_ConnHdlr {
	HNBAP.receive(tr_HNBAP_HNBRegisterRequest(char2oct(g_pars.hNB_Identity_Info),
						  f_enc_mcc_mnc(g_pars.mcc, g_pars.mnc),
						  int2bit(g_pars.cell_identity, 28),
						  int2oct(g_pars.lac, 2),
						  int2oct(g_pars.rac, 1),
						  int2oct(g_pars.sac, 2)
						 ));
	HNBAP.send(ts_HNBAP_HNBRegisterAccept(g_pars.rnc_id));
}

/* Initialize and start the RTP emulation component for a ConnHdlr */
function f_HNBGW_rtpem_activate(inout octetstring payload)
runs on HNBGW_ConnHdlr {
	/* Initialize, connect and start the emulation component */
	var RtpemConfig cfg := c_RtpemDefaultCfg;
	cfg.iuup_mode := true;
	cfg.iuup_cfg.active_init := false;
	cfg.tx_payloads[0].payload_type := 96;
	cfg.rx_payloads[0].payload_type := 96;

	vc_RTPEM := RTP_Emulation_CT.create(testcasename() & "-RTPEM") alive;
	map(vc_RTPEM:RTP, system:RTP);
	map(vc_RTPEM:RTCP, system:RTCP);
	connect(vc_RTPEM:CTRL, self:RTPEM_CTRL);
	connect(vc_RTPEM:DATA, self:RTPEM_DATA);
	vc_RTPEM.start(RTP_Emulation.f_main());

	/* Configure the RTP parameters (TCH/FS). TODO: IuUP */
	var integer payload_len := 33;
	var octetstring hdr := 'D0'O;

	/* Pad the payload to conform the expected length */
	payload := f_pad_oct(hdr & payload, payload_len, '00'O);
	cfg.tx_payloads[0].fixed_payload := payload;
	f_rtpem_configure(RTPEM_CTRL, cfg);

	/* Bind the RTP emulation to the configured address */
	f_rtpem_bind(RTPEM_CTRL, g_pars.hnbgw_addr, g_pars.hnbgw_rtp_port);

	/* Set the given RTP emulation mode */
	f_rtpem_mode(RTPEM_CTRL, RTPEM_MODE_RXONLY);
}

function f_HNBGW_rtpem_connect(HostName remote_host, PortNumber remote_port)
runs on HNBGW_ConnHdlr {
	f_rtpem_connect(RTPEM_CTRL, remote_host, remote_port);
	/* Set the given RTP emulation mode */
	f_rtpem_mode(RTPEM_CTRL, RTPEM_MODE_BIDIR);
}

}
