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 MobileL3_SMS_Types all;
import from L3_Templates all;
import from L3_Common all;

import from SMPP_Emulation all;

/* this component represents a single subscriber connection */
type component BSC_ConnHdlr extends BSSAP_ConnHdlr, MNCC_ConnHdlr, GSUP_ConnHdlr, MGCP_ConnHdlr, SMPP_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,
	boolean send_early_cm
};

/* 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());
	/* Route all SMPP messages for our MSISDN to us */
	f_create_smpp_expect(hex2str(pars.msisdn));
}


/* 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,
	EST_TYPE_MO_SMS,
	EST_TYPE_SS_ACT
};

/* helper function to fully establish a dedicated channel */
function f_establish_fully(EstablishType etype := EST_TYPE_MO_CALL)
runs on BSC_ConnHdlr {
	var PDU_ML3_MS_NW l3_info;
	var MobileIdentityLV mi;

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

	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));
		}
	case (EST_TYPE_MO_SMS) {
		l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, mi));
		}
	case (EST_TYPE_SS_ACT) {
		l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_SS_ACT, 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()
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 (g_pars.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 */
	boolean mgw_drop_dlcx optional,			/* Provoke errors by not responding to DLCX
							   (f_mt_call and f_mt_call) */

	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_establish(inout CallParameters cpars)
runs on BSC_ConnHdlr {

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

	f_establish_fully(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);

		/* When the endpoint contains a wildcard we keep the endpoint
		 * identifier we have set up in cpars. Otherwise we use the
		 * endpoint name that the call agent has supplied */
		if (match(mgcp_cmd.line.ep, t_MGCP_EP_wildcard) == false) {
			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)) }));
		var template MgcpResponse mgcp_resp;
		mgcp_resp := ts_CRCX_ACK(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_bss, sdp);
		f_mgcp_par_append(mgcp_resp.params, ts_MgcpParSpecEP(cpars.mgcp_ep));
		MGCP.send(mgcp_resp);
		}
	/* 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));

	setverdict(pass);
}

function f_mo_call_establish(inout CallParameters cpars)
runs on BSC_ConnHdlr {

	var MNCC_PDU mncc;
	var MgcpCommand mgcp_cmd;
	var boolean respond_to_dlcx;

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

		/* When the endpoint contains a wildcard we keep the endpoint
		 * identifier we have set up in cpars. Otherwise we use the
		 * endpoint name that the call agent has supplied */
		if (match(mgcp_cmd.line.ep, t_MGCP_EP_wildcard) == false) {
			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)) }));

		var template MgcpResponse mgcp_resp;
		mgcp_resp := ts_CRCX_ACK(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_bss, sdp);
		f_mgcp_par_append(mgcp_resp.params, ts_MgcpParSpecEP(cpars.mgcp_ep));
		MGCP.send(mgcp_resp);
		}
	}
	/* 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)));

	setverdict(pass);
}

function f_call_hangup(inout CallParameters cpars, boolean release_by_ms)
runs on BSC_ConnHdlr {

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

	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 (release_by_ms) {
		/* 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)));
	} else {
		/* 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)));
	}

	respond_to_dlcx := not (isbound(cpars.mgw_drop_dlcx) and valueof(cpars.mgw_drop_dlcx));

	/* 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 {
		if (respond_to_dlcx) {
			/* 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_mt_call(inout CallParameters cpars)
runs on BSC_ConnHdlr {

	f_mt_call_establish(cpars);

	/* Hold the call for some time */
	f_sleep(3.0);

	f_call_hangup(cpars, true);

	setverdict(pass);
}

function f_mo_call(inout CallParameters cpars)
runs on BSC_ConnHdlr {

	f_mo_call_establish(cpars);

	/* Hold the call for some time */
	f_sleep(3.0);

	f_call_hangup(cpars, false);

	setverdict(pass);
}

