/* MME (SBc-AP) Connection Handler of CBC test suite in TTCN-3
 * (C) 2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
 * All rights reserved.
 *
 * Author: Pau Espin Pedrol <pespin@sysmocom.de>
 *
 * 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 MME_ConnectionHandler {

import from SBC_AP_IEs all;
import from SBC_AP_Constants all;
import from SBC_AP_PDU_Contents all;
import from SBC_AP_PDU_Descriptions all;
import from SBC_AP_Types all;
import from SBC_AP_Templates all;
import from SBC_AP_CodecPort all;
import from SBC_AP_Adapter all;

import from CBS_Message all;

type function void_fn() runs on MME_ConnHdlr;

/* Coordinate with test_CT: */
type port MME_ConnHdlr_Coord_PT message {
	inout charstring;
} with { extension "internal" };

/* this component represents a single subscriber connection */
type component MME_ConnHdlr extends SBC_AP_Adapter_CT {
	var MME_ConnHdlrPars g_pars;
	port MME_ConnHdlr_Coord_PT COORD;
}

type record MME_ConnHdlrPars {
	charstring mme_host,
	integer mme_sbcap_port,
	charstring cbc_host,
	integer cbc_sbcap_port,
	boolean sctp_is_client,
	void_fn start_fn,
	CBS_Message exp_cbs_msg optional,
	SBC_AP_Cause write_replace_warning_ind_cause optional,
	List_of_TAIs write_repl_unknown_TAIs optional,
	CellId_Broadcast_List bcast_cell_id_list optional
};

function f_MME_ConnHdlr_main(charstring id, MME_ConnHdlrPars pars) runs on MME_ConnHdlr {
	g_pars := pars;
	if (g_pars.sctp_is_client) {
		SBC_AP_Adapter.f_connect(g_pars.cbc_host, g_pars.cbc_sbcap_port,
					 g_pars.mme_host, g_pars.mme_sbcap_port);
	} else {
		SBC_AP_Adapter.f_bind(g_pars.mme_host, g_pars.mme_sbcap_port);
		SBC_AP_Adapter.f_wait_client_connect();
	}
	COORD.send(COORD_MSG_CONNECTED);
	g_pars.start_fn.apply();
}

function f_sbcap_tx_write_replace_warn_resp(CBS_Message msg, integer idx := 0)
runs on MME_ConnHdlr {
	var template (value) SBC_AP_PDU tx;
	if (ispresent(g_pars.write_repl_unknown_TAIs)) {
		tx := ts_SBCAP_WRITE_WARNING_RESP_UNKNOWN_TAI(
						int2bit(msg.msg_id, 16),
						int2bit(msg.ser_nr, 16),
						SBC_AP_Cause_message_accepted,
						g_pars.write_repl_unknown_TAIs);
	} else {
		tx := ts_SBCAP_WRITE_WARNING_RESP(int2bit(msg.msg_id, 16),
						  int2bit(msg.ser_nr, 16));
	}
	f_SBC_AP_send(tx, idx);
}

function f_sbcap_tx_write_replace_warn_ind(integer idx := 0, CBS_Message msg,
					   SBC_AP_Cause cause,
					   template (value) CellId_Broadcast_List bcast_cell_id_li)
runs on MME_ConnHdlr {
	var template (value) SBC_AP_PDU tx;
	tx := ts_SBCAP_WRITE_WARNING_IND(int2bit(msg.msg_id, 16),
					 int2bit(msg.ser_nr, 16),
					 cause, bcast_cell_id_li);
	f_SBC_AP_send(tx, idx);
}

function f_sbcap_tx_stop_warn_resp(integer idx := 0, CBS_Message msg)
runs on MME_ConnHdlr {
	var template (value) SBC_AP_PDU tx;
	tx := ts_SBCAP_STOP_WARNING_RESP(int2bit(msg.msg_id, 16),
					  int2bit(msg.ser_nr, 16));
	f_SBC_AP_send(tx, idx);
}

/* handle a SBc-AP Write-Replace Request and respond to it with Response or FAILURE depending on arguments */
function f_sbcap_handle_write_replace_warn_req(CBS_Message msg, integer idx := 0)
runs on MME_ConnHdlr {
	var template (present) SBC_AP_PDU rx_templ;
	var SBC_AP_RecvFrom rf;
	rx_templ := tr_SBCAP_WRITE_WARNING(int2bit(msg.msg_id, 16),
					   int2bit(msg.ser_nr, 16),
					   msg.rep_period,
					   msg.num_bcast_req);
	alt {
	[] SBC_AP[idx].receive(tr_SBC_AP_Recv(g_SBC_AP_conn_id[idx], rx_templ)) -> value rf {
		log ("received expected req:", rf);
		f_sbcap_tx_write_replace_warn_resp(msg, idx);
		}
	[] SBC_AP[idx].receive {
		setverdict(fail, "Received unexpected SBc-AP in index ", idx);
		}
	}
}

/* handle a SBc-AP Stop-Warning-Request and respond to it with Response or FAILURE depending on arguments */
function f_sbcap_handle_stop_warn_req(integer idx := 0, CBS_Message msg)
runs on MME_ConnHdlr {
	var template (present) SBC_AP_PDU rx_templ;
	var SBC_AP_RecvFrom rf;

	rx_templ := tr_SBCAP_STOP_WARNING(int2bit(msg.msg_id, 16),
					  int2bit(msg.ser_nr, 16));
	alt {
	[] SBC_AP[idx].receive(tr_SBC_AP_Recv(g_SBC_AP_conn_id[idx], rx_templ)) -> value rf {
		log ("received expected req:", rf);
		f_sbcap_tx_stop_warn_resp(idx, msg);
		}
	[] SBC_AP[idx].receive {
		setverdict(fail, "Received unexpected SBc-AP in index ", idx);
		}
	}
}

}
