/* BSC Connection Handler of MSC test suite in TTCN-3
 * (C) 2018-2019 Harald Welte <laforge@gnumonks.org>
 * (C) 2018-2019 sysmocom - s.f.m.c. GmbH
 * (C) 2018 Vadim Yanitskiy <axilirator@gmail.com>
 * All rights reserved.
 *
 * Released under the terms of GNU General Public License, Version 2 or
 * (at your option) any later version.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

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 RAN_Emulation all;
import from BSSMAP_Templates all;

import from RANAP_Constants all;
import from RANAP_IEs all;
import from RANAP_PDU_Contents all;
import from RANAP_PDU_Descriptions all;
import from RANAP_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;

import from IPA_Emulation all;
import from Osmocom_CTRL_Functions all;
import from Osmocom_CTRL_Types all;
import from Osmocom_CTRL_Adapter all;

import from TELNETasp_PortType all;
import from Osmocom_VTY_Functions all;

import from SGsAP_Emulation all;

/* this component represents a single subscriber connection */
type component BSC_ConnHdlr extends RAN_ConnHdlr, MNCC_ConnHdlr, GSUP_ConnHdlr, MGCP_ConnHdlr, SMPP_ConnHdlr, CTRL_Adapter_CT, SGsAP_ConnHdlr {
	var BSC_ConnHdlrPars g_pars;
	timer g_Tguard := 60.0;
	port TELNETasp_PT MSCVTY;
}

type record BSC_ConnHdlrNetworkPars {
	OCT1	kc_support,
	boolean expect_tmsi,
	boolean	expect_auth,
	boolean	expect_ciph,
	boolean expect_imei,
	boolean expect_imei_early,
	GSUP_IMEIResult check_imei_result,
	boolean check_imei_error
}

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,
	charstring ipa_ctrl_ip,
	integer ipa_ctrl_port,
	boolean ipa_ctrl_enable,
	boolean mm_info,
	boolean sgsap_enable,
	boolean gsup_enable,
	integer ran_idx,
	boolean use_umts_aka,
	boolean ran_is_geran,
	boolean use_osmux
};

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

	/* Route all SGs message for our IMSI to us */
	if (g_pars.sgsap_enable == true) {
		f_create_sgsap_expect(pars.imsi);
	}

	if (g_pars.ipa_ctrl_enable == true) {
		f_ipa_ctrl_start(g_pars.ipa_ctrl_ip, g_pars.ipa_ctrl_port);
	}

	map(self:MSCVTY, system:MSCVTY);
	f_vty_set_prompts(MSCVTY);
	f_vty_transceive(MSCVTY, "enable");
}


/* Callback function from general RAN_Emulation whenever a connectionless
 * BSSMAP message arrives. Canreturn a PDU_BSSAPthat should be sent in return */
private function BscUnitdataCallback(PDU_BSSAP bssap)
runs on RAN_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(g_ran_ops.use_osmux))){
		log("BSSMAP_BscUnitdataCallback: Responding to RESET with RESET-ACK");
		resp := ts_BSSMAP_ResetAck(g_ran_ops.use_osmux);
	}

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

private function RncUnitdataCallback(RANAP_PDU ranap)
runs on RAN_Emulation_CT return template RANAP_PDU {
	var template RANAP_PDU resp := omit;

	log("RANAP_RncUnitdataCallback");
	/* answer all RESET with RESET ACK */
	if (match(ranap, tr_RANAP_Reset())) {
		log("RANAP_RncUnitdataCallback: Responding to RESET with RESET-ACK");
		var CN_DomainIndicator dom;
		dom := ranap.initiatingMessage.value_.Reset.protocolIEs[1].value_.cN_DomainIndicator;
		resp := ts_RANAP_ResetAck(dom);
	}

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


const RanOps BSC_RanOps := {
	/* Create call-back for inbound connections from MSC (hand-over) */
	create_cb := refers(RAN_Emulation.ExpectedCreateCallback),
	unitdata_cb := refers(BscUnitdataCallback),
	ranap_create_cb := refers(RAN_Emulation.RanapExpectedCreateCallback),
	ranap_unitdata_cb := refers(RncUnitdataCallback),
	ps_domain := false,
	decode_dtap := true,
	role_ms := true,
	protocol := RAN_PROTOCOL_BSSAP,
	transport := BSSAP_TRANSPORT_AoIP,
	use_osmux := false,
	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)
}