function f_mo_seq_dtmf_dup(inout CallParameters cpars)
runs on BSC_ConnHdlr {

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

	f_establish_fully();

	/* 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 */
altstep as_clear_cmd_compl_disc(float t := 5.0) runs on BSC_ConnHdlr {
	[] BSSAP.receive(tr_BSSMAP_ClearCommand) {
		BSSAP.send(ts_BSSMAP_ClearComplete);
		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;
			}
		}
		}
	[] BSSAP.receive {
		setverdict(fail, "Unexpected BSSMAP while waiting for ClearCommand");
		self.stop;
		}
}

function f_expect_clear(float t := 5.0) runs on BSC_ConnHdlr {
	timer T := t;

	T.start;
	alt {
	[] as_clear_cmd_compl_disc(t) { }
	[] T.timeout {
		setverdict(fail, "Timeout waiting for ClearCommand/Release");
		self.stop;
		}
	}
}

type record SmsParametersTp {
	OCT1		msg_ref,
	TP_DA		da,
	OCT1		pid,
	OCT1		dcs,
	integer		udl,
	octetstring	ud
}
type record SmsParametersRp {
	OCT1		msg_ref,
	RP_NumberingPlan_and_NumberDigits orig optional,
	RP_NumberingPlan_and_NumberDigits dest optional
}
type record SmsParameters {
	SmsParametersTp tp,
	SmsParametersRp rp,
	uint3_t		tid,
	OCT1		dlci,
	uint7_t		exp_rp_err optional
}

template (value) TP_DA ts_TP_DA(BIT4 npl, BIT3 ton, hexstring addr) := {
	tP_DA_NoPad := {
		tP_LengthIndicator := 0, /* overwritten */
		tP_NumberingPlanID := npl,
		tP_TypeOfNumber := ton,
		tp_Spare := '0'B,
		tP_DAValue := addr
	}
}

template (value) SmsParameters t_SmsPars(hexstring tp_daddr := '12345'H) := {
	tp := {
		msg_ref := '23'O,
		da := ts_TP_DA('0000'B, '000'B, tp_daddr),
		pid := '00'O,
		dcs := '00'O,
		udl := 0,
		ud := ''O
	},
	rp := {
		msg_ref := '42'O,
		orig := omit,
		dest := { '0000'B, '000'B, '0'B, '98765'H }
	},
	tid := 0,
	dlci := '03'O,
	exp_rp_err := omit
}

private altstep as_other_sms() runs on BSC_ConnHdlr {
	[] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_SMS(?, ?, ?), ?)) {
		setverdict(fail, "Unexpected SMS related PDU from MSC");
		self.stop;
	}
}

