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;
import from L3_Common 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;
	timer g_Tguard := 60.0;
}

type record BSC_ConnHdlrNetworkPars {
	OCT1	kc_support,
	boolean expect_tmsi,
	boolean	expect_auth,
	boolean	expect_ciph
}

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,
	MobileStationClassmark1_V cm1,
	BSSMAP_IE_ClassmarkInformationType2 cm2,
	BSSMAP_IE_ClassmarkInformationType3 cm3 optional,
	AuthVector vec optional,
	BSC_ConnHdlrNetworkPars net
};

/* get a one-octet bitmaks of supported algorithms based on Classmark information */
function f_alg_mask_from_cm(BSSMAP_IE_ClassmarkInformationType2 cm2) return OCT1 {
	var BIT8 res := '00000001'B;	/* A5/0 always supported */

	if (cm2.a5_1 == '0'B) {
		res := res or4b '00000010'B;
	}
	if (cm2.classmarkInformationType2_oct5.a5_2 == '1'B ) {
		res := res or4b '00000100'B;
	}
	if (cm2.classmarkInformationType2_oct5.a5_3 == '1'B) {
		res := res or4b '00001000'B;
	}
	/* TODO: CM3 for A5/4 and beyond */
	return bit2oct(res);
}

/* determine the best algorithm available within the bit-mask */
function f_best_alg_from_mask(OCT1 alg_in) return OCT1 {
	var BIT8 alg := oct2bit(alg_in);
	var BIT8 ordered_algs[8] := {
		'10000000'B, '01000000'B, '00100000'B, '00010000'B,
		'00001000'B,	/* A5/3 */
		'00000010'B,	/* A5/1 */
		'00000100'B,	/* A5/2 */
		'00000001'B 	/* A5/0 */ }
	for (var integer i := 0; i < sizeof(ordered_algs); i := i+1) {
		if (alg and4b ordered_algs[i] != '00000000'B) {
			return bit2oct(ordered_algs[i]);
		}
	}
	return '00'O;
}

/* return an integer like '1' for A5/1 based on a mask (with only one bit set */
function f_alg_from_mask(OCT1 mask_in) return integer {
	var BIT8 mask := oct2bit(mask_in);
	for (var integer i := 0; i < 8; i := i+1) {
		if (mask and4b ('00000001'B << i) != '00000000'B) {
			return i;
		}
	}
	return -1;
}

/* altstep for the global guard timer */
private altstep as_Tguard() runs on BSC_ConnHdlr {
	[] g_Tguard.timeout {
		setverdict(fail, "Tguard timeout");
		self.stop;
	}
}

/* init function, called as first function in new BSC_ConnHdlr */
function f_init_handler(BSC_ConnHdlrPars pars, float t_guard := 60.0) runs on BSC_ConnHdlr {
	/* make parameters available via component variable */
	g_pars := pars;
	/* Start guard timer and activate it as default */
	g_Tguard.start(t_guard);
	activate(as_Tguard());
}


/* 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,
	sccp_addr_local := omit,
	sccp_addr_peer := omit
}


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

type enumerated EstablishType {
	EST_TYPE_MO_CALL,
	EST_TYPE_EMERG_CALL,
	EST_TYPE_PAG_RESP
};

/* helper function to fully establish a dedicated channel */
function f_establish_fully(MobileIdentityLV mi, EstablishType etype := EST_TYPE_MO_CALL)
runs on BSC_ConnHdlr {
	var PDU_ML3_MS_NW l3_info;
	select (etype) {
	case (EST_TYPE_MO_CALL) {
		l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
		}
	case (EST_TYPE_EMERG_CALL) {
		l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_EMERG_CALL, mi));
		}
	case (EST_TYPE_PAG_RESP) {
		l3_info := valueof(ts_PAG_RESP(mi));
		}
	}

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

	f_mm_common();
	if (g_pars.net.expect_ciph) {
		/* implicit CM SERVICE ACCEPT? */
	} else {
		if (etype != EST_TYPE_PAG_RESP) {
			/* 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) runs on BSC_ConnHdlr 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) runs on BSC_ConnHdlr 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) runs on BSC_ConnHdlr 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) runs on BSC_ConnHdlr 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, g_pars.cm1));
	return l3_info;
}

function f_mm_auth() runs on BSC_ConnHdlr
{
	if (g_pars.net.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)));
	}
}

function f_mm_common() runs on BSC_ConnHdlr
{
	f_mm_auth();
	if (g_pars.net.expect_ciph) {
		var OCT1 a5_net := f_alg_mask_from_cm(g_pars.cm2);
		var OCT1 a5_intersect := g_pars.net.kc_support and4b a5_net;
		alt {
		[] BSSAP.receive(tr_BSSMAP_CipherModeCmd(a5_intersect, g_pars.vec.kc)) {
			var OCT1 a5_chosen := f_best_alg_from_mask(a5_intersect);
			var integer a5_nr := f_alg_from_mask(a5_chosen);
			BSSAP.send(ts_BSSMAP_CipherModeCompl(int2oct(a5_nr+1, 1)));
			}
		[] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?, g_pars.vec.kc)) {
			setverdict(fail, "Wrong ciphering algorithm mask in CiphModCmd");
			self.stop;
			}
		}
		/* FIXME: Send the best available algorithm */
	}
}

