/* 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 TCCOpenSecurity_Functions all;
import from General_Types all;
import from Osmocom_Types all;
import from Native_Functions all;
import from Misc_Helpers 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;

import from TCCConversion_Functions { function f_strstr };

/* 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,
	OCT4 gsup_sid,
	integer ran_idx,
	boolean use_umts_aka,
	boolean ran_is_geran,
	boolean use_osmux,
	boolean use_ipv6,
	boolean verify_cell_id,
	OCT3 common_id_last_eutran_plmn optional
};

/* get a one-octet bitmaks of supported algorithms based on Classmark information */
function f_alg_mask_from_cm(BSSMAP_IE_ClassmarkInformationType2 cm2, template (omit) BSSMAP_IE_ClassmarkInformationType3 cm3 := omit) 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;
	}
	if (not istemplatekind(cm3, "omit")) {
		var BSSMAP_IE_ClassmarkInformationType3 v := valueof(cm3);
		var BIT8 tmp := oct2bit(v.classmark3ValuePart[0]) and4b '00001111'B;
		res := res or4b (tmp << 4);
	}

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

/* return true for A5/x supported by OCT1 bitmask */
function f_alg_supported_by_mask(OCT1 mask_in, integer whicha5) return boolean {
	var BIT8 mask := oct2bit(mask_in);
	if (mask and4b ('00000001'B << whicha5) != '00000000'B) {
		return true;
	}
	return false;
}

/* 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_client(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_verify_vty_lac_ci(verify_vlr := false);

	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));
		g_pars.vec.kc := f_auth3g_kc();
	} 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 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 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_expect_common_id() runs on BSC_ConnHdlr
{
	if (g_pars.ran_is_geran) {
		BSSAP.receive(tr_BSSMAP_CommonId(g_pars.imsi,
						 f_tr_BSSMAP_LastUsedEUTRANPLMNId(g_pars.common_id_last_eutran_plmn)));
	} else {
		BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)));
	}
}

function f_auth3g_kc() runs on BSC_ConnHdlr return OCT8 {
	var integer i;
	var octetstring res := g_pars.vec.ck[0] xor4b g_pars.vec.ck[0 + 8] xor4b g_pars.vec.ik[0] xor4b g_pars.vec.ik[0 + 8];
	for (i := 1; i < 8; i := i + 1) {
		var octetstring a := g_pars.vec.ck[i] xor4b g_pars.vec.ck[i + 8] xor4b g_pars.vec.ik[i] xor4b g_pars.vec.ik[i + 8];
		res := res & a;
	}

	return res;
}


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, g_pars.cm3);
			var OCT1 a5_intersect := g_pars.net.kc_support and4b a5_net;
			var boolean has_a54 := f_alg_supported_by_mask(a5_intersect, 4);

			var PDU_BSSAP pdu;
			alt {
				[] BSSAP.receive(tr_BSSMAP_CipherModeCmd(a5_intersect, g_pars.vec.kc)) -> value pdu {
				var PDU_BSSMAP_CipherModeCommand ciphmodcmd := pdu.pdu.bssmap.cipherModeCommand;
				if (g_pars.use_umts_aka and has_a54) {
					var OCT32 fulloutput := f_calculate_HMAC_SHA256(g_pars.vec.ck & g_pars.vec.ik, '32'O, 32);
					var OCT16 kc128 := substr(fulloutput, 0, 16);
					if (not ispresent(ciphmodcmd.kC128)) {
						setverdict(fail, "kc128 missing in CiphModCmd");
						mtc.stop;
					}
					if (ciphmodcmd.kC128.kC128_Value != kc128) {
						setverdict(fail, "kc128 wrong in CiphModCmd?!", kc128);
						mtc.stop;
					}
				} else {
					if (ispresent(ciphmodcmd.kC128)) {
						setverdict(fail, "kc128 present in CiphModCmd, but should not exist!");
						mtc.stop;
					}
				}

				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;
				}
			[] BSSAP.receive(tr_BSSMAP_ClassmarkRequest) {
				BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3))
				repeat;
				}
			}
			/* FIXME: Send the best available algorithm */
		}
		f_expect_common_id();
	} 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));
			f_expect_common_id();
			}
		[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));
			f_expect_common_id();
			}
		[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));
	 }
}

