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),
	decode_dtap := false,
	role_ms := true
}


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);
			}
		}
	}
}

}
