module MSC_ConnectionHandler {

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 BSSMAP_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 BSSAP_ConnHdlr components.
 * We inherit all component variables, ports, functions, ... from BSSAP_ConnHdlr */
type component MSC_ConnHdlr extends BSSAP_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 BSSMAP_Emulation_CT return BSSAP_ConnHdlr {
	var MSC_ConnHdlr vc_conn;
	/* Create a new BSSAP_ConnHdlr component */
	vc_conn := MSC_ConnHdlr.create(g_bssmap_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 BSSMAP_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 BssmapOps MSC_BssmapOps := {
	create_cb := refers(CreateCallback),
	unitdata_cb := refers(UnitdataCallback),
	decode_dtap := false,
	role_ms := false
}

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(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
			setverdict(pass);
			self.stop;
			}

		/* TODO: CLEAR REQUEST from BSS */

		[] BSSAP.receive(BSSAP_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(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
			setverdict(inconc);
			self.stop;
			}

		}
	}
}

}