/* Encode 'l3' and ask RAN_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(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) {}
	[] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
			setverdict(fail, "DISC.ind from SCCP");
			mtc.stop;
		}
	}
}

/* generate Iu LAI from BSSAP CGI */
private function f_IuLAI_from_BssmapCI(BSSMAP_IE_CellIdentifier ci) return LAI {
	var LAI lai;
	if (ischosen(ci.cellIdentification.cI_CGI)) {
		lai.pLMNidentity := ci.cellIdentification.cI_CGI.mcc_mnc;
		lai.lAC := ci.cellIdentification.cI_CGI.lac;
	} else if (ischosen(ci.cellIdentification.cI_SAI)) {
		lai.pLMNidentity := ci.cellIdentification.cI_SAI.mcc_mnc;
		lai.lAC := ci.cellIdentification.cI_SAI.lac;
	} else if (ischosen(ci.cellIdentification.ci_LAC_RNC_CI)) {
		lai.pLMNidentity := ci.cellIdentification.ci_LAC_RNC_CI.mcc_mnc;
		lai.lAC := ci.cellIdentification.ci_LAC_RNC_CI.lac;
	} else {
		mtc.stop;
	}
	lai.iE_Extensions := omit;
	return lai;
}

/* like f_bssap_compl_l3() but for 3G */
function f_ranap_initial_ue(PDU_ML3_MS_NW l3)
runs on BSC_ConnHdlr {
	log("Sending InitialUE: ", l3);
	var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3);
	var RANAP_PDU ranap;
	var LAI lai := f_IuLAI_from_BssmapCI(g_pars.cell_id);
	var SAI sai := {
		pLMNidentity := lai.pLMNidentity,
		lAC := lai.lAC,
		sAC := '0000'O, /* FIXME */
		iE_Extensions := omit
	};
	var IuSignallingConnectionIdentifier sigc_id := int2bit(23, 24);
	var GlobalRNC_ID grnc_id := {
		pLMNidentity := lai.pLMNidentity,
		rNC_ID := 2342 /* FIXME */
	};

	ranap := valueof(ts_RANAP_initialUE_CS(lai, sai, l3_enc, sigc_id, grnc_id));
	BSSAP.send(ts_RANAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_own, ranap));
	alt {
	[] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) {}
	[] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
			setverdict(fail, "DISC.ind from SCCP");
			mtc.stop;
		}
	}
}

/* Send BSSMAP Complete L3 or RANAP Initial UE depending on 2G/3G RAN type */
function f_cl3_or_initial_ue(PDU_ML3_MS_NW l3)
runs on BSC_ConnHdlr {
	if (g_pars.ran_is_geran) {
		f_bssap_compl_l3(l3);
	} else {
		f_ranap_initial_ue(l3);
	}
}

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_cl3_or_initial_ue(l3_info);

	f_mm_common();
	if (g_pars.net.expect_ciph or not g_pars.ran_is_geran) {
		/* 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;
}

altstep as_GSUP_SAI() runs on BSC_ConnHdlr {
var GSUP_IE auth_tuple;
[] GSUP.receive(tr_GSUP_SAI_REQ(g_pars.imsi)) {
	if (g_pars.use_umts_aka) {
		g_pars.vec := f_gen_auth_vec_3g();
		auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G3G(g_pars.vec.rand,
								g_pars.vec.sres,
								g_pars.vec.kc,
								g_pars.vec.ik,
								g_pars.vec.ck,
								g_pars.vec.autn,
								g_pars.vec.res));
		GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
	} else {
		g_pars.vec := f_gen_auth_vec_2g();
		auth_tuple := valueof(ts_GSUP_IE_AuthTuple2G(g_pars.vec.rand,
								g_pars.vec.sres,
								g_pars.vec.kc));
		GSUP.send(ts_GSUP_SAI_RES(g_pars.imsi, auth_tuple));
	}
	}
}

function f_mm_auth() runs on BSC_ConnHdlr
{
	if (g_pars.net.expect_auth) {
		as_GSUP_SAI();
		if (g_pars.use_umts_aka) {
			BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_AUTH_REQ_3G(g_pars.vec.rand, g_pars.vec.autn)));
			var OCT4 res := substr(g_pars.vec.res, 0, 4);
			var OCT4 xres := substr(g_pars.vec.res, 4, 4);
			BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MT_MM_AUTH_RESP_3G(res, xres)));
		} else {
			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_imei() runs on BSC_ConnHdlr
{
	var PDU_DTAP_MT dtap_mt;
	var GSUP_PDU gsup_msg;
	var MobileL3_CommonIE_Types.MobileIdentityLV mi;

	if (not g_pars.net.expect_imei) {
		return
	}

	/* MSC <-> BSC: ID req/rsp for IMEI */
	alt {
	[] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req(CM_ID_TYPE_IMEI))) {
		mi := valueof(ts_MI_IMEI_LV(g_pars.imei));
		BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_MM_ID_Rsp(mi)));
		}
	[] BSSAP.receive(tr_PDU_DTAP_MT(?)) -> value dtap_mt {
		setverdict(fail, "Expected ID REQ for IMEI DTAP MT message, but got: ", dtap_mt);
		mtc.stop;
		}
	}

	/* MSC <-> HLR: Check IMEI req/res/err */
	alt {
	[g_pars.net.check_imei_error] GSUP.receive(tr_GSUP_CHECK_IMEI_REQ(g_pars.imsi, g_pars.imei)) {
		GSUP.send(ts_GSUP_CHECK_IMEI_ERR(g_pars.imsi, 96 /* Invalid Mandatory Information */));
		}
	[not g_pars.net.check_imei_error] GSUP.receive(tr_GSUP_CHECK_IMEI_REQ(g_pars.imsi, g_pars.imei)) {
		GSUP.send(ts_GSUP_CHECK_IMEI_RES(g_pars.imsi, g_pars.net.check_imei_result));
		}
	[] GSUP.receive(?) -> value gsup_msg {
		setverdict(fail, "Expected CHECK IMEI REQ GSUP message (with IMEI:", g_pars.imei, " and IMSI: ",
			   g_pars.imsi, "), but got: ", gsup_msg);
		mtc.stop;
		}
	}
}

