module BSC_ConnectionHandler {

import from General_Types all;
import from Osmocom_Types all;
import from Native_Functions all;
import from GSM_Types all;
import from IPL4asp_Types all;
import from SCCPasp_Types all;
import from BSSAP_Types all;
import from BSSMAP_Emulation all;
import from BSSMAP_Templates all;

import from GSUP_Types all;
import from GSUP_Emulation all;

import from MNCC_Types all;
import from MNCC_Emulation all;

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

import from MobileL3_Types all;
import from MobileL3_CommonIE_Types all;
import from MobileL3_MM_Types all;
import from MobileL3_CC_Types all;
import from L3_Templates all;

/* this component represents a single subscriber connection */
type component BSC_ConnHdlr extends BSSAP_ConnHdlr, MNCC_ConnHdlr, GSUP_ConnHdlr, MGCP_ConnHdlr {
	var BSC_ConnHdlrPars g_pars;
}

type record AuthVector {
	OCT16 rand,
	OCT4 sres,
	OCT8 kc
	/* FIXME: 3G elements */
}

type record BSC_ConnHdlrPars {
	SCCP_PAR_Address sccp_addr_own,
	SCCP_PAR_Address sccp_addr_peer,
	BSSMAP_IE_CellIdentifier cell_id,
	hexstring imei,
	hexstring imsi,
	hexstring msisdn,
	OCT4 tmsi optional,
	BSSMAP_IE_ClassmarkInformationType2 cm2,
	BSSMAP_IE_ClassmarkInformationType3 cm3 optional,
	AuthVector vec optional
};


/* Callback function from general BSSMAP_Emulation whenever a connectionless
 * BSSMAP message arrives. Canreturn a PDU_BSSAPthat should be sent in return */
private function BscUnitdataCallback(PDU_BSSAP bssap)
runs on BSSMAP_Emulation_CT return template PDU_BSSAP {
	var template PDU_BSSAP resp := omit;

	log("BSSMAP_BscUnitdataCallback");
	/* answer all RESET with RESET ACK */
	if (match(bssap, tr_BSSMAP_Reset)){
		log("BSSMAP_BscUnitdataCallback: Responding to RESET with RESET-ACK");
		resp := ts_BSSMAP_ResetAck;
	}

	/* FIXME: Handle paging, etc. */
	return resp;
}

const BssmapOps BSC_BssmapOps := {
	/* Create call-back for inbound connections from MSC (hand-over) */
	create_cb := refers(BSSMAP_Emulation.ExpectedCreateCallback),
	unitdata_cb := refers(BscUnitdataCallback),
	decode_dtap := true,
	role_ms := true
}


private function MnccUnitdataCallback(MNCC_PDU mncc)
runs on MNCC_Emulation_CT return template MNCC_PDU {
	log("Ignoring MNCC", mncc);
	return omit;
}

const MnccOps BCC_MnccOps := {
	create_cb := refers(MNCC_Emulation.ExpectedCreateCallback),
	unitdata_cb := refers(MnccUnitdataCallback)
}



template BSSAP_Conn_Req ts_BSSAP_Conn_Req(SCCP_PAR_Address peer, SCCP_PAR_Address own, PDU_BSSAP bssap) := {
	addr_peer := peer,
	addr_own := own,
	bssap := bssap
};

/* Encode 'l3' and ask BSSMAP_Emulation to create new connection with COMPL L3 INFO */
function f_bssap_compl_l3(PDU_ML3_MS_NW l3)
runs on BSC_ConnHdlr {
	log("Sending COMPL L3: ", l3);
	var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3);
	BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_own,
				     valueof(ts_BSSMAP_ComplL3(g_pars.cell_id, l3_enc))));
	alt {
	[] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_CONF_IND) {}
	[] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
			setverdict(fail, "DISC.ind from SCCP");
			self.stop;
		}
	}
}

/* helper function to fully establish a dedicated channel */
function f_establish_fully(MobileIdentityLV mi, boolean expect_auth, boolean expect_ciph)
runs on BSC_ConnHdlr {
	var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
	var PDU_DTAP_MT dtap_mt;

	/* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
	f_bssap_compl_l3(l3_info);

	f_mm_common(expect_auth, expect_ciph);
	if (expect_ciph) {
		/* implicit CM SERVICE ACCEPT? */
	} else {
		/* explicit CM SERVICE ACCEPT */
		BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_ACC));
	}
}