private function f_lac_ci_vty_str(BSSMAP_IE_CellIdentifier cell_id) return charstring
{
	return "LAC / cell ID: "
		& int2str(oct2int(cell_id.cellIdentification.cI_CGI.lac)) & " / "
		& int2str(oct2int(cell_id.cellIdentification.cI_CGI.ci));
}

/* Get an IMSI's info and verify that the g_pars.cell_id is reflected in the info.
 * Verify both the "LAC / cell ID" in the VLR and the "LAC / cell ID" in the "Connection:" part, if any.
 * If verify_vlr == false, then only verify the "Connection:" part, and fail if there is no "Connection:"; this is
 * useful when a conn has been established, but the subscriber has not been authenticated, so the VLR does not yet
 * reflect the new conn's cell ID.
 */
function f_verify_vty_lac_ci(boolean verify_vlr := true) runs on BSC_ConnHdlr {
	if (not g_pars.ran_is_geran) {
		 log("Skipping f_verify_vty_lac_ci(), disabled for Iu");
		 setverdict(pass);
		 return;
	}
	if (not g_pars.verify_cell_id) {
		/* Skip this verification; either the TC expects no cell id to end up being accepted, or this was
		 * disabled globally to test an older osmo-msc which doesn't store the cell id properly yet. */
		 log("Skipping f_verify_vty_lac_ci()");
		 setverdict(pass);
		 return;
	}

	var charstring vty_cmd := "show subscriber imsi " & hex2str(g_pars.imsi) & " conn";
	var charstring result := f_vty_transceive_ret(MSCVTY, vty_cmd);
	var charstring expect_lac_ci := "LAC / cell ID: "
		& int2str(oct2int(g_pars.cell_id.cellIdentification.cI_CGI.lac)) & " / "
		& int2str(oct2int(g_pars.cell_id.cellIdentification.cI_CGI.ci));

	var boolean vlr_matches := false;
	var boolean connection_present := false;
	var boolean connection_matches := false;

	/* There are two occurences of LAC / cell ID: once for the VLR record, and once for the active connection. The
	 * active connection part starts with 'Connection:'. If there is no active connection, that part is omitted.
	 * So, first find out whether there is a 'Connection:' part. Then verify the LAC / cell ID above 'Connection:'
	 * and below 'Connection:', separately.
	 */
	var integer connection_start := f_strstr(result, "Connection:");
	connection_present := (connection_start >= 0);

	var integer lac_ci_match := f_strstr(result, expect_lac_ci);
	if (connection_present) {
		if (lac_ci_match > connection_start) {
			/* The first match is below 'Connection:', so the VLR part above it did not match. */
			vlr_matches := false;
			connection_matches := true;
		} else if (lac_ci_match >= 0) {
			/* The first match is above 'Connection:', so the VLR part matches. */
			vlr_matches := true;

			/* Now find a match below 'Connection:' */
			lac_ci_match := f_strstr(result, expect_lac_ci, connection_start);
			connection_matches := (lac_ci_match > 0);
		}
	} else {
		/* There is no 'Connection:', so a match, if any, is from the VLR part. */
		vlr_matches := (lac_ci_match >= 0);
	}

	if (verify_vlr) {
		if (not vlr_matches) {
			setverdict(fail, vty_cmd, " shows mismatching LAC / cell ID in the VLR part, expecting: ",
				   expect_lac_ci, " -- got: ", result);
			return;
		} else {
			log("f_verify_vty_lac_ci(): VLR record matches ", expect_lac_ci);
			setverdict(pass);
		}
	}

	if (connection_present) {
		if (not connection_matches) {
			setverdict(fail, vty_cmd, " shows mismatching LAC cell ID in the 'Connection' part, expecting: ",
				   expect_lac_ci, " -- got: ", result);
		} else {
			log("f_verify_vty_lac_ci(): Active connection matches ", expect_lac_ci);
			setverdict(pass);
		}
	}

	if (not verify_vlr and not connection_present) {
		setverdict(fail, "f_verify_vty_lac_ci(verify_vlr := false) called, which requires an active connection, but there is no 'Connection:' part to verify in ", result);
	}
}

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

	/* at this point the conn has been established, but the subscriber has not been authenticated, so the VLR does
	 * not yet reflect this conn's cell ID. */
	f_verify_vty_lac_ci(verify_vlr := false);

	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_expect_lu_reject(template OCT1 cause := ?) runs on BSC_ConnHdlr {
	var PDU_DTAP_MT dtap_mt;
	timer T := 5.0;

	T.start;
	alt {
	[] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej(cause))) {
		setverdict(pass);
		}
	[] BSSAP.receive(tr_PDU_DTAP_MT(?)) -> value dtap_mt {
		setverdict(fail, "Expected LU reject BSSAP message, got: ", dtap_mt);
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for LU reject");
		}
	}
}

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

