module BSC_MS_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 MobileL3_Types all;
import from MobileL3_CommonIE_Types all;
import from L3_Templates all;

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

type function void_fn_bsc_ms(charstring id) runs on BSC_MS_ConnHdlr;

/* 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 BSC_MS_ConnHdlr extends RAN_ConnHdlr {
	/* SCCP Connecction Identifier for the underlying SCCP connection */
	var integer g_sccp_conn_id;
	var MgcpConnectionId g_mgcp_conn_id;
	var SDP_Message g_sdp;
	var BSC_State g_state;
	var BSC_MS_TestHdlrParams g_pars;
}

type record BSC_MS_TestHdlrParams {
	SCCP_PAR_Address sccp_addr_own,
	SCCP_PAR_Address sccp_addr_remote,
	boolean use_osmux
};

/* Callback function from general RAN_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 {
	log("Incoming SCCP Connection on BSC ?!?");
	self.stop;
}

/* Callback function from general RAN_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 BSC_MS_RanOps := {
	create_cb := refers(CreateCallback),
	unitdata_cb := refers(UnitdataCallback),
	decode_dtap := false,
	role_ms := true,
	protocol := RAN_PROTOCOL_BSSAP,
	transport := BSSAP_TRANSPORT_AoIP,
	use_osmux := false,
	sccp_addr_local := omit,
	sccp_addr_peer := omit
}


function f_gen_cl3(hexstring imsi) return PDU_BSSAP {
	var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(imsi));
	var PDU_ML3_MS_NW l3 := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
	var BSSMAP_IE_CellIdentifier cell_id := valueof(ts_CellID_LAC_CI(23, 42));
	var PDU_BSSAP bssap := valueof(ts_BSSMAP_ComplL3(cell_id, enc_PDU_ML3_MS_NW(l3)));
	return bssap;
}

type enumerated BSC_State {
	BSC_STATE_NONE,
	BSC_STATE_WAIT_ASS_REQ,
	BSC_STATE_WAIT_CRCX,
	BSC_STATE_WAIT_MDCX,
	BSC_STATE_WAIT_MDCX2,
	BSC_STATE_WAIT_CLEAR_CMD,
	BSC_STATE_WAIT_DLCX,
	BSC_STATE_WAIT_DISC_IND
}

/* main function processing various incoming events */
function bsc_ms_establish_fully(charstring id)
runs on BSC_MS_ConnHdlr {
	var PDU_BSSAP bssap;
	var MgcpCommand mgcp_cmd;
	var template MgcpResponse mgcp_resp;
	var MgcpOsmuxCID osmux_cid;

	log("Starting main of BSC_MS_ConnHdlr");

	g_mgcp_conn_id := f_mgcp_alloc_conn_id();

	/* generate and send the Complete Layer3 Info */
	bssap := f_gen_cl3('901770123456789'H);
	var BSSAP_Conn_Req creq := {
		addr_peer := g_pars.sccp_addr_remote,
		addr_own := g_pars.sccp_addr_own,
		bssap := bssap
	}
	g_state := BSC_STATE_WAIT_ASS_REQ;
	BSSAP.send(creq);

	while (true) {
		alt {
		/* new SCCP-level connection indication from BSC */
		[g_state == BSC_STATE_WAIT_ASS_REQ] BSSAP.receive(tr_BSSMAP_AssignmentReq) -> value bssap {
			/* FIXME: Read CIC */
			/* respond with ASSIGNMENT COMPL */
			g_state := BSC_STATE_WAIT_CRCX;
			BSSAP.send(ts_BSSMAP_AssignmentComplete(bssap.pdu.bssmap.assignmentRequest.circuitIdentityCode));
			}

		/* CRCX -> OK */
		[g_state == BSC_STATE_WAIT_CRCX] BSSAP.receive(tr_CRCX) -> value mgcp_cmd {
			/* FIXME: proper SDP parameters */
			g_sdp := valueof(ts_SDP("127.0.0.1", "127.0.0.1", "foo", "21", 1000, { "98" },
						{ valueof(ts_SDP_rtpmap(98, "AMR/8000")),
						  valueof(ts_SDP_ptime(20)) }));
			/* respond with CRCX_ACK */
			g_state := BSC_STATE_WAIT_MDCX;

			if (g_pars.use_osmux != f_MgcpCmd_contains_par(mgcp_cmd, "X-OSMUX")) {
				setverdict(fail, log2str("Received Osmux CID presence doesn't match presence expectancy (", g_pars.use_osmux, ")"));
				self.stop;
			}

			if (g_pars.use_osmux) {
				osmux_cid := f_MgcpCmd_extract_osmux_cid(mgcp_cmd);
				mgcp_resp := ts_CRCX_ACK_osmux(mgcp_cmd.line.trans_id, g_mgcp_conn_id, osmux_cid, g_sdp);
			} else {
				mgcp_resp := ts_CRCX_ACK(mgcp_cmd.line.trans_id, g_mgcp_conn_id, g_sdp);
			}
			BSSAP.send(valueof(mgcp_resp));
			}

		/* MDCX -> OK */
		[g_state == BSC_STATE_WAIT_MDCX] BSSAP.receive(tr_MDCX) -> value mgcp_cmd {
			/* FIXME: verify if local part of endpoint name matches CIC */
			/* respond with MDCX_ACK */
			g_state := BSC_STATE_WAIT_MDCX2;
			BSSAP.send(ts_MDCX_ACK(mgcp_cmd.line.trans_id, g_mgcp_conn_id, g_sdp));
			}

		/* MDCX -> OK */
		[g_state == BSC_STATE_WAIT_MDCX2] BSSAP.receive(tr_MDCX) -> value mgcp_cmd {
			/* FIXME: verify if local part of endpoint name matches CIC */
			/* respond with MDCX_ACK */
			g_state := BSC_STATE_WAIT_CLEAR_CMD;
			BSSAP.send(ts_MDCX_ACK(mgcp_cmd.line.trans_id, g_mgcp_conn_id, g_sdp));
			}

		/* CLEAR COMMAND from MSC; respond with CLEAR COMPLETE) */
		[g_state == BSC_STATE_WAIT_CLEAR_CMD] BSSAP.receive(tr_BSSMAP_ClearCommand) -> value bssap {
			g_state := BSC_STATE_WAIT_DLCX;
			BSSAP.send(ts_BSSMAP_ClearComplete);
			}

		/* DLCX -> OK */
		[g_state == BSC_STATE_WAIT_DLCX] BSSAP.receive(tr_DLCX) -> value mgcp_cmd {
			/* FIXME: verify if local part of endpoint name matches CIC */
			g_state := BSC_STATE_WAIT_DISC_IND;
			BSSAP.send(ts_DLCX_ACK(mgcp_cmd.line.trans_id, g_mgcp_conn_id));
			}

		[] BSSAP.receive(tr_BSSAP_DTAP) -> value bssap {
			/* FIXME: verify if local part of endpoint name matches CIC */
			var PDU_ML3_MS_NW l3 := dec_PDU_ML3_MS_NW(bssap.pdu.dtap);
			log("Unhandled DTAP ", l3);
			}

		[g_state == BSC_STATE_WAIT_DISC_IND] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
			setverdict(pass);
			self.stop;
			}

		[] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) {
			}

		/* disconnect in invalid state */
		[] 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);
			}
		}
	}
}

function bsc_ms_do_nothing(charstring id)
runs on BSC_MS_ConnHdlr {
}

}