function f_mm_imei_early() runs on BSC_ConnHdlr
{
	var PDU_DTAP_MT dtap_mt;
	var GSUP_PDU gsup_msg;
	var MobileL3_CommonIE_Types.MobileIdentityLV mi;

	if (not g_pars.net.expect_imei_early) {
		return
	}

	/* MSC <-> BSC: ID req/rsp for IMEISV */
	alt {
	[] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_ID_Req(CM_ID_TYPE_IMEISV))) {
		mi := valueof(ts_MI_IMEISV_LV(g_pars.imei));
		BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_MM_ID_Rsp(mi)));
		}
	[] BSSAP.receive(tr_PDU_DTAP_MT(?)) -> value dtap_mt {
		setverdict(fail, "Expected ID REQ for IMEISV DTAP MT message, but got: ", dtap_mt);
		mtc.stop;
		}
	}

	/* MSC <-> HLR: Check IMEI req/res/err */
	alt {
	[g_pars.net.check_imei_error] GSUP.receive(tr_GSUP_CHECK_IMEI_REQ(g_pars.imsi, g_pars.imei)) {
		GSUP.send(ts_GSUP_CHECK_IMEI_ERR(g_pars.imsi, 96 /* Invalid Mandatory Information */));
		}
	[not g_pars.net.check_imei_error] GSUP.receive(tr_GSUP_CHECK_IMEI_REQ(g_pars.imsi, g_pars.imei)) {
		GSUP.send(ts_GSUP_CHECK_IMEI_RES(g_pars.imsi, g_pars.net.check_imei_result));
		}
	[] GSUP.receive(?) -> value gsup_msg {
		setverdict(fail, "Expected CHECK IMEI REQ GSUP message (with IMEI:", g_pars.imei, " and IMSI: ",
			   g_pars.imsi, "), but got: ", gsup_msg);
		mtc.stop;
		}
	}
}

function f_mm_common() runs on BSC_ConnHdlr
{
	f_mm_auth();
	if (g_pars.ran_is_geran) {
		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");
				mtc.stop;
				}
			}
			/* FIXME: Send the best available algorithm */
		}
	} else { /* UTRAN */
		alt {
		[g_pars.net.expect_ciph] BSSAP.receive(tr_RANAP_SecurityModeCmdEnc(uia_algs := ?,
										   uia_key := oct2bit(g_pars.vec.ik),
										   key_sts := ?,
										   uea_algs := ?,
										   uea_key := oct2bit(g_pars.vec.ck))) {
			var IntegrityProtectionAlgorithm uia_chosen := 0; /*standard_UMTS_integrity_algorithm_UIA1*/
			var EncryptionAlgorithm uea_chosen := 1; /*standard_UMTS_encryption_algorith_UEA1*/
			BSSAP.send(ts_RANAP_SecurityModeCompleteEnc(uia_chosen, uea_chosen));
			BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)));
			}
		[g_pars.net.expect_ciph] BSSAP.receive(tr_RANAP_SecurityModeCmdEnc(?,?,?,?,?)) {
			setverdict(fail, "Invalid SecurityModeCommand (ciphering case)");
			mtc.stop;
			}
		[not g_pars.net.expect_ciph] BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?,
										    uia_key := oct2bit(g_pars.vec.ik),
										    key_sts := ?)) {
			var IntegrityProtectionAlgorithm uia_chosen := 0; /*standard_UMTS_integrity_algorithm_UIA1;*/
			BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
			BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)));
			}
		[not g_pars.net.expect_ciph] BSSAP.receive(tr_RANAP_SecurityModeCmd(?,?,?)) {
			setverdict(fail, "Invalid SecurityModeCommand (non-ciphering case)");
			mtc.stop;
			}
		}
	}
}

