module MSC_ConnectionHandler {

/* (C) 2017-2019 Harald Welte <laforge@gnumonks.org>
 * 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 General_Types all;
import from Osmocom_Types all;
import from SCCPasp_Types all;
import from BSSAP_Types all;
import from BSSAP_CodecPort all;
import from RAN_Emulation all;
import from BSSMAP_Templates all;

import from MGCP_Types all;
import from MGCP_Templates all;
import from SDP_Types all;

/* this component represents a single subscriber connection at the MSC.
 * There is a 1:1 mapping between SCCP connections and RAN_ConnHdlr components.
 * We inherit all component variables, ports, functions, ... from RAN_ConnHdlr */
type component MSC_ConnHdlr extends RAN_ConnHdlr {
	/* SCCP Connecction Identifier for the underlying SCCP connection */
	var integer g_sccp_conn_id;

	var MSC_State g_state := MSC_STATE_NONE;
	var MgcpEndpoint g_ep_name;
	var MgcpCallId g_call_id;
	var MgcpConnectionId g_mgcp_conn_id;
}

/* Callback function from general BSSMAP_Emulation whenever a new incoming
 * SCCP connection arrivces. Must create + start a new component */
private function CreateCallback(BSSAP_N_CONNECT_ind conn_ind, charstring id)
runs on RAN_Emulation_CT return RAN_ConnHdlr {
	var MSC_ConnHdlr vc_conn;
	/* Create a new RAN_ConnHdlr component */
	vc_conn := MSC_ConnHdlr.create(g_ran_id & "-Conn-" & int2str(conn_ind.connectionId));
	/* connect it to the port */
	connect(vc_conn:BSSAP, self:CLIENT);
	/* start it */
	vc_conn.start(MSC_ConnectionHandler.main(conn_ind.connectionId, g_next_e1_ts));
	/* increment next E1 timeslot */
	g_next_e1_ts := g_next_e1_ts + 1;
	return vc_conn;
}

/* Callback function from general BSSMAP_Emulation whenever a connectionless
 * BSSMAP message arrives.  Can retunr a PDU_BSSAP that should be sent in return */
private function UnitdataCallback(PDU_BSSAP bssap)
runs on RAN_Emulation_CT return template PDU_BSSAP {
	var template PDU_BSSAP resp := omit;

	if (match(bssap, tr_BSSMAP_Reset)) {
		resp := ts_BSSMAP_ResetAck;
	}

	return resp;
}

const RanOps MSC_RanOps := {
	create_cb := refers(CreateCallback),
	unitdata_cb := refers(UnitdataCallback),
	decode_dtap := false,
	role_ms := false,
	protocol := RAN_PROTOCOL_BSSAP,
	use_osmux := false,
	sccp_addr_local := omit,
	sccp_addr_peer := omit
}

type enumerated MSC_State {
	MSC_STATE_NONE,
	MSC_STATE_WAIT_ASS_COMPL,
	MSC_STATE_WAIT_CRCX_ACK,
	MSC_STATE_WAIT_MDCX_ACK,
	MSC_STATE_WAIT_CLEAR_COMPL,
	MSC_STATE_WAIT_DLCX_ACK
}

/* main function processing various incoming events */
function main(integer connection_id, integer e1_timeslot) runs on MSC_ConnHdlr {
	var MgcpResponse mgcp_rsp;
	timer T := 5.0;

	g_sccp_conn_id := connection_id;
	g_call_id := f_mgcp_alloc_call_id();
	g_ep_name := hex2str(int2hex(e1_timeslot, 1)) & "@mgw";

	/* we just accepted an incoming SCCP connection, start guard timer */
	T.start;

	while (true) {
		var PDU_BSSAP bssap;
		alt {
		/* new SCCP-level connection indication from BSC */
		[g_state == MSC_STATE_NONE] BSSAP.receive(tr_BSSMAP_ComplL3) -> value bssap {
			/* respond with ASSIGNMENT CMD  */
			g_state := MSC_STATE_WAIT_ASS_COMPL;
			BSSAP.send(ts_BSSMAP_AssignmentReq(ts_BSSMAP_IE_CIC(0, e1_timeslot)));
			}
		[g_state == MSC_STATE_WAIT_ASS_COMPL] BSSAP.receive(tr_BSSMAP_AssignmentComplete(?,*)) {
			/* FIXME: Send MGCP CRCX */
			g_state := MSC_STATE_WAIT_CRCX_ACK;
			var MgcpTransId trans_id := f_mgcp_alloc_tid();
			//template SDP_Message sdp := omit;
			BSSAP.send(ts_CRCX(trans_id, g_ep_name, "recvonly", g_call_id)); //, sdp));
			}
		/*
		[] BSSAP.receive(tr_BSSMAP_AssignmentFail) {
		}
		*/

		/* receive CRCX ACK: transmit MDCX */
		[g_state == MSC_STATE_WAIT_CRCX_ACK] BSSAP.receive(tr_CRCX_ACK) -> value mgcp_rsp {
			/* extract connection ID */
			g_mgcp_conn_id := f_MgcpResp_extract_conn_id(mgcp_rsp);
			g_state := MSC_STATE_WAIT_MDCX_ACK;
			var MgcpTransId trans_id := f_mgcp_alloc_tid();
			BSSAP.send(ts_MDCX(trans_id, g_ep_name, "sendrecv", g_call_id, g_mgcp_conn_id));
			}

		/* receive MDCX ACK: wait + transmit CLEAR COMMAND */
		[g_state == MSC_STATE_WAIT_MDCX_ACK] BSSAP.receive(tr_CRCX_ACK) -> value mgcp_rsp {
			g_state := MSC_STATE_WAIT_CLEAR_COMPL
			BSSAP.send(ts_BSSMAP_ClearCommand(9)); /* Cause: call control */
			}

		/* CLEAR COMPLETE from BSS (response to CLEAR COMMAND) */
		[g_state == MSC_STATE_WAIT_CLEAR_COMPL] BSSAP.receive(tr_BSSMAP_ClearComplete) {
			/* send DLCX */
			g_state := MSC_STATE_WAIT_DLCX_ACK;
			var MgcpTransId trans_id := f_mgcp_alloc_tid();
			BSSAP.send(ts_DLCX(trans_id, g_ep_name, g_call_id));
			}

		[g_state == MSC_STATE_WAIT_DLCX_ACK] BSSAP.receive(tr_DLCX_ACK) {
			BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
			setverdict(pass);
			self.stop;
			}

		/* TODO: CLEAR REQUEST from BSS */

		[] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
			setverdict(fail);
			self.stop;
			}

		[] BSSAP.receive(PDU_BSSAP:?) -> value bssap {
			log("Received unhandled SCCP-CO: ", bssap);
			}

		/* Guard timer has expired, close connection */
		[] T.timeout {
			BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
			setverdict(fail, "Timeout of guard timer");
			self.stop;
			}

		}
	}
}

}