type record CrcxResponse {
	integer resp,	/* 1 = reply with OK, 0 = do not reply, -1 = reply with error */
	HostName mgw_rtp_ip,
	PortNumber mgw_rtp_port,
	MgcpConnectionId mgcp_connection_id	/* MGCP Connection ID BSS Side */
}

/* 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 */
	HostName mncc_rtp_ip optional,			/* MNCC Side RTP IP */
	PortNumber mncc_rtp_port optional,		/* MNCC Side RTP port */

	/* 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 */
	integer got_crcx_count,
	CrcxResponse mgw_conn_1,
	CrcxResponse mgw_conn_2,
	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) */
	boolean stop_after_cc_setup,			/* Special case: stop call establish after CC Setup */
	boolean ran_clear_when_alerting,		/* Special case: send Clear upon CC Alerting */
	boolean expect_release,				/* Special case: expect call establish to cause direct CC Rel */

	MgcpCallId mgcp_call_id optional,		/* MGCP Call ID; CallAgent allocated */
	MgcpEndpoint mgcp_ep optional			/* MGCP Endpoint, CallAgent or MGW allocated */,

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

template (value) CallParameters t_CallParams(hexstring called := '12345'H, integer tid := 0) := {
	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),
	mncc_rtp_ip := "42.23.11.5",
	mncc_rtp_port := 423,
	bss_rtp_ip := "9.8.7.6",
	bss_rtp_port := 9000,
	mss_rtp_ip := omit,
	mss_rtp_port := omit,
	got_crcx_count := 0,
	mgw_conn_1 := {
		resp := 1,
		mgw_rtp_ip := "1.1.1.1",
		mgw_rtp_port := 10000,
		mgcp_connection_id := '11111'H
	},
	mgw_conn_2 := {
		resp := 1,
		mgw_rtp_ip := "2.2.2.2",
		mgw_rtp_port := 11000,
		mgcp_connection_id := '22222'H
	},
	rtp_payload_type := 98,
	rtp_sdp_format := "AMR/8000",
	mgw_drop_dlcx := false,
	stop_after_cc_setup := false,
	ran_clear_when_alerting := false,
	expect_release := false,
	mgcp_call_id := omit,
	mgcp_ep := "rtpbridge/1@mgw",
	use_osmux := false,
	got_osmux_count := 0
};