function f_expect_mm_info() runs on BSC_ConnHdlr {
	 if (g_pars.mm_info == true) {
		 BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_Info));
	 }
}

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 */
	if (g_pars.ran_is_geran) {
		f_bssap_compl_l3(l3_lu);
		if (g_pars.send_early_cm) {
			BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
		}
	} else {
		f_ranap_initial_ue(l3_lu);
	}

	f_mm_imei_early();
	f_mm_common();
	f_msc_lu_hlr();
	f_mm_imei();
	f_accept_reject_lu();
	/* FIXME: there could be pending SMS or other common procedures by the MSC, let's ignore them */
	f_expect_clear();

	setverdict(pass);
}

function f_msc_lu_hlr() runs on BSC_ConnHdlr
{
	/* 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));
}

function f_accept_reject_lu() runs on BSC_ConnHdlr {
	var PDU_DTAP_MT dtap_mt;

	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");
				mtc.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");
				mtc.stop;
			}
		}
		}
	[] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
		setverdict(fail, "Expected LU ACK, but received LU REJ");
		mtc.stop;
		}
	}

	/* Wait for MM-Information (if enabled) */
	f_expect_mm_info();
	setverdict(pass);
}

function f_foo() runs on BSC_ConnHdlr{
	/* SCCP CC handled by RAN_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 */
	boolean mo_call,				/* For a MO call, the transaction_id was allocated by the MS,
							   important to set the TI flag properly */
	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 */

	boolean use_osmux				/* MSC is expected to use Osmux for this call */
}

template (value) CallParameters t_CallParams(hexstring called, integer tid) := {
	called_party := called,
	transaction_id := tid,
	mo_call := false,
	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",
	mgw_drop_dlcx := false,
	mgcp_call_id := omit,
	mgcp_ep := omit,
	mgcp_connection_id_bss := '0'H,//
	mgcp_connection_id_mss := '0'H,//
	use_osmux := false
};

/* Allocate a call reference and send SETUP via MNCC to MSC */
function f_mt_call_initate(inout CallParameters cpars)
runs on BSC_ConnHdlr {
	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)));
}

private template (value) SDP_Message ts_SDP_CRCX_CN(CallParameters cpars) :=
	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)) });