/* build a PDU_ML3_MS_NW containing a Location Update by IMSI */
function f_build_lu_imsi(hexstring imsi) return PDU_ML3_MS_NW
{
	var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(imsi));
	return f_build_lu(mi);
}
function f_build_lu_imei(hexstring imei) return PDU_ML3_MS_NW
{
	var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(imei));
	return f_build_lu(mi);
}
function f_build_lu_tmsi(OCT4 tmsi) return PDU_ML3_MS_NW
{
	var MobileIdentityLV mi := valueof(ts_MI_TMSI_LV(tmsi));
	return f_build_lu(mi);
}
private function f_build_lu(MobileIdentityLV mi) return PDU_ML3_MS_NW
{
	var LocationAreaIdentification_V old_lai := { '62F220'O, '9999'O };
	var PDU_ML3_MS_NW l3_info := valueof(ts_ML3_MO_LU_Req(valueof(ts_ML3_IE_LuType_Attach),
							      old_lai, mi, valueof(ts_CM1)));
	return l3_info;
}

private function f_rnd_oct(integer len) return octetstring {
	var integer i;
	var octetstring res;
	for (i := 0; i < len; i := i + 1) {
		res[i] := int2oct(float2int(rnd()*256.0), 1);
	}
	return res;
}

function f_gen_auth_vec_2g() return AuthVector {
	var AuthVector vec;
	vec.rand := f_rnd_oct(16);
	vec.sres := f_rnd_oct(4);
	vec.kc := f_rnd_oct(8);
	return vec;
}


function f_mm_common(boolean expect_auth, boolean expect_ciph) runs on BSC_ConnHdlr
{
	if (expect_auth) {
		g_pars.vec := f_gen_auth_vec_2g();
		var GSUP_IE auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
									 g_pars.vec.sres,
									 g_pars.vec.kc));
		GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi));
		GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));

		BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_AUTH_REQ(g_pars.vec.rand)));
		BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MT_MM_AUTH_RESP_2G(g_pars.vec.sres)));
	}

	if (expect_ciph) {
		BSSAP.receive(tr_BSSMAP_CipherModeCmd(?, g_pars.vec.kc));
		BSSAP.send(ts_BSSMAP_CipherModeCompl('02'O));
	}
}

function f_perform_lu(boolean expect_auth, boolean expect_tmsi, boolean send_early_cm,
		      boolean expect_ciph := false)
runs on BSC_ConnHdlr {
	var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
	var PDU_DTAP_MT dtap_mt;

	/* tell GSUP dispatcher to send this IMSI to us */
	f_create_gsup_expect(hex2str(g_pars.imsi));

	/* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
	f_bssap_compl_l3(l3_lu);

	if (send_early_cm) {
		BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
	}

	f_mm_common(expect_auth, expect_ciph);

	/* Expect MSC to perform LU with HLR */
	GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
	GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
	GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
	GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));

	alt {
	[] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) -> value dtap_mt {
		var PDU_ML3_LocationUpdateAccept lu_acc := dtap_mt.dtap.msgs.mm.locationUpdateAccept;
		if (expect_tmsi) {
			if (not ispresent(lu_acc.mobileIdentityTLV) or
			    not ischosen(lu_acc.mobileIdentityTLV.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi)) {
				setverdict(fail, "Expected TMSI but no TMSI was allocated");
				self.stop;
			} else {
				g_pars.tmsi := lu_acc.mobileIdentityTLV.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets;
				BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_TmsiRealloc_Cmpl));
			}
		} else {
			if (ispresent(lu_acc.mobileIdentityTLV) and
			    ischosen(lu_acc.mobileIdentityTLV.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi)) {
				setverdict(fail, "Expected no TMSI but TMSI was allocated");
				self.stop;
			}
		}
		}
	[] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
		setverdict(fail, "Expected LU ACK, but received LU REJ");
		self.stop;
		}
	}
	/* FIXME: there could be pending SMS or other common procedures by the MSC, let's ignore them */
	BSSAP.receive(tr_BSSMAP_ClearCommand);
	BSSAP.send(ts_BSSMAP_ClearComplete);
	BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
	setverdict(pass);
}

