module BSC_MS_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 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;

/* 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 BSC_MS_ConnHdlr extends BSSAP_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;
}

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

/* 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 BSC_MS_BssmapOps := {
	create_cb := refers(CreateCallback),
	unitdata_cb := refers(UnitdataCallback)
}


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('0001'B, 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 main(SCCP_PAR_Address sccp_addr_own, SCCP_PAR_Address sccp_addr_remote)
runs on BSC_MS_ConnHdlr {
	var PDU_BSSAP bssap;
	var MgcpCommand mgcp_cmd;
	var MgcpResponse mgcp_resp;

	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 := sccp_addr_remote,
		addr_own := 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;
			BSSAP.send(ts_CRCX_ACK(mgcp_cmd.line.trans_id, g_mgcp_conn_id, g_sdp));
			}

		/* 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(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
			setverdict(pass);
			self.stop;
			}

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

}