/* Complete call, begin with a paging response message via BSSAP */
function f_mt_call_complete(inout CallParameters cpars)
runs on BSC_ConnHdlr {
	var MNCC_PDU mncc;
	var MgcpCommand mgcp_cmd;
	var template MgcpResponse mgcp_resp;
	var MgcpOsmuxCID osmux_cid;
	var PDU_BSSAP bssap;

	f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);

	f_establish_fully(EST_TYPE_PAG_RESP);

	log("f_mt_call_complete 1");

	/* 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));
	log("f_mt_call_complete 2");

	/* 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 {
		log("f_mt_call_complete 3");
		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)) }));

		if (cpars.use_osmux) {
			osmux_cid := f_MgcpCmd_extract_osmux_cid(mgcp_cmd);
			if (osmux_cid != -1) { /* we expect MSC to use wildcard here */
				setverdict(fail, "MSC using unexpected CID " & int2str(osmux_cid) & " != -1");
				mtc.stop;
			}
			osmux_cid := 0;
			mgcp_resp := ts_CRCX_ACK_osmux(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_bss, osmux_cid, sdp);
		} else {
			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);
		}


	if (g_pars.ran_is_geran) {
		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 {
		/* Second MGCP CRCX (this time for MSS/CN side) */
		[] MGCP.receive(tr_CRCX(cpars.mgcp_ep)) -> value mgcp_cmd {
			log("f_mt_call_complete 4");
			var SDP_Message sdp := valueof(ts_SDP_CRCX_CN(cpars));
			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)) {
			log("f_mt_call_complete 5");
			}

		/* expect the MSC to trigger a BSSMAP ASSIGNMENT */
		[] BSSAP.receive(tr_BSSMAP_AssignmentReq(omit, tla_ass)) -> value bssap {
			var BSSMAP_IE_AoIP_TransportLayerAddress tla;
			var BSSMAP_IE_SpeechCodec codec;
			var BSSMAP_IE_Osmo_OsmuxCID osmuxCID;
			log("f_mt_call_complete 6");

			tla := valueof(ts_BSSMAP_IE_AoIP_TLA4(f_inet_addr(cpars.bss_rtp_ip), cpars.bss_rtp_port));
			codec := valueof(ts_BSSMAP_IE_SpeechCodec({ts_CodecFR}));

			if (cpars.use_osmux) {
				if (not ispresent(bssap.pdu.bssmap.assignmentRequest.osmuxCID)) {
					setverdict(fail, "MSC sent AssignReq without expected OsmuxCID IE");
					mtc.stop;
				}
				osmuxCID := valueof(ts_OsmuxCID(0));
				if (cpars.use_osmux and not match(bssap.pdu.bssmap.assignmentRequest.osmuxCID, osmuxCID)) {
					setverdict(fail, "MSC sent AssignReq without expected OsmuxCID IE");
					mtc.stop;
				}
				bssap := valueof(ts_BSSMAP_AssignmentComplete(omit, tla, codec, osmuxCID));
			} else {
				bssap := valueof(ts_BSSMAP_AssignmentComplete(omit, tla, codec));
			}
			BSSAP.send(bssap);

			BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CONNECT(cpars.transaction_id)));
			}

		[] MNCC.receive(tr_MNCC_SETUP_cnf(cpars.mncc_callref)) {
			log("f_mt_call_complete 7");
			MNCC.send(ts_MNCC_RTP_CONNECT(cpars.mncc_callref,
						      /* ip 42.23.11.5 */ hex2int('42231105'H),
						      /* port 423 */ 423,
						      /* payload type 3 = GSM FR */ 3));
			}

		/* MDCX setting up the RAN side remote RTP address received from Assignment Complete */
		[] MGCP.receive(tr_MDCX) -> value mgcp_cmd {
			log("f_mt_call_complete 8");
			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)) }));
			if (cpars.use_osmux) {
				osmux_cid := f_MgcpCmd_extract_osmux_cid(mgcp_cmd);
				if (osmux_cid != 0) { /* we expect MSC to use specific CID here */
					setverdict(fail, "MSC using unexpected CID " & int2str(osmux_cid) & " != 0");
					mtc.stop;
				}
				mgcp_resp := ts_MDCX_ACK_osmux(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_bss, osmux_cid, sdp);
			} else {
				mgcp_resp := ts_MDCX_ACK(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_mss, sdp);
			}
			MGCP.send(mgcp_resp);
			}

		/* MDCX setting up the CN side remote RTP address received from MNCC CONNECT */
		[] MGCP.receive(tr_MDCX) -> value mgcp_cmd {
			log("f_mt_call_complete 9");
			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_MDCX_ACK(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_mss, sdp));
			}

		}
	} else {
		var template TransportLayerAddress rab_tla := ? /* FIXME: encode the mgw_rtp_ip_bss/mgw_rtp_port_bss */
		var template RAB_SetupOrModifyList rab_sml := tr_RAB_SML(rab_id := ?, tla := rab_tla, binding_id := ?);

		interleave {
		[] MGCP.receive(tr_CRCX(cpars.mgcp_ep)) -> value mgcp_cmd {
			var SDP_Message sdp := valueof(ts_SDP_CRCX_CN(cpars));
			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));
			}
		[] BSSAP.receive(tr_RANAP_RabAssReq(rab_sml)) {
			//BSSAP.send(ts_RANAP_RabAssResp(rab_sml)); FIXME
			}

		/* FIXME: same MNCC and MGCP as in 2G above */
		}
	}

	log("f_mt_call_complete DONE");
}

function f_expect_paging(boolean by_tmsi := true)
runs on BSC_ConnHdlr {
	if (g_pars.ran_is_geran) {
		BSSAP.receive(tr_BSSMAP_Paging(g_pars.imsi));
	} else {
		BSSAP.receive(tr_RANAP_Paging(cs_domain, imsi_hex2oct(g_pars.imsi)));
	}
}

function f_mt_call_establish(inout CallParameters cpars)
runs on BSC_ConnHdlr {

	/* Initiate the call via MNCC */
	f_mt_call_initate(cpars);

	/* BSC <- MSC: Expect paging. FIXME: By TMSI or not? */
	f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);
	f_expect_paging()

	/* Complete the call via BSSAP */
	f_mt_call_complete(cpars);

	setverdict(pass);
}

