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

type port BSC_ConnHdlr_Coord_PT message
{
	inout charstring, CallParameters;
} with { extension "internal" };


/* 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;
	port BSC_ConnHdlr_Coord_PT COORD;
}

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_ConnectionHandler generates an auth vector in as_GSUP_SAI(). For tests that want control over which
	 * vector is used, pass vec_keep := true to not regenerate a new auth vector in as_GSUP_SAI(). */
	boolean vec_keep,
	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,
	bssap_reset_retries := 1,
	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) {
		if (not g_pars.vec_keep) {
			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 {
		if (not g_pars.vec_keep) {
			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)));
	}
}

/* For UMTS AKA on GERAN, calculate the specific kc from the UMTS AKA ck and ik vectors. */
function f_auth3g_kc(AuthVector vec) return OCT8 {
	var integer i;
	var octetstring res := vec.ck[0] xor4b vec.ck[0 + 8] xor4b vec.ik[0] xor4b vec.ik[0 + 8];
	for (i := 1; i < 8; i := i + 1) {
		var octetstring a := vec.ck[i] xor4b vec.ck[i + 8] xor4b vec.ik[i] xor4b vec.ik[i + 8];
		res := res & a;
	}

	return res;
}

function f_get_expected_encryption(
	out template BSSMAP_IE_EncryptionInformation encryptionInformation,
	out template BSSMAP_IE_ChosenEncryptionAlgorithm chosenEncryptionAlgorithm,
	out template BSSMAP_IE_KC128 kC128,
	out OCT1 a5_perm_alg) runs on BSC_ConnHdlr
{
	var OCT1 a5_ms := f_alg_mask_from_cm(g_pars.cm2, g_pars.cm3);
	a5_perm_alg := g_pars.net.kc_support and4b a5_ms;

	if (not g_pars.net.expect_ciph) {
		encryptionInformation := *;
		chosenEncryptionAlgorithm := *;
		kC128 := *;
		return;
	}

	var OCT8 kc;
	if (g_pars.use_umts_aka) {
		kc := f_auth3g_kc(g_pars.vec);
	} else {
		kc := g_pars.vec.kc;
	}
	encryptionInformation := tr_BSSMAP_IE_EncrInfo(kc, a5_perm_alg);

	var OCT1 chosen_alg := int2oct(f_alg_from_mask(f_best_alg_from_mask(a5_perm_alg)) + 1, 1);
	chosenEncryptionAlgorithm := tr_BSSMAP_IE_ChosenEncryptionAlgorithm(chosen_alg);

	if (g_pars.use_umts_aka and f_alg_supported_by_mask(a5_perm_alg, 4)) {
		/* A5/4 is permitted, expecting kc128 to be present */
		var OCT32 full_sha256 := f_calculate_HMAC_SHA256(g_pars.vec.ck & g_pars.vec.ik, '32'O, 32);
		var OCT16 expect_kc128 := substr(full_sha256, 0, 16);
		kC128 := tr_BSSMAP_IE_Kc128(expect_kc128);
	} else {
		kC128 := omit
	}
}


private function f_mm_ciph_geran() runs on BSC_ConnHdlr
{
	var template BSSMAP_IE_EncryptionInformation encryptionInformation;
	var template BSSMAP_IE_ChosenEncryptionAlgorithm chosenEncryptionAlgorithm;
	var template BSSMAP_IE_KC128 kC128;
	var OCT1 a5_perm_alg;
	var PDU_BSSAP pdu;

	if (not g_pars.net.expect_ciph) {
		/* There is nothing to do */
		return;
	}

	f_get_expected_encryption(encryptionInformation, chosenEncryptionAlgorithm, kC128, a5_perm_alg);
	alt {
	[] BSSAP.receive(tr_BSSMAP_CipherModeCmd2(encryptionInformation, kC128)) -> value pdu {
		var OCT1 a5_chosen := f_best_alg_from_mask(a5_perm_alg);
		var integer a5_nr := f_alg_from_mask(a5_chosen);
		BSSAP.send(ts_BSSMAP_CipherModeCompl(int2oct(a5_nr+1, 1)));
		}
	[] BSSAP.receive(tr_BSSMAP_CipherModeCmd2) -> value pdu {
		log("Error: Ciphering Mode Command with unexpected content. Expected: ",
		    tr_BSSMAP_CipherModeCmd2(encryptionInformation, kC128), "  got: ", pdu);
		setverdict(fail, "Ciphering Mode Command with unexpected content.");
		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 */
}

private function f_mm_ciph_utran() runs on BSC_ConnHdlr
{
	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));
		}
	[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));
		}
	[not g_pars.net.expect_ciph] BSSAP.receive(tr_RANAP_SecurityModeCmd(?,?,?)) {
		setverdict(fail, "Invalid SecurityModeCommand (non-ciphering case)");
		mtc.stop;
		}
	}
}

function f_mm_common() runs on BSC_ConnHdlr
{
	f_mm_auth();

	if (g_pars.ran_is_geran) {
		f_mm_ciph_geran();
	} else {
		f_mm_ciph_utran();
	}

	f_expect_common_id();
}

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

template CallParameters tr_CallParams := {
	called_party := ?,
	transaction_id := ?,
	mo_call := ?,
	bearer_cap := ?,
	emergency := ?,
	mncc_callref := *,
	mncc_bearer_cap := ?,
	mncc_rtp_ip := ?,
	mncc_rtp_port := ?,
	bss_rtp_ip := ?,
	bss_rtp_port := ?,
	mss_rtp_ip := *,
	mss_rtp_port := *,
	got_crcx_count := ?,
	mgw_conn_1 := ?,
	mgw_conn_2 := ?,
	rtp_payload_type := ?,
	rtp_sdp_format := ?,
	mgw_drop_dlcx := ?,
	stop_after_cc_setup := ?,
	ran_clear_when_alerting := ?,
	expect_release := ?,
	mgcp_call_id := *,
	mgcp_ep := ?,
	use_osmux := ?,
	got_osmux_count := ?
};

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


}