function f_perform_lu(boolean send_early_cm)
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 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 (g_pars.net.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 {
	/* 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 */
	boolean emergency,				/* is this an emergency call? */

	/* 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) := {
	called_party := called,
	transaction_id := tid,
	bearer_cap := valueof(ts_Bcap_voice),
	emergency := false,
	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_mt_call(inout CallParameters cpars)
runs on BSC_ConnHdlr {

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

	f_bssmap_register_imsi(g_pars.imsi, g_pars.tmsi);

	/* Allocate a call reference and send SETUP via MNCC to MSC */
	cpars.mncc_callref := f_rnd_int(2147483648);
	MNCC.send(ts_MNCC_SETUP_req(cpars.mncc_callref, hex2str(g_pars.msisdn),
					hex2str(cpars.called_party), hex2str(g_pars.imsi)));
	/* BSC <- MSC: Expect paging. FIXME: By TMSI or not? */
	BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi));

	/* 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, EST_TYPE_PAG_RESP);

	/* MS <- MSC: Expect CC SETUP */
	BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_SETUP(cpars.transaction_id, *, cpars.called_party)));

	/* MS -> MSC: ALERTING */
	BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_ALERTING(cpars.transaction_id)));
	MNCC.receive(tr_MNCC_ALERT_ind(cpars.mncc_callref));


	/* Create MGCP expect */
	f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
	/* Ask MSC via MNCC to create the RTP socket on the MSC/MGW side */
	MNCC.send(ts_MNCC_RTP_CREATE(cpars.mncc_callref));

	/* 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));
		/* MSC acknowledges the MNCC_CREATE to the MNCC handler */
		MNCC.receive(tr_MNCC_RTP_CREATE(cpars.mncc_callref));
	}

	/* expect the MSC to trigger a BSSMAP ASSIGNMENT */
	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));
	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));
		}

	/* MS -> MSC: ALERTING */
	BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CONNECT(cpars.transaction_id)));
	MNCC.receive(tr_MNCC_SETUP_cnf(cpars.mncc_callref));

	/* FIXME */
	f_sleep(3.0);

	/* Hangup by "A" 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)));

	if (false) {
		/* A-side (PLMN) 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)));
	} else {
		/* B-side (MS) Release of call */
		BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_RELEASE(cpars.transaction_id, '1'B, '0000000'B)));
		MNCC.receive(tr_MNCC_REL_ind(cpars.mncc_callref));
		BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_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);
}

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));
	}
	if (cpars.emergency) {
		f_establish_fully(mi, EST_TYPE_EMERG_CALL);
	} else {
		f_establish_fully(mi, EST_TYPE_MO_CALL);
	}

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

	if (cpars.emergency) {
		BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_EMERG_SETUP(cpars.transaction_id)));
	} else {
		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);
}

function f_mo_seq_dtmf_dup(inout CallParameters cpars)
runs on BSC_ConnHdlr {

	timer T := 1.0;
	var MobileIdentityLV mi;
	var MNCC_PDU mncc;
	var MgcpCommand mgcp_cmd;
	var template PDU_ML3_MS_NW dtmf_dtap;

	/* 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);

	/* 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)));
	MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc;
	cpars.mncc_callref := mncc.u.signal.callref;

	/* Send DTMF */
	dtmf_dtap := ts_ML3_MO_CC_START_DTMF(cpars.transaction_id, "2");
	dtmf_dtap.msgs.cc.startDTMF.nsd := int2bit(2, 2);
	BSSAP.send(ts_PDU_DTAP_MO(dtmf_dtap, '00'O, true));
	T.start;
	alt {
	[] MNCC.receive(tr_MNCC_START_DTMF_ind(cpars.mncc_callref, "2")) {}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for START_DTMF_ind");
		self.stop;
		}
	}

	BSSAP.send(ts_PDU_DTAP_MO(dtmf_dtap, '00'O, true));
	T.start;
	alt {
	[] MNCC.receive(tr_MNCC_START_DTMF_ind(cpars.mncc_callref, "2")) {
		setverdict(fail, "Received duplicate START_DTMF_ind");
		self.stop;
		}
	[] T.timeout { }
	}

	dtmf_dtap := ts_ML3_MO_CC_START_DTMF(cpars.transaction_id, "3");
	dtmf_dtap.msgs.cc.startDTMF.nsd := int2bit(3, 2);
	BSSAP.send(ts_PDU_DTAP_MO(dtmf_dtap, '00'O, true));
	alt {
	[] MNCC.receive(tr_MNCC_START_DTMF_ind(cpars.mncc_callref, "3")) { }
	[] T.timeout {
		setverdict(fail, "Received duplicate START_DTMF_ind");
		self.stop;
		}
	}

	setverdict(pass);
}
/* expect a clear command */
function f_expect_clear(float t := 5.0) runs on BSC_ConnHdlr {
	timer T := t;

	T.start;
	alt {
	[] BSSAP.receive(tr_BSSMAP_ClearCommand) { }
	[] BSSAP.receive {
		setverdict(fail, "Unexpected BSSMAP while waiting for ClearCommand");
		self.stop;
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for ClearCommand");
		self.stop;
		}
	}

	BSSAP.send(ts_BSSMAP_ClearComplete);

	T.start;
	alt {
	[] BSSAP.receive(BSSAP_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
		setverdict(pass);
		}
	[] BSSAP.receive {
		setverdict(fail, "Unexpected BSSMAP while waiting for SCCP Release");
		self.stop;
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for SCCP Release");
		self.stop;
		}
	}
}




}