function f_mo_call_establish(inout CallParameters cpars)
runs on BSC_ConnHdlr {

	var MNCC_PDU mncc;
	var MgcpCommand mgcp_cmd;
	var template MgcpResponse mgcp_resp;
	var boolean respond_to_dlcx;
	var PDU_BSSAP bssap;
	var MgcpOsmuxCID osmux_cid;

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

	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 {
	[] MNCC.receive(tr_MNCC_SETUP_ind(?, tr_MNCC_number(hex2str(cpars.called_party)))) -> value mncc {
		log("f_mo_call_establish 1: rx MNCC SETUP ind");
		cpars.mncc_callref := mncc.u.signal.callref;
		MNCC.send(ts_MNCC_RTP_CREATE(cpars.mncc_callref));
		}

	/* First MGCP CRCX (for BSS/RAN side) */
	[] MGCP.receive(tr_CRCX) -> value mgcp_cmd {
		log("f_mo_call_establish 2: rx 1st CRCX");
		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;
		}

		if (cpars.use_osmux) {
			osmux_cid := f_MgcpCmd_extract_osmux_cid(mgcp_cmd);
		}

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

		if (cpars.use_osmux) {
			osmux_cid := f_MgcpCmd_extract_osmux_cid(mgcp_cmd);
			if (osmux_cid != -1) { /* we expect MSC to use wildcard here */
				setverdict(fail, "MSC using unexpected CID " & int2str(osmux_cid) & " != -1");
				mtc.stop;
			}
			osmux_cid := 0;
			mgcp_resp := ts_CRCX_ACK_osmux(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_bss, osmux_cid, sdp);
		} else {
			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);
		}

	[] MNCC.receive(tr_MNCC_RTP_CREATE(cpars.mncc_callref)) {
		log("f_mo_call_establish 3: rx RTP CREATE");
		/* 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)));

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

	//[g_pars.ran_is_geran] BSSAP.receive(tr_BSSMAP_AssignmentReq(omit, tla_ass)) -> value bssap {
	[] BSSAP.receive(tr_BSSMAP_AssignmentReq(omit, tla_ass)) -> value bssap {
		log("f_mo_call_establish 4: rx Assignment Request");
		var BSSMAP_IE_AoIP_TransportLayerAddress tla;
		var BSSMAP_IE_SpeechCodec codec;
		var BSSMAP_IE_Osmo_OsmuxCID osmuxCID;

		tla := valueof(ts_BSSMAP_IE_AoIP_TLA4(f_inet_addr(cpars.bss_rtp_ip), cpars.bss_rtp_port));
		codec := valueof(ts_BSSMAP_IE_SpeechCodec({ts_CodecFR}));
		if (cpars.use_osmux) {
			if (not ispresent(bssap.pdu.bssmap.assignmentRequest.osmuxCID)) {
				setverdict(fail, "MSC sent AssignReq without expected OsmuxCID IE");
				mtc.stop;
			}
			osmuxCID := valueof(ts_OsmuxCID(0));
			if (cpars.use_osmux and not match(bssap.pdu.bssmap.assignmentRequest.osmuxCID, osmuxCID)) {
				setverdict(fail, "MSC sent AssignReq without expected OsmuxCID IE");
				mtc.stop;
			}
			bssap := valueof(ts_BSSMAP_AssignmentComplete(omit, tla, codec, osmuxCID));
		} else {
			bssap := valueof(ts_BSSMAP_AssignmentComplete(omit, tla, codec));
		}
		BSSAP.send(bssap);
		}
	/*
	[!g_pars.ran_is_geran] BSSAP.receive(tr_RANAP_RabAssReq(rab_sml)) {
		//BSSAP.send(ts_RANAP_RabAssResp(rab_sml)); FIXME
		}
	*/

	/* MDCX setting up the RAN side remote RTP address received from Assignment Complete */
	[] MGCP.receive(tr_MDCX) -> value mgcp_cmd {
		log("f_mo_call_establish 5: rx MDCX for the RAN side");
		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)) }));

		if (cpars.use_osmux) {
			osmux_cid := f_MgcpCmd_extract_osmux_cid(mgcp_cmd);
			if (osmux_cid != 0) { /* we expect MSC to use specific CID here */
				setverdict(fail, "MSC using unexpected CID " & int2str(osmux_cid) & " != 0");
				mtc.stop;
			}
			mgcp_resp := ts_MDCX_ACK_osmux(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_bss, osmux_cid, sdp);
		} else {
			mgcp_resp := ts_MDCX_ACK(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_mss, sdp);
		}
		MGCP.send(mgcp_resp);
		}

	/* Second MGCP CRCX (this time for MSS/CN side) */
	[] MGCP.receive(tr_CRCX(cpars.mgcp_ep)) -> value mgcp_cmd {
		log("f_mo_call_establish 6: rx 2nd CRCX, for CN side");
		var SDP_Message sdp := valueof(ts_SDP_CRCX_CN(cpars));
		MGCP.send(ts_CRCX_ACK(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_mss, sdp));
		}

	[] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_ALERTING(cpars.transaction_id))) {
		log("f_mo_call_establish 7: rx CC Alerting");
		cpars.mncc_callref := mncc.u.signal.callref;
		/* Call Proceeding */
		MNCC.send(ts_MNCC_RTP_CONNECT(cpars.mncc_callref,
					      /* ip 42.23.11.5 */ hex2int('42231105'H),
					      /* port 423 */ 423,
					      /* payload type 3 = GSM FR */ 3));
		MNCC.send(ts_MNCC_SETUP_rsp(cpars.mncc_callref));
		}

	[] MNCC.receive(tr_MNCC_SETUP_COMPL_ind(?)) -> value mncc {
		log("f_mo_call_establish 8: rx MNCC SETUP COMPLETE ind");
		}

	/* second MDCX setting up the CN side remote RTP address and codec received from MNCC RTP CONNECT */
	[] MGCP.receive(tr_MDCX) -> value mgcp_cmd {
		log("f_mo_call_establish 9: rx MDCX for CN side");
		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_MDCX_ACK(mgcp_cmd.line.trans_id, cpars.mgcp_connection_id_mss, sdp));
		}

	[] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_CONNECT(cpars.transaction_id))) {
		log("f_mo_call_establish 10: rx CC CONNECT");
		BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_CONNECT_ACK(cpars.transaction_id)));
		}
	}

	log("f_mo_call_establish DONE");
	setverdict(pass);
}

