/* 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 {
	/* Bitmask of expected A5 levels; in Ciphering, will expect use of the highest A5 remaining after masking this
	 * with A5 supported by the MS */
	OCT1	kc_support,
	/* osmo-msc VTY cfg under 'network': If a test wants to temporarily modify auth and encr config, this is the
	 * original config to return to for this test (is *not* sent to vty before the test, but maybe it should).
	 * For example: { "authentication optional", "encryption a5 0 3" } */
	rof_charstring net_config,
	/* expect_attach_success == true: expect Location Updating / CM Service Request to succeed.
	 * expect_attach_success == false: expect the MSC to reject LU / CM Service. */
	boolean expect_attach_success,
	/* expect_tmsi == true: expect MSC to allocate a new TMSI.
	 * expect_tmsi == false: expect no TMSI to be assigned, operate with IMSI Mobile Identity. */
	boolean expect_tmsi,
	/* expect_auth == true overrides expect_auth_attempt == false */
	boolean	expect_auth_attempt,
	/* hlr_has_auth_info has an effect only when (expect_auth_attempt or expect_auth) == true.
	 * hlr_has_auth_info == false means the HLR responds to Send Auth Info Request with a NACK. */
	boolean hlr_has_auth_info,
	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,
	EST_TYPE_MO_CSD
};

/* 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_MO_CSD) {
		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 */
			if (g_pars.net.expect_attach_success) {
				BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_ACC));
			} else {
				BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_REJ));
			}
		}
	}
}

/* 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.net.hlr_has_auth_info) {
		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));
		}
	} else {
		log("XXX ts_GSUP_SAI_ERR");
		/* HLR knows the IMSI but has no authentication info; osmo-hlr responds with GMM_CAUSE_IMSI_UNKNOWN=2 in
		 * this case, for SAI this merely means there is no auth entry for this IMSI. */
		GSUP.send(ts_GSUP_SAI_ERR(g_pars.imsi, 2));
	}
	}
}

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

	if (not g_pars.net.expect_attach_success) {
		return;
	}
	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();
	as_accept_reject_lu(g_pars.net.expect_attach_success);
	/* FIXME: there could be pending SMS or other common procedures by the MSC, let's ignore them */
	f_expect_clear(verify_vlr_cell_id := g_pars.net.expect_attach_success);

	setverdict(pass);
}

function f_msc_lu_hlr() runs on BSC_ConnHdlr
{
	if (not g_pars.net.expect_attach_success) {
		return;
	}
	/* 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));
}

altstep as_accept_reject_lu(boolean expect_accept := true) runs on BSC_ConnHdlr {
	var PDU_DTAP_MT dtap_mt;

	[expect_accept] 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;
			}
		}

		/* Wait for MM-Information (if enabled) */
		f_expect_mm_info();
		setverdict(pass);
	}
	[expect_accept] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
		setverdict(fail, "Expected LU ACK, but received LU REJ");
		mtc.stop;
	}

	[not expect_accept] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
		setverdict(pass);
	}
	[not expect_accept] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) -> value dtap_mt {
		setverdict(fail, "Expected LU REJ, but received LU ACK");
		mtc.stop;
	}
}

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? */
	boolean csd,					/* is this a circuit switched data 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,
	csd := 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 := ?,
	csd := ?,
	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_initiate(inout CallParameters cpars)
runs on BSC_ConnHdlr {
	var template MNCC_bearer_cap bcap := ts_MNCC_bcap_voice;

	if (cpars.csd) {
		bcap := ts_MNCC_bcap_data;
	}

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

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_ass1 :=
			f_tr_BSSMAP_IE_AoIP_TLA(cpars.mgw_conn_1.mgw_rtp_ip, ?);
		var template BSSMAP_IE_AoIP_TransportLayerAddress tla_ass2 :=
			f_tr_BSSMAP_IE_AoIP_TLA(cpars.mgw_conn_2.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_ass1, tla_ass2))) -> 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_initiate(cpars);

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

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

	setverdict(pass);
}

function f_call_keep_open(inout CallParameters cpars, float open_time := 5.0)
runs on BSC_ConnHdlr {
	log("Hold the call for some time");

	timer T := open_time;
	T.start;
	alt {
	[] MNCC.receive(tr_MNCC_DISC_ind(cpars.mncc_callref));
	[] MNCC.receive(tr_MNCC_REL_ind(cpars.mncc_callref));
	[] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_DISC(cpars.transaction_id)));
	[] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_RELEASE(cpars.transaction_id)));
	[] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND);
	[] BSSAP.receive(tr_BSSMAP_ClearCommand);
	[] BSSAP.receive(tr_BSSMAP_ClearCommandCSFB);
	[] BSSAP.receive(tr_RANAP_IuReleaseCommand(?));

	[] T.timeout {
		log("Call stayed open for ", open_time, " seconds, all is well.")
		setverdict(pass);
		return;
	}
	}

	setverdict(fail, "An unexpected release event disconnected the active call prematurely");
	mtc.stop;
}

/* 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 if (cpars.csd) {
		f_establish_fully(EST_TYPE_MO_CSD);
	} 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)));
	} if (cpars.csd) {
		BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_SETUP(cpars.transaction_id, cpars.called_party, ts_Bcap_csd)));
	} 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_ass1 :=
		f_tr_BSSMAP_IE_AoIP_TLA(cpars.mgw_conn_1.mgw_rtp_ip, ?);
	var template BSSMAP_IE_AoIP_TransportLayerAddress tla_ass2 :=
		f_tr_BSSMAP_IE_AoIP_TLA(cpars.mgw_conn_2.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 ispresent(bssap.pdu.bssmap.assignmentRequest.aoIPTransportLayer)) {
			setverdict(fail, "MSC sent Assignment Request without AoIP Transport Layer IE");
			mtc.stop;
		}
		if (not match(bssap.pdu.bssmap.assignmentRequest.aoIPTransportLayer, tla_ass1)
		    and not match(bssap.pdu.bssmap.assignmentRequest.aoIPTransportLayer, tla_ass2)) {
			log("Expected one of: 1:", tla_ass1, " 2:", tla_ass2);
			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);

	f_call_keep_open(cpars);

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

	f_call_keep_open(cpars);

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


}
