module HNBGW_ConnectionHandler {

/* HNBGW Connection Handler of HNB_Tests in TTCN-3
 * (C) 2021 by sysmocom - s.m.f.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 GTP_Templates all;
import from GTP_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) GtpPeer 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 GtpPeer 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_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_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);
}

}