private altstep as_optional_mgcp_mdcx() runs on BSC_ConnHdlr {
	[] MGCP.receive(tr_MDCX) {};
}

function f_call_hangup(inout CallParameters cpars, boolean release_by_ms, boolean is_csfb := false)
runs on BSC_ConnHdlr {

	var MobileIdentityLV mi;
	var MNCC_PDU mncc;
	var MgcpCommand mgcp_cmd;
	var boolean respond_to_dlcx;
	var boolean dlcx_contained_ci := false;
	var template PDU_BSSAP t_clear := tr_BSSMAP_ClearCommand;

	if (is_csfb) {
		t_clear := tr_BSSMAP_ClearCommandCSFB;
	}

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

	log("f_call_hangup 1: rx DTAP CC DISC");

	if (release_by_ms) {
		var BIT1 tid_remote := '1'B;
		if (cpars.mo_call) {
			tid_remote := '0'B;
		}
		/* B-side (MS) Release of call */
		BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_RELEASE(cpars.transaction_id, tid_remote, '0000000'B)));
		MNCC.receive(tr_MNCC_REL_ind(cpars.mncc_callref));
		log("f_call_hangup 2: rx MNCC REL ind");
		BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_REL_COMPL(cpars.transaction_id)));
		log("f_call_hangup 3: rx DTAP CC REL COMPL");
	} 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)));
		log("f_call_hangup 4: rx DTAP CC RELEASE");
		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));

	var default mdcx := activate(as_optional_mgcp_mdcx());

	/* clearing of radio channel */
	interleave {
	//[g_pars.ran_is_geran] BSSAP.receive(t_clear) {
	[] BSSAP.receive(t_clear) {
		log("f_call_hangup 5: rx BSSAP Clear Command");
		BSSAP.send(ts_BSSMAP_ClearComplete);
		BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
		log("f_call_hangup 6: rx SCCP DISC");
		}
	/*
	[!g_pars.ran_is_geran] BSSAP.receive(t_iurel) {
		BSSAP.send(ts_RANAP_IuReleaseComplete);
		BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
		}
	*/
	[] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
			log("f_call_hangup 7: rx MGCP DLCX");
			if (respond_to_dlcx) {
				MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
			}
			dlcx_contained_ci := f_MgcpCmd_contains_par(mgcp_cmd, "I");
		}
	}

	/* Two DLCXes expected, one for RAN and one for CN side.
	 * Unless the first DLCX did not contain a CI, in which case it was a wildcard DLCX for both. */
	if (dlcx_contained_ci) {
		MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
			log("f_call_hangup 8: rx MGCP DLCX");
			if (respond_to_dlcx) {
				MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
			}
		}
	}

	f_create_mgcp_delete_ep(cpars.mgcp_ep);
	log("f_call_hangup 9: done");

	deactivate(mdcx);

	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");
		mtc.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");
		mtc.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");
		mtc.stop;
		}
	}

	setverdict(pass);
}