function f_foo() runs on BSC_ConnHdlr{
	/* SCCP CC handled by BSSMAP_Emulation_CT.main() */
	/* Expect auth, if enabled */

	/* TODO: ISD */
	/* Expect encr, if enabled */
	/* Expect encr, if enabled */
	/* Expect ASS CMD, if chan_type != requested */
	/* Send ASS CMPL in successful case */

	/* Expect AoIP port/ip information for RTP stream */
	/* Expect MSC-originated MGCP to our simulated MGW */
	/* Verify Counters via CTRL */
	/* re-configure MSC behaviour via VTY */
}

/* parameters related to a (MO?) voice call */
type record CallParameters {
	boolean expect_auth,				/* do we expect AUTHENTICATE from network */
	boolean expect_ciph,				/* do we expect CIPHER MODE from network */

	/* CC related parameters */
	hexstring called_party,				/* whom are we calling */
	integer transaction_id optional,		/* which TS 04.08 CC transaction ID to use */
	BearerCapability_TLV bearer_cap,		/* which bearer capabilities to claim */

	/* MNCC related parameters */
	uint32_t mncc_callref optional,			/* call reference on the MNCC side */
	MNCC_bearer_cap mncc_bearer_cap optional,	/* MNCC-side bearer capabilities */

	/* RTP related parameters */
	HostName bss_rtp_ip optional,			/* BSS Side RTP IP */
	PortNumber bss_rtp_port optional,		/* BSS Side RTP Port */
	HostName mss_rtp_ip optional,			/* MSS Side RTP IP */
	PortNumber mss_rtp_port optional,		/* MSS Side RTP Port */
	HostName mgw_rtp_ip_bss,			/* BSS-facing MGW RTP IP */
	PortNumber mgw_rtp_port_bss,			/* BSS-facing MGW RTP Port */
	HostName mgw_rtp_ip_mss,			/* MSS-facing MGW RTP IP */
	PortNumber mgw_rtp_port_mss,			/* MSS-facing MGW RTP Port */
	uint7_t rtp_payload_type,			/* dynamic RTP payload type */
	charstring rtp_sdp_format,			/* AMR/8000 or the like */

	MgcpCallId mgcp_call_id optional,			/* MGCP Call ID; CallAgent allocated */
	MgcpEndpoint mgcp_ep optional			/* MGCP Endpoint, CallAgent or MGW allocated */,
	MgcpConnectionId mgcp_connection_id_bss,	/* MGCP Connection ID BSS Side */
	MgcpConnectionId mgcp_connection_id_mss		/* MGCP Connection ID MSS Side */
}

template (value) CallParameters t_CallParams(hexstring called, integer tid) := {
	expect_auth := false,
	expect_ciph := false,
	called_party := called,
	transaction_id := tid,
	bearer_cap := valueof(ts_Bcap_voice),
	mncc_callref := omit,
	mncc_bearer_cap := valueof(ts_MNCC_bcap_voice),
	bss_rtp_ip := "9.8.7.6",
	bss_rtp_port := 9000,
	mss_rtp_ip := omit,
	mss_rtp_port := omit,
	mgw_rtp_ip_bss := "1.1.1.1",
	mgw_rtp_port_bss := 10000,
	mgw_rtp_ip_mss := "1.1.1.1",
	mgw_rtp_port_mss := 11000,
	rtp_payload_type := 98,
	rtp_sdp_format := "AMR/8000",
	mgcp_call_id := omit,
	mgcp_ep := omit,
	mgcp_connection_id_bss := '0'H,//
	mgcp_connection_id_mss := '0'H //
};