/* Submit a MO-SMS over an already existing (and authenticated, ...) DTAP connection */
function f_mo_sms(inout SmsParameters spars)
runs on BSC_ConnHdlr {
	var template (value) TPDU_RP_DATA_MS_SGSN tp_mo;
	var template (value) RPDU_MS_SGSN rp_mo;
	var template (value) PDU_ML3_MS_NW l3_mo;

	var template TPDU_RP_DATA_SGSN_MS tp_mt;
	var template RPDU_SGSN_MS rp_mt;
	var template PDU_ML3_NW_MS l3_mt;

	var default d := activate(as_other_sms());

	/* just in case this is routed to SMPP.. */
	f_create_smpp_expect(hex2str(spars.tp.da.tP_DA_NoPad.tP_DAValue));

	tp_mo := ts_SMS_SUBMIT(spars.tp.msg_ref, spars.tp.da, spars.tp.pid, spars.tp.dcs,
				 spars.tp.udl, spars.tp.ud);
	rp_mo := ts_RP_DATA_MO(spars.rp.msg_ref, spars.rp.orig, spars.rp.dest, tp_mo);
	l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_ORIG, ts_CP_DATA_MO(rp_mo));
	BSSAP.send(ts_PDU_DTAP_MO(l3_mo, spars.dlci, true));
	/* receive CP-ACK for CP-DATA above */
	BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_SMS(spars.tid, c_TIF_REPL, tr_CP_ACK_MT), spars.dlci));

	if (ispresent(spars.exp_rp_err)) {
		/* expect an RP-ERROR message from MSC with given cause */
		rp_mt := tr_RP_ERROR_MT(spars.rp.msg_ref, spars.exp_rp_err);
		l3_mt := tr_ML3_MT_SMS(spars.tid, c_TIF_REPL, tr_CP_DATA_MT(rp_mt));
		BSSAP.receive(tr_PDU_DTAP_MT(l3_mt, spars.dlci));
		/* send CP-ACK for CP-DATA just received */
		l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_ORIG, ts_CP_ACK_MO);
		BSSAP.send(ts_PDU_DTAP_MO(l3_mo, spars.dlci, true));
	} else {
		/* expect RP-ACK for RP-DATA */
		rp_mt := tr_RP_ACK_MT(spars.rp.msg_ref);
		l3_mt := tr_ML3_MT_SMS(spars.tid, c_TIF_REPL, tr_CP_DATA_MT(rp_mt));
		BSSAP.receive(tr_PDU_DTAP_MT(l3_mt, spars.dlci));
		/* send CP-ACO for CP-DATA just received */
		l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_ORIG, ts_CP_ACK_MO);
		BSSAP.send(ts_PDU_DTAP_MO(l3_mo, spars.dlci, true));
	}
	deactivate(d);
	setverdict(pass);
}

/* receive MT-SMS delivered from the MSC/SMSC over an already existing DTAP connection */
function f_mt_sms(inout SmsParameters spars)
runs on BSC_ConnHdlr {
	var template (value) TPDU_RP_DATA_MS_SGSN tp_mo;
	var template (value) RPDU_MS_SGSN rp_mo;
	var template (value) PDU_ML3_MS_NW l3_mo;

	var template TPDU_RP_DATA_SGSN_MS tp_mt;
	var template RPDU_SGSN_MS rp_mt;
	var template PDU_ML3_NW_MS l3_mt;

	var PDU_DTAP_MT dtap_mt;

	var default d := activate(as_other_sms());

	/* Expect CP-DATA(RP-DATA(SMS-DELIVER)) */
	tp_mt := tr_SMS_DELIVER(?, spars.tp.ud, spars.tp.pid, spars.tp.dcs, ?);
	rp_mt := tr_RP_DATA_MT(?, ?, omit, tp_mt);
	l3_mt := tr_ML3_MT_SMS(?, c_TIF_ORIG, tr_CP_DATA_MT(rp_mt));
	BSSAP.receive(tr_PDU_DTAP_MT(l3_mt, spars.dlci)) -> value dtap_mt;
	/* Extract relevant identifiers */
	spars.tid := bit2int(dtap_mt.dtap.tiOrSkip.transactionId.tio);
	spars.rp.msg_ref := dtap_mt.dtap.msgs.sms.cP_DATA.cP_User_Data.cP_RPDU.rP_DATA_SGSN_MS.rP_MessageReference;

	/* send CP-ACK for CP-DATA just received */
	l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_REPL, ts_CP_ACK_MO);
	BSSAP.send(ts_PDU_DTAP_MO(l3_mo, spars.dlci, true));

	/* send RP-ACK for RP-DATA */
	rp_mo := ts_RP_ACK_MO(spars.rp.msg_ref);
	l3_mo := ts_ML3_MO_SMS(spars.tid, c_TIF_REPL, ts_CP_DATA_MO(rp_mo));
	BSSAP.send(ts_PDU_DTAP_MO(l3_mo, spars.dlci, true));

	/* expect CP-ACK for CP-DATA(RP-ACK) just sent */
	l3_mt := tr_ML3_MT_SMS(spars.tid, c_TIF_ORIG, tr_CP_ACK_MT);
	BSSAP.receive(tr_PDU_DTAP_MT(l3_mt, spars.dlci));

	deactivate(d);
	setverdict(pass);
}




}