/* Allocate a call reference and send SETUP via MNCC to MSC */
function f_mt_call_initate(inout CallParameters cpars)
runs on BSC_ConnHdlr {
	cpars.mo_call := false;
	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_conn_2.mgw_rtp_ip, cpars.mgw_conn_2.mgw_rtp_ip,
		hex2str(cpars.mgcp_call_id), "42",
		cpars.mgw_conn_2.mgw_rtp_port,
		{ 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");

	cpars.got_osmux_count := 0;

	/* 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 */
	MGCP.receive(tr_CRCX) -> value mgcp_cmd {
		log("f_mt_call_complete 3");
		if (not f_handle_crcx(cpars, mgcp_cmd)) {
			return;
		}
		}


	if (g_pars.ran_is_geran) {
		var template BSSMAP_IE_AoIP_TransportLayerAddress tla_ass :=
			f_tr_BSSMAP_IE_AoIP_TLA(cpars.mgw_conn_1.mgw_rtp_ip, ?);

		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");
			if (not f_handle_crcx(cpars, mgcp_cmd)) {
				break;
			}
			}

		/* 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 template BSSMAP_IE_AoIP_TransportLayerAddress tla;
			var BSSMAP_IE_SpeechCodec codec;
			var BSSMAP_IE_Osmo_OsmuxCID osmuxCID;
			log("f_mt_call_complete 6");
			tla := f_ts_BSSMAP_IE_AoIP_TLA(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 (not match(bssap.pdu.bssmap.assignmentRequest.osmuxCID, osmuxCID)) {
					setverdict(fail, "MSC sent AssignReq without expected OsmuxCID IE. Expected ", osmuxCID, " Got ", bssap.pdu.bssmap.assignmentRequest.osmuxCID);
					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");
			var octetstring ip;
			var boolean is_ipv6 := f_addr_is_ipv6(cpars.mncc_rtp_ip);
			if (is_ipv6) {
				ip := f_inet6_addr(cpars.mncc_rtp_ip);
			} else {
				ip := f_inet_addr(cpars.mncc_rtp_ip);
			}
			MNCC.send(ts_MNCC_RTP_CONNECT(cpars.mncc_callref,
						      is_ipv6, ip,
						      cpars.mncc_rtp_port,
						      /* 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_conn_1.mgw_rtp_ip, cpars.mgw_conn_1.mgw_rtp_ip,
								hex2str(cpars.mgcp_call_id), "42",
								cpars.mgw_conn_1.mgw_rtp_port,
								{ 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.mgw_conn_1.mgcp_connection_id, osmux_cid, sdp);
			} else {
				mgcp_resp := ts_MDCX_ACK(mgcp_cmd.line.trans_id, cpars.mgw_conn_1.mgcp_connection_id, 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 {
			var SDP_Message sdp;
			log("f_mt_call_complete 9");

			if (isvalue(mgcp_cmd.sdp)) {
				sdp := mgcp_cmd.sdp;
				if (sdp.media_list[0].media_field.ports.port_number != cpars.mncc_rtp_port) {
					setverdict(fail, "Wrong MDCX Connection port received, expected ", cpars.mncc_rtp_port, " and received ", sdp.media_list[0].media_field.ports.port_number)
					mtc.stop;
				}
				if (sdp.connection.conn_addr.addr != cpars.mncc_rtp_ip) {
					setverdict(fail, "Wrong MDCX Connection address received, expected ", cpars.mncc_rtp_ip, " and received ", sdp.connection.conn_addr.addr)
					mtc.stop;
				}
			}

			sdp := valueof(ts_SDP(cpars.mgw_conn_2.mgw_rtp_ip, cpars.mgw_conn_2.mgw_rtp_ip,
						hex2str(cpars.mgcp_call_id), "42",
						cpars.mgw_conn_2.mgw_rtp_port,
						{ 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.mgw_conn_2.mgcp_connection_id, sdp));
			}

		}
	} else {
		interleave {
		[] MGCP.receive(tr_CRCX(cpars.mgcp_ep)) -> value mgcp_cmd {
			log("f_mt_call_complete 4.iu");
			if (not f_handle_crcx(cpars, mgcp_cmd)) {
				break;
			}
			}

		/* MSC acknowledges the MNCC_CREATE to the MNCC handler */
		[] MNCC.receive(tr_MNCC_RTP_CREATE(cpars.mncc_callref)) {
			log("f_mt_call_complete 5.iu");
			}

		[] BSSAP.receive(tr_RANAP_RabAssReq(?)) {
			log("f_mt_call_complete 6.iu");
			var RAB_SetupOrModifiedList l := {
				{
					{
						id := id_RAB_SetupOrModifiedItem,
						criticality := ignore,
						value_ := {
						  rAB_SetupOrModifiedItem := {
							rAB_ID := int2bit(23, 8),
							transportLayerAddress := hex2bit( '350001c0a8021500000000000000000000000000'H),
							iuTransportAssociation := {
								bindingID := '040c0000'O
							},
							dl_dataVolumes := omit,
							iE_Extensions := omit
							}
						}
					}
				}
			};
			BSSAP.send(ts_RANAP_RabAssResp(l));

			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.iu");
			var octetstring ip;
			var boolean is_ipv6 := f_addr_is_ipv6(cpars.mncc_rtp_ip);
			if (is_ipv6) {
				ip := f_inet6_addr(cpars.mncc_rtp_ip);
			} else {
				ip := f_inet_addr(cpars.mncc_rtp_ip);
			}
			MNCC.send(ts_MNCC_RTP_CONNECT(cpars.mncc_callref,
						      is_ipv6, ip,
						      cpars.mncc_rtp_port,
						      /* 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.iu");
			var SDP_Message sdp := valueof(ts_SDP(cpars.mgw_conn_1.mgw_rtp_ip, cpars.mgw_conn_1.mgw_rtp_ip,
								hex2str(cpars.mgcp_call_id), "42",
								cpars.mgw_conn_1.mgw_rtp_port,
								{ 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.mgw_conn_1.mgcp_connection_id, osmux_cid, sdp);
			} else {
				mgcp_resp := ts_MDCX_ACK(mgcp_cmd.line.trans_id, cpars.mgw_conn_1.mgcp_connection_id, 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.iu");
			var SDP_Message sdp := valueof(ts_SDP(cpars.mgw_conn_2.mgw_rtp_ip, cpars.mgw_conn_2.mgw_rtp_ip,
								hex2str(cpars.mgcp_call_id), "42",
								cpars.mgw_conn_2.mgw_rtp_port,
								{ 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.mgw_conn_2.mgcp_connection_id, sdp));
			}

		}
	}

	if (cpars.use_osmux == (cpars.got_osmux_count != 0)) {
		log("Osmux ok: use_osmux = ", cpars.use_osmux, " got_osmux_count = ", cpars.got_osmux_count);
	} else {
		setverdict(fail, "Osmux failure: use_osmux = ", cpars.use_osmux, " got_osmux_count = ", cpars.got_osmux_count);
		mtc.stop;
	}

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

/* Reply to a received CRCX with an OK (or the reply configured in cpars), using the given parameters.
 * Return true when an OK reply was sent, false otherwise.
 * Count occurence of Osmux, include Osmux parameters in the reply if necessary. */
function f_handle_crcx(inout CallParameters cpars, MgcpCommand mgcp_cmd)
runs on BSC_ConnHdlr
return boolean {
	var CrcxResponse conn := cpars.mgw_conn_1;
	if (cpars.got_crcx_count > 0) {
		conn := cpars.mgw_conn_2;
	}
	cpars.got_crcx_count := cpars.got_crcx_count + 1;

	var MgcpMessage mgcp_msg := {
		command := mgcp_cmd
	}
	var template MgcpResponse mgcp_resp;
	var MgcpOsmuxCID osmux_cid;
	var MgcpCallId call_id := f_MgcpCmd_extract_call_id(mgcp_cmd);
	if (ispresent(cpars.mgcp_call_id)) {
		if (cpars.mgcp_call_id != call_id) {
			setverdict(fail, "CRCX contained unexpected call id. Expected:", cpars.mgcp_call_id, " got:", call_id);
			mtc.stop;
		}
	} else {
		cpars.mgcp_call_id := call_id;
	}

	/* 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 (conn.resp == -1) {
		/* Reply with error */
		var MgcpResponse mgcp_rsp := {
			line := {
				code := "542",
				trans_id := mgcp_cmd.line.trans_id,
				string := "FORCED_FAIL"
			},
			sdp := omit

		}
		var MgcpParameter mgcp_rsp_param := {
			code := "Z",
			val := cpars.mgcp_ep
		};
		mgcp_rsp.params[0] := mgcp_rsp_param;
		MGCP.send(mgcp_rsp);
		return false;
	}

	if (conn.resp == 0) {
		/* Do not reply at all */
		return false;
	}

	if (conn.resp != 1) {
		setverdict(fail, "Unexpected value for cpars.mgw_conn_*.resp, expect -1, 0 or 1");
		mtc.stop;
	}

	var SDP_Message sdp := valueof(ts_SDP(conn.mgw_rtp_ip, conn.mgw_rtp_ip,
						hex2str(cpars.mgcp_call_id), "42",
						conn.mgw_rtp_port,
						{ int2str(cpars.rtp_payload_type) },
						{ valueof(ts_SDP_rtpmap(cpars.rtp_payload_type,
									cpars.rtp_sdp_format)),
						  valueof(ts_SDP_ptime(20)) }));

	if (f_mgcp_contains_par(mgcp_msg, "X-OSMUX")) {
		if (not cpars.use_osmux) {
			setverdict(fail, "MSC sent X-Osmux parameter in MGCP, but not expecting any Osmux");
			mtc.stop;
		}
		cpars.got_osmux_count := cpars.got_osmux_count + 1;
		/* we expect MSC to use wildcard here, i.e. osmux_cid == -1 */
		osmux_cid := f_MgcpCmd_extract_osmux_cid(mgcp_cmd);
		log("f_handle_crcx(): got Osmux CID: ", osmux_cid);
		if (osmux_cid != -1) {
			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, conn.mgcp_connection_id, osmux_cid, sdp);
	} else {
		mgcp_resp := ts_CRCX_ACK(mgcp_cmd.line.trans_id, conn.mgcp_connection_id, sdp);
	}

	f_mgcp_par_append(mgcp_resp.params, ts_MgcpParSpecEP(cpars.mgcp_ep));
	MGCP.send(mgcp_resp);
	return true;
}


altstep as_optional_mgcp_crcx(CallParameters cpars) runs on BSC_ConnHdlr {
	var MgcpCommand mgcp_cmd;
	[] MGCP.receive(tr_CRCX) -> value mgcp_cmd {
		log("as_optional_mgcp_crcx: rx CRCX");
		f_handle_crcx(cpars, mgcp_cmd);

		/* Without this 'repeat', the as_optional_mgcp_crcx() exits currently waiting interleaves as soon as an
		 * CRCX is handled. */
		repeat;
		}
}

private altstep as_optional_mgcp_mdcx(HostName mgw_rtp_ip, PortNumber mgw_rtp_port) runs on BSC_ConnHdlr {
	var MgcpCommand mgcp_cmd;
	[] MGCP.receive(tr_MDCX) -> value mgcp_cmd {
		log("as_optional_mgcp_mdcx: rx MDCX");
		log(mgcp_cmd);
		var charstring conn_id;
		var charstring rtp_payload_type;
		f_mgcp_find_param_entry(mgcp_cmd.params, "I", conn_id);
		rtp_payload_type := mgcp_cmd.sdp.media_list[0].media_field.fmts[0];

		var SDP_Message sdp := valueof(ts_SDP(mgw_rtp_ip, mgw_rtp_ip,
							mgcp_cmd.sdp.origin.session_id, "42",
							mgw_rtp_port,
							{ rtp_payload_type },
							{ valueof(ts_SDP_ptime(20)) }));
		MGCP.send(ts_MDCX_ACK(mgcp_cmd.line.trans_id, str2hex(conn_id), sdp));

		/* Without this 'repeat', currently active other interleave and alt series exit as soon as an MDCX is
		 * handled. */
		repeat;
	}
}

private altstep as_optional_mgcp_dlcx(CallParameters cpars) runs on BSC_ConnHdlr {
	var MgcpCommand mgcp_cmd;
	var boolean respond_to_dlcx := not (isbound(cpars.mgw_drop_dlcx) and valueof(cpars.mgw_drop_dlcx));
	[] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
		log("as_optional_mgcp_dlcx: rx MGCP DLCX");
		if (respond_to_dlcx) {
			MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
		}
		/* Without this 'repeat', currently active other interleave and alt series exit as soon as a
		 * DLCX is handled. */
		repeat;
	}
}

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 RANAP_PDU ranap;
	var MgcpOsmuxCID osmux_cid;

	cpars.mo_call := true;

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

	if (cpars.stop_after_cc_setup) {
		return;
	}

	var template BSSMAP_IE_AoIP_TransportLayerAddress tla_ass :=
		f_tr_BSSMAP_IE_AoIP_TLA(cpars.mgw_conn_1.mgw_rtp_ip, ?);

	var default mdcx := activate(as_optional_mgcp_mdcx(cpars.mgw_conn_2.mgw_rtp_ip, cpars.mgw_conn_2.mgw_rtp_port));
	var boolean got_mncc_setup_compl_ind := false;
	var boolean got_cc_connect := false;

	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 */
	[] MGCP.receive(tr_CRCX) -> value mgcp_cmd {
		log("f_mo_call_establish 2: rx 1st CRCX");
		if (not f_handle_crcx(cpars, mgcp_cmd)) {
			break;
		}
		}

	/* Second MGCP CRCX */
	[] MGCP.receive(tr_CRCX(cpars.mgcp_ep)) -> value mgcp_cmd {
		log("f_mo_call_establish 6: rx 2nd CRCX");
		if (not f_handle_crcx(cpars, mgcp_cmd)) {
			break;
		}
		}

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

		if (not match(bssap.pdu.bssmap.assignmentRequest.aoIPTransportLayer, tla_ass)) {
			log("Expected:", tla_ass);
			log("Got:", bssap.pdu.bssmap.assignmentRequest.aoIPTransportLayer);
			setverdict(fail, "MSC sent Assignment Request with unexpected AoIP Transport Layer IE");
			mtc.stop;
		}

		tla := valueof(f_ts_BSSMAP_IE_AoIP_TLA(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.receive(tr_RANAP_RabAssReq(*)) -> value ranap {
		log("f_mo_call_establish 4.iu: rx RANAP RAB Assignment Request");
		var RAB_SetupOrModifiedList l := {
			{
				{
					id := id_RAB_SetupOrModifiedItem,
					criticality := ignore,
					value_ := {
					  rAB_SetupOrModifiedItem := {
						rAB_ID := int2bit(23, 8),
						transportLayerAddress := hex2bit( '350001c0a8021500000000000000000000000000'H),
						iuTransportAssociation := {
							bindingID := '040c0000'O
						},
						dl_dataVolumes := omit,
						iE_Extensions := omit
						}
					}
				}
			}
		};
		BSSAP.send(ts_RANAP_RabAssResp(l));
		}

	/* 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_conn_1.mgw_rtp_ip, cpars.mgw_conn_1.mgw_rtp_ip,
							hex2str(cpars.mgcp_call_id), "42",
							cpars.mgw_conn_1.mgw_rtp_port,
							{ 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.mgw_conn_1.mgcp_connection_id, osmux_cid, sdp);
		} else {
			mgcp_resp := ts_MDCX_ACK(mgcp_cmd.line.trans_id, cpars.mgw_conn_1.mgcp_connection_id, sdp);
		}
		MGCP.send(mgcp_resp);
		}

	[] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_ALERTING(cpars.transaction_id))) {
		log("f_mo_call_establish 7: rx CC Alerting");

		if (cpars.ran_clear_when_alerting) {
			if (g_pars.ran_is_geran) {
				BSSAP.send(ts_BSSMAP_ClearRequest(0));
			} else {
				BSSAP.send(ts_RANAP_IuReleaseRequest(ts_RanapCause_om_intervention));
			}
			break;
		}

		cpars.mncc_callref := mncc.u.signal.callref;
		/* Call Proceeding */
		var octetstring ip;
		var boolean is_ipv6 := f_addr_is_ipv6(cpars.mncc_rtp_ip);
		if (is_ipv6) {
			ip := f_inet6_addr(cpars.mncc_rtp_ip);
		} else {
			ip := f_inet_addr(cpars.mncc_rtp_ip);
		}
		MNCC.send(ts_MNCC_RTP_CONNECT(cpars.mncc_callref,
					      is_ipv6, ip,
					      cpars.mncc_rtp_port,
					      /* 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");
		got_mncc_setup_compl_ind := true;
		if (not cpars.expect_release and got_cc_connect) {
			break;
		}
		}

	[] 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)));
		got_cc_connect := true;
		if (not cpars.expect_release and got_mncc_setup_compl_ind) {
			break;
		}
		}

	[] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id))) {
		log("f_mo_call_establish 11: rx CC RELEASE");
		if (not cpars.expect_release) {
			setverdict(fail, "Got unexpected CC Release");
			mtc.stop;
		}
		f_expect_clear();
		break;
		}
	}

	f_sleep(0.5);
	deactivate(mdcx);

	if (cpars.use_osmux == (cpars.got_osmux_count != 0)) {
		log("Osmux ok: use_osmux = ", cpars.use_osmux, " got_osmux_count = ", cpars.got_osmux_count);
	} else {
		setverdict(fail, "Osmux failure: use_osmux = ", cpars.use_osmux, " got_osmux_count = ", cpars.got_osmux_count);
		mtc.stop;
	}

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

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

	log("f_call_hangup 0: tx MNCC_DISC_REQ");
	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(cpars.mgw_conn_2.mgw_rtp_ip, cpars.mgw_conn_2.mgw_rtp_port));
	var default dlcx := activate(as_optional_mgcp_dlcx(cpars));

	/* clearing of radio channel */
	alt {
	[g_pars.ran_is_geran] 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");
		setverdict(pass);
		}
	[not g_pars.ran_is_geran] BSSAP.receive(tr_RANAP_IuReleaseCommand(?)) {
		log("f_call_hangup 5.iu: rx Iu Release Command");
		BSSAP.send(ts_RANAP_IuReleaseComplete);
		BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
		log("f_call_hangup 6.iu: rx SCCP DISC");
		setverdict(pass);
		}
	}

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

	deactivate(mdcx);
	deactivate(dlcx);
}

function f_mt_call(inout CallParameters cpars)
runs on BSC_ConnHdlr {

	f_mt_call_establish(cpars);

	log("Hold the call for some time");
	f_sleep(3.0);

	log("Hangup");
	f_call_hangup(cpars, true);

	setverdict(pass);
}

function f_mo_call(inout CallParameters cpars)
runs on BSC_ConnHdlr {

	f_mo_call_establish(cpars);

	log("Hold the call for some time");
	f_sleep(3.0);

	log("Hangup");
	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_mo_call_establish(cpars);

	/* Send DTMF: send the exact same DTAP message twice, the dup should be filtered out by
	 * 3GPP TS 24.007 11.2.3.2 Message Type Octet / Duplicate Detection. */

	/* Find out the next NSD that will be used, from RAN emulation. */
	var N_Sd_Array last_n_sd := f_bssmap_last_n_sd();
	var uint2_t next_n_sd := f_next_n_sd(last_n_sd, 0 /* cc is index 0 */);

	/* Compose DTAP with this correct NSD */
	dtmf_dtap := ts_ML3_MO_CC_START_DTMF(cpars.transaction_id, "2");

	/* Here, pass skip_seq_patching == false so that the RAN Emulation NSD increments after this message. */
	BSSAP.send(ts_PDU_DTAP_MO(dtmf_dtap, '00'O, false));
	T.start;
	alt {
	[] MNCC.receive(tr_MNCC_START_DTMF_ind(cpars.mncc_callref, "2")) {
		log("f_mo_seq_dtmf_dup() 1: got first START_DTMF_ind");
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for START_DTMF_ind");
		mtc.stop;
		}
	}

	/* Send the exact same DTAP with above NSD, which is now incorrect (has not incremented), so that this message
	 * will get filtered by the duplicate detection. Write NSD into DTAP and pass skip_seq_patching == true. */
	dtmf_dtap.msgs.cc.startDTMF.nsd := int2bit(next_n_sd, 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")) {
		setverdict(fail, "f_mo_seq_dtmf_dup() 2: Received duplicate START_DTMF_ind");
		mtc.stop;
		}
	[] T.timeout { }
	}

	/* Here the NSD should be correct again and we see a DTMF. */
	dtmf_dtap := ts_ML3_MO_CC_START_DTMF(cpars.transaction_id, "3");
	BSSAP.send(ts_PDU_DTAP_MO(dtmf_dtap, '00'O, false));
	alt {
	[] MNCC.receive(tr_MNCC_START_DTMF_ind(cpars.mncc_callref, "3")) {
		log("f_mo_seq_dtmf_dup() 3: got second START_DTMF_ind");
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for final START_DTMF_ind");
		mtc.stop;
		}
	}

	f_call_hangup(cpars, true);
	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, boolean verify_vlr_cell_id := true) 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;
		}
	}

	if (verify_vlr_cell_id) {
		/* Now the conn is gone, but the VLR reflects the cell ID */
		f_verify_vty_lac_ci();
	}
}

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 smsc_addr 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 RP_NumberingPlan_and_NumberDigits t_RP_Addr(template hexstring addr,
						     template BIT4 npi := '0001'B,
						     template BIT3 ton := '001'B,
						     template BIT1 ext := '1'B) := {
	rP_NumberingPlanIdentification := npi,
	rP_TypeOfNumber := ton,
	rP_Ext := ext,
	rP_NumberDigits := 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,
		/* We don't really need to have both SM-RP-DA/OA here, because only one IE
		 * is included in MO/MT SMS, and in the most cases it's the SMSC address.
		 * NOTE: this address is currently hard-coded by OsmoMSC. */
		smsc_addr := t_RP_Addr('447785016005'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, omit, spars.rp.smsc_addr, 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);
}

function f_mt_sms_deliver_pdu(in SmsParameters spars)
runs on BSC_ConnHdlr
return template PDU_DTAP_MT {
	var template TPDU_RP_DATA_SGSN_MS tp_mt := tr_SMS_DELIVER(?, spars.tp.ud, spars.tp.pid, spars.tp.dcs, ?);
	var template RPDU_SGSN_MS rp_mt := tr_RP_DATA_MT(?, spars.rp.smsc_addr, omit, tp_mt);
	var template PDU_ML3_NW_MS l3_mt := tr_ML3_MT_SMS(?, c_TIF_ORIG, tr_CP_DATA_MT(rp_mt));
	return tr_PDU_DTAP_MT(l3_mt, spars.dlci);
}

/* 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 PDU_DTAP_MT dtap_mt;

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

	/* Expect CP-DATA(RP-DATA(SMS-DELIVER)) */
	BSSAP.receive(f_mt_sms_deliver_pdu(spars)) -> 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);
}


}