function f_mo_call(inout CallParameters cpars)
runs on BSC_ConnHdlr {

	var MobileIdentityLV mi;
	var MNCC_PDU mncc;
	var MgcpCommand mgcp_cmd;

	/* If we have a TMSI, use TMSI instead of IMSI */
	if (ispresent(g_pars.tmsi)) {
		mi := valueof(ts_MI_TMSI_LV(g_pars.tmsi));
	} else {
		mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
	}
	f_establish_fully(mi, cpars.expect_auth, cpars.expect_ciph);

	/* Create MNCC and MGCP expect */
	f_create_mncc_expect(hex2str(cpars.called_party));
	f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});

	BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party)));
	interleave {
	[] MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc {
		cpars.mncc_callref := mncc.u.signal.callref;
		/* Call Proceeding */
		MNCC.send(ts_MNCC_CALL_PROC_req(cpars.mncc_callref, cpars.mncc_bearer_cap));
		BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CALL_PROC(cpars.transaction_id)));
		};
	/* First MGCP CRCX (for BSS/RAN side) */
	[] MGCP.receive(tr_CRCX) -> value mgcp_cmd {
		cpars.mgcp_call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
		/* TODO: dynamic EP allocation case */
		cpars.mgcp_ep := mgcp_cmd.line.ep;
		var SDP_Message sdp := valueof(ts_SDP(cpars.mgw_rtp_ip_bss, cpars.mgw_rtp_ip_bss,
							hex2str(cpars.mgcp_call_id), "42",
							cpars.mgw_rtp_port_bss,
							{ int2str(cpars.rtp_payload_type) },
							{ valueof(ts_SDP_rtpmap(cpars.rtp_payload_type,
										cpars.rtp_sdp_format)),
							  valueof(ts_SDP_ptime(20)) }));
		MGCP.send(ts_CRCX_ACK(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_bss, sdp));
		}
	}
	/* Second MGCP CRCX (this time for MSS/CN side) */
	MGCP.receive(tr_CRCX(cpars.mgcp_ep)) -> value mgcp_cmd {
		var SDP_Message sdp := valueof(ts_SDP(cpars.mgw_rtp_ip_mss, cpars.mgw_rtp_ip_mss,
							hex2str(cpars.mgcp_call_id), "42",
							cpars.mgw_rtp_port_mss,
							{ int2str(cpars.rtp_payload_type) },
							{ valueof(ts_SDP_rtpmap(cpars.rtp_payload_type,
										cpars.rtp_sdp_format)),
							  valueof(ts_SDP_ptime(20)) }));
		MGCP.send(ts_CRCX_ACK(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_mss, sdp));
	}

	/* Alerting */
	MNCC.send(ts_MNCC_ALERT_req(cpars.mncc_callref));

	var BSSMAP_IE_AoIP_TransportLayerAddress tla_ass :=
		valueof(ts_BSSMAP_IE_AoIP_TLA4(f_inet_addr(cpars.mgw_rtp_ip_bss),cpars.mgw_rtp_port_bss));
	interleave {
	[] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_ALERTING(cpars.transaction_id))) {}
	/* expect AoIP IP/Port to match what we returned in CRCX_ACK above */
	[] BSSAP.receive(tr_BSSMAP_AssignmentReq(omit, tla_ass)) {
		var BSSMAP_IE_AoIP_TransportLayerAddress tla;
		tla := valueof(ts_BSSMAP_IE_AoIP_TLA4(f_inet_addr(cpars.bss_rtp_ip), cpars.bss_rtp_port));
		BSSAP.send(ts_BSSMAP_AssignmentComplete(omit, tla));
		}
	}

	/* Answer. MNCC_SETUP_RSP -> CONNECT to MS; CONNECT_ACK from MS */
	MNCC.send(ts_MNCC_SETUP_rsp(cpars.mncc_callref));
	BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CONNECT(cpars.transaction_id)));
	BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CONNECT_ACK(cpars.transaction_id)));

	f_sleep(3.0);

	/* Hangup by "B" side */
	MNCC.send(ts_MNCC_DISC_req(cpars.mncc_callref, valueof(ts_MNCC_cause(23))));
	BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_DISC(cpars.transaction_id)));

	/* Release of call */
	MNCC.send(ts_MNCC_REL_req(cpars.mncc_callref, valueof(ts_MNCC_cause(42))));
	BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
	BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_REL_COMPL(cpars.transaction_id)));

	/* clearing of radio channel */
	interleave {
	[] BSSAP.receive(tr_BSSMAP_ClearCommand) {
		BSSAP.send(ts_BSSMAP_ClearComplete);
		BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
		}
	[] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
		/* TODO: For one or all connections on EP? */
		MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
		f_create_mgcp_delete_ep(cpars.mgcp_ep);
		}
	}
	setverdict(pass);
}




}