/* expect a clear command */
altstep as_clear_cmd_compl_disc(float t := 5.0) runs on BSC_ConnHdlr {
	var PDU_BSSAP bssap;
	[] BSSAP.receive(tr_BSSMAP_ClearCommand) {
		BSSAP.send(ts_BSSMAP_ClearComplete);
		alt {
		[] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
			setverdict(pass);
			}
		[] BSSAP.receive {
			setverdict(fail, "Unexpected BSSMAP while waiting for SCCP Release");
			mtc.stop;
			}
		}
		}
	[] BSSAP.receive(tr_BSSAP_BSSMAP) -> value bssap {
		setverdict(fail, "Unexpected BSSMAP while waiting for ClearCommand", bssap);
		mtc.stop;
		}
}

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

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

function f_create_bssmap_exp_handoverRequest(integer targetPointCode) runs on BSC_ConnHdlr {
	BSSAP_PROC.call(RAN_register_handoverRequest:{targetPointCode, self}) {
		[] BSSAP_PROC.getreply(RAN_register_handoverRequest:{?, ?}) {};
	}
}

function f_bssmap_last_n_sd() runs on BSC_ConnHdlr return N_Sd_Array {
	var N_Sd_Array last_n_sd;
	BSSAP_PROC.call(RAN_last_n_sd:{self, -}) {
		[] BSSAP_PROC.getreply(RAN_last_n_sd:{self, ?}) -> param(last_n_sd) {
				return last_n_sd;
			};
	}
}

function f_bssmap_continue_after_n_sd(N_Sd_Array last_n_sd) runs on BSC_ConnHdlr {
	BSSAP_PROC.call(RAN_continue_after_n_sd:{last_n_sd, self}) {
		[] BSSAP_PROC.getreply(RAN_continue_after_n_sd:{last_n_sd, self});
	}
}

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");
		mtc.stop;
	}
}

/* Submit a MO RP-SMMA over an already existing DTAP connection */
function f_mo_smma(inout SmsParameters spars)
runs on BSC_ConnHdlr {
	var template (value) RPDU_MS_SGSN rp_mo;
	var template (value) PDU_ML3_MS_NW l3_mo;

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

	rp_mo := ts_RP_SMMA_MO(spars.rp.msg_ref);
	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));

	deactivate(d);
	setverdict(pass);
}

/* Submit a MO-SMS over an already existing DTAP connection */
function f_mo_sms_submit(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 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));

	deactivate(d);
	setverdict(pass);
}

/* Wait RP-ACK for MO-SMS on an already existing DTAP connection */
function f_mo_sms_wait_rp_ack(inout SmsParameters spars)
runs on BSC_ConnHdlr {
	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));

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

/* Submit a MO-SMS, and wait for RP-ACK on an existing
 * (and authenticated, ...) DTAP connection */
function f_mo_sms(inout SmsParameters spars)
runs on BSC_ConnHdlr {
	f_mo_sms_submit(spars);
	f_mo_sms_wait_rp_ack(spars);
}

/* Wait for MT SMS on an already existing DTAP connection */
function f_mt_sms_expect(inout SmsParameters spars)
runs on BSC_ConnHdlr {
	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));

	deactivate(d);
	setverdict(pass);
}

/* Send RP-ACK for MT-SMS over an already existing DTAP connection */
function f_mt_sms_send_rp_ack(inout SmsParameters spars)
runs on BSC_ConnHdlr {
	var template (value) RPDU_MS_SGSN rp_mo;
	var template (value) PDU_ML3_MS_NW l3_mo;
	var template PDU_ML3_NW_MS l3_mt;

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

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

/* Send RP-ERROR for MT-SMS over an already existing DTAP connection */
function f_mt_sms_send_rp_error(inout SmsParameters spars, uint7_t cause)
runs on BSC_ConnHdlr {
	var template (value) RPDU_MS_SGSN rp_mo;
	var template (value) PDU_ML3_MS_NW l3_mo;
	var template PDU_ML3_NW_MS l3_mt;

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

	/* send RP-ACK for RP-DATA */
	rp_mo := ts_RP_ERROR_MO(spars.rp.msg_ref, cause);
	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-ERROR) 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);
}

/* Wait for a MT-SMS and send RP-ACK over an already existing
 * (and authenticated, ...) DTAP connection */
function f_mt_sms(inout SmsParameters spars)
runs on BSC_ConnHdlr {
	f_mt_sms_expect(spars);
	f_mt_sms_send_rp_ack(spars);
}


}


