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

module BSC_ConnectionHandler {

import from General_Types all;
import from Osmocom_Types all;
import from Native_Functions all;
import from GSM_Types all;
import from IPL4asp_Types all;
import from SCCPasp_Types all;
import from BSSAP_Types all;
import from RAN_Emulation all;
import from BSSMAP_Templates all;

import from RANAP_Constants all;
import from RANAP_IEs all;
import from RANAP_PDU_Contents all;
import from RANAP_PDU_Descriptions all;
import from RANAP_Templates all;

import from GSUP_Types all;
import from GSUP_Emulation all;

import from MNCC_Types all;
import from MNCC_Emulation all;

import from MGCP_Types all;
import from MGCP_Emulation all;
import from MGCP_Templates all;
import from SDP_Types all;

import from MobileL3_Types all;
import from MobileL3_CommonIE_Types all;
import from MobileL3_MM_Types all;
import from MobileL3_CC_Types all;
import from MobileL3_SMS_Types all;
import from L3_Templates all;
import from L3_Common all;

import from SMPP_Emulation all;

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

import from TELNETasp_PortType all;
import from Osmocom_VTY_Functions all;

import from SGsAP_Emulation all;

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

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

type record BSC_ConnHdlrPars {
	SCCP_PAR_Address sccp_addr_own,
	SCCP_PAR_Address sccp_addr_peer,
	BSSMAP_IE_CellIdentifier cell_id,
	hexstring imei,
	hexstring imsi,
	hexstring msisdn,
	OCT4 tmsi optional,
	MobileStationClassmark1_V cm1,
	BSSMAP_IE_ClassmarkInformationType2 cm2,
	BSSMAP_IE_ClassmarkInformationType3 cm3 optional,
	AuthVector vec optional,
	BSC_ConnHdlrNetworkPars net,
	boolean send_early_cm,
	charstring ipa_ctrl_ip,
	integer ipa_ctrl_port,
	boolean ipa_ctrl_enable,
	boolean mm_info,
	boolean sgsap_enable,
	boolean gsup_enable,
	OCT4 gsup_sid,
	integer ran_idx,
	boolean use_umts_aka,
	boolean ran_is_geran,
	boolean use_osmux
};

/* get a one-octet bitmaks of supported algorithms based on Classmark information */
function f_alg_mask_from_cm(BSSMAP_IE_ClassmarkInformationType2 cm2) return OCT1 {
	var BIT8 res := '00000001'B;	/* A5/0 always supported */

	if (cm2.a5_1 == '0'B) {
		res := res or4b '00000010'B;
	}
	if (cm2.classmarkInformationType2_oct5.a5_2 == '1'B ) {
		res := res or4b '00000100'B;
	}
	if (cm2.classmarkInformationType2_oct5.a5_3 == '1'B) {
		res := res or4b '00001000'B;
	}
	/* TODO: CM3 for A5/4 and beyond */
	return bit2oct(res);
}

/* determine the best algorithm available within the bit-mask */
function f_best_alg_from_mask(OCT1 alg_in) return OCT1 {
	var BIT8 alg := oct2bit(alg_in);
	var BIT8 ordered_algs[8] := {
		'10000000'B, '01000000'B, '00100000'B, '00010000'B,
		'00001000'B,	/* A5/3 */
		'00000010'B,	/* A5/1 */
		'00000100'B,	/* A5/2 */
		'00000001'B 	/* A5/0 */ }
	for (var integer i := 0; i < sizeof(ordered_algs); i := i+1) {
		if (alg and4b ordered_algs[i] != '00000000'B) {
			return bit2oct(ordered_algs[i]);
		}
	}
	return '00'O;
}

/* return an integer like '1' for A5/1 based on a mask (with only one bit set */
function f_alg_from_mask(OCT1 mask_in) return integer {
	var BIT8 mask := oct2bit(mask_in);
	for (var integer i := 0; i < 8; i := i+1) {
		if (mask and4b ('00000001'B << i) != '00000000'B) {
			return i;
		}
	}
	return -1;
}

/* altstep for the global guard timer */
private altstep as_Tguard() runs on BSC_ConnHdlr {
	[] g_Tguard.timeout {
		setverdict(fail, "Tguard timeout");
		mtc.stop;
	}
}

/* init function, called as first function in new BSC_ConnHdlr */
function f_init_handler(BSC_ConnHdlrPars pars, float t_guard := 60.0) runs on BSC_ConnHdlr {
	/* make parameters available via component variable */
	g_pars := pars;
	/* Start guard timer and activate it as default */
	g_Tguard.start(t_guard);
	activate(as_Tguard());
	/* Route all SMPP messages for our MSISDN to us */
	f_create_smpp_expect(hex2str(pars.msisdn));

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

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

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


/* Callback function from general RAN_Emulation whenever a connectionless
 * BSSMAP message arrives. Canreturn a PDU_BSSAPthat should be sent in return */
private function BscUnitdataCallback(PDU_BSSAP bssap)
runs on RAN_Emulation_CT return template PDU_BSSAP {
	var template PDU_BSSAP resp := omit;

	log("BSSMAP_BscUnitdataCallback");
	/* answer all RESET with RESET ACK */
	if (match(bssap, tr_BSSMAP_Reset(g_ran_ops.use_osmux))){
		log("BSSMAP_BscUnitdataCallback: Responding to RESET with RESET-ACK");
		resp := ts_BSSMAP_ResetAck(g_ran_ops.use_osmux);
	}

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

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

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

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


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


private function MnccUnitdataCallback(MNCC_PDU mncc)
runs on MNCC_Emulation_CT return template MNCC_PDU {
	log("Ignoring MNCC", mncc);
	return omit;
}

const MnccOps BCC_MnccOps := {
	create_cb := refers(MNCC_Emulation.ExpectedCreateCallback),
	unitdata_cb := refers(MnccUnitdataCallback)
}



/* Encode 'l3' and ask RAN_Emulation to create new connection with COMPL L3 INFO */
function f_bssap_compl_l3(PDU_ML3_MS_NW l3)
runs on BSC_ConnHdlr {
	log("Sending COMPL L3: ", l3);
	var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3);
	BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_peer, g_pars.sccp_addr_own,
				     valueof(ts_BSSMAP_ComplL3(g_pars.cell_id, l3_enc))));
	alt {
	[] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) {}
	[] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
			setverdict(fail, "DISC.ind from SCCP");
			mtc.stop;
		}
	}
}

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

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

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

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

type enumerated EstablishType {
	EST_TYPE_MO_CALL,
	EST_TYPE_EMERG_CALL,
	EST_TYPE_PAG_RESP,
	EST_TYPE_MO_SMS,
	EST_TYPE_SS_ACT
};

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

	/* If we have a TMSI, use TMSI instead of IMSI */
	if (ispresent(g_pars.tmsi)) {
		mi := valueof(ts_MI_TMSI_LV(g_pars.tmsi));
	} else {
		mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
	}

	select (etype) {
	case (EST_TYPE_MO_CALL) {
		l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
		}
	case (EST_TYPE_EMERG_CALL) {
		l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_EMERG_CALL, mi));
		}
	case (EST_TYPE_PAG_RESP) {
		l3_info := valueof(ts_PAG_RESP(mi));
		}
	case (EST_TYPE_MO_SMS) {
		l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, mi));
		}
	case (EST_TYPE_SS_ACT) {
		l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_SS_ACT, mi));
		}
	}

	/* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
	f_cl3_or_initial_ue(l3_info);

	f_mm_common();
	if (g_pars.net.expect_ciph or not g_pars.ran_is_geran) {
		/* implicit CM SERVICE ACCEPT? */
	} else {
		if (etype != EST_TYPE_PAG_RESP) {
			/* explicit CM SERVICE ACCEPT */
			BSSAP.receive(tr_PDU_DTAP_MT(tr_CM_SERV_ACC));
		}
	}
}

/* build a PDU_ML3_MS_NW containing a Location Update by IMSI */
function f_build_lu_imsi(hexstring imsi) runs on BSC_ConnHdlr return PDU_ML3_MS_NW
{
	var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(imsi));
	return f_build_lu(mi);
}
function f_build_lu_imei(hexstring imei) runs on BSC_ConnHdlr return PDU_ML3_MS_NW
{
	var MobileIdentityLV mi := valueof(ts_MI_IMEI_LV(imei));
	return f_build_lu(mi);
}
function f_build_lu_tmsi(OCT4 tmsi) runs on BSC_ConnHdlr return PDU_ML3_MS_NW
{
	var MobileIdentityLV mi := valueof(ts_MI_TMSI_LV(tmsi));
	return f_build_lu(mi);
}
private function f_build_lu(MobileIdentityLV mi) runs on BSC_ConnHdlr return PDU_ML3_MS_NW
{
	var LocationAreaIdentification_V old_lai := { '62F220'O, '9999'O };
	var PDU_ML3_MS_NW l3_info := valueof(ts_ML3_MO_LU_Req(valueof(ts_ML3_IE_LuType_Attach),
							      old_lai, mi, g_pars.cm1));
	return l3_info;
}

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

function f_mm_auth() runs on BSC_ConnHdlr
{
	if (g_pars.net.expect_auth) {
		as_GSUP_SAI();
		if (g_pars.use_umts_aka) {
			BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_AUTH_REQ_3G(g_pars.vec.rand, g_pars.vec.autn)));
			var OCT4 res := substr(g_pars.vec.res, 0, 4);
			var OCT4 xres := substr(g_pars.vec.res, 4, 4);
			BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MT_MM_AUTH_RESP_3G(res, xres)));
		} else {
			BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_MM_AUTH_REQ(g_pars.vec.rand)));
			BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MT_MM_AUTH_RESP_2G(g_pars.vec.sres)));
		}
	}
}

function f_mm_imei() runs on BSC_ConnHdlr
{
	var PDU_DTAP_MT dtap_mt;
	var GSUP_PDU gsup_msg;
	var 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_mm_common() runs on BSC_ConnHdlr
{
	f_mm_auth();
	if (g_pars.ran_is_geran) {
		if (g_pars.net.expect_ciph) {
			var OCT1 a5_net := f_alg_mask_from_cm(g_pars.cm2);
			var OCT1 a5_intersect := g_pars.net.kc_support and4b a5_net;
			alt {
			[] BSSAP.receive(tr_BSSMAP_CipherModeCmd(a5_intersect, g_pars.vec.kc)) {
				var OCT1 a5_chosen := f_best_alg_from_mask(a5_intersect);
				var integer a5_nr := f_alg_from_mask(a5_chosen);
				BSSAP.send(ts_BSSMAP_CipherModeCompl(int2oct(a5_nr+1, 1)));
				}
			[] BSSAP.receive(tr_BSSMAP_CipherModeCmd(?, g_pars.vec.kc)) {
				setverdict(fail, "Wrong ciphering algorithm mask in CiphModCmd");
				mtc.stop;
				}
			}
			/* FIXME: Send the best available algorithm */
		}
	} else { /* UTRAN */
		alt {
		[g_pars.net.expect_ciph] BSSAP.receive(tr_RANAP_SecurityModeCmdEnc(uia_algs := ?,
										   uia_key := oct2bit(g_pars.vec.ik),
										   key_sts := ?,
										   uea_algs := ?,
										   uea_key := oct2bit(g_pars.vec.ck))) {
			var IntegrityProtectionAlgorithm uia_chosen := 0; /*standard_UMTS_integrity_algorithm_UIA1*/
			var EncryptionAlgorithm uea_chosen := 1; /*standard_UMTS_encryption_algorith_UEA1*/
			BSSAP.send(ts_RANAP_SecurityModeCompleteEnc(uia_chosen, uea_chosen));
			BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)));
			}
		[g_pars.net.expect_ciph] BSSAP.receive(tr_RANAP_SecurityModeCmdEnc(?,?,?,?,?)) {
			setverdict(fail, "Invalid SecurityModeCommand (ciphering case)");
			mtc.stop;
			}
		[not g_pars.net.expect_ciph] BSSAP.receive(tr_RANAP_SecurityModeCmd(uia_algs := ?,
										    uia_key := oct2bit(g_pars.vec.ik),
										    key_sts := ?)) {
			var IntegrityProtectionAlgorithm uia_chosen := 0; /*standard_UMTS_integrity_algorithm_UIA1;*/
			BSSAP.send(ts_RANAP_SecurityModeComplete(uia_chosen));
			BSSAP.receive(tr_RANAP_CommonId(imsi_hex2oct(g_pars.imsi)));
			}
		[not g_pars.net.expect_ciph] BSSAP.receive(tr_RANAP_SecurityModeCmd(?,?,?)) {
			setverdict(fail, "Invalid SecurityModeCommand (non-ciphering case)");
			mtc.stop;
			}
		}
	}
}

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

function f_perform_lu()
runs on BSC_ConnHdlr {
	var PDU_ML3_MS_NW l3_lu := f_build_lu_imsi(g_pars.imsi)
	var PDU_DTAP_MT dtap_mt;

	/* tell GSUP dispatcher to send this IMSI to us */
	f_create_gsup_expect(hex2str(g_pars.imsi));

	/* Send BSSAP_Conn_Req with COMPL L3 INFO to MSC */
	if (g_pars.ran_is_geran) {
		f_bssap_compl_l3(l3_lu);
		if (g_pars.send_early_cm) {
			BSSAP.send(ts_BSSMAP_ClassmarkUpd(g_pars.cm2, g_pars.cm3));
		}
	} else {
		f_ranap_initial_ue(l3_lu);
	}

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

	setverdict(pass);
}

function f_msc_lu_hlr() runs on BSC_ConnHdlr
{
	/* Expect MSC to perform LU with HLR */
	GSUP.receive(tr_GSUP_UL_REQ(g_pars.imsi));
	GSUP.send(ts_GSUP_ISD_REQ(g_pars.imsi, g_pars.msisdn));
	GSUP.receive(tr_GSUP_ISD_RES(g_pars.imsi));
	GSUP.send(ts_GSUP_UL_RES(g_pars.imsi));
}

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

	alt {
	[] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Acc)) -> value dtap_mt {
		var PDU_ML3_LocationUpdateAccept lu_acc := dtap_mt.dtap.msgs.mm.locationUpdateAccept;
		if (g_pars.net.expect_tmsi) {
			if (not ispresent(lu_acc.mobileIdentityTLV) or
			    not ischosen(lu_acc.mobileIdentityTLV.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi)) {
				setverdict(fail, "Expected TMSI but no TMSI was allocated");
				mtc.stop;
			} else {
				g_pars.tmsi := lu_acc.mobileIdentityTLV.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi.octets;
				BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_TmsiRealloc_Cmpl));
			}
		} else {
			if (ispresent(lu_acc.mobileIdentityTLV) and
			    ischosen(lu_acc.mobileIdentityTLV.mobileIdentityLV.mobileIdentityV.oddEvenInd_identity.tmsi_ptmsi)) {
				setverdict(fail, "Expected no TMSI but TMSI was allocated");
				mtc.stop;
			}
		}
		}
	[] BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_LU_Rej)) {
		setverdict(fail, "Expected LU ACK, but received LU REJ");
		mtc.stop;
		}
	}

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

function f_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 */

	/* 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),
	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 := "1.1.1.1",
		mgw_rtp_port := 11000,
		mgcp_connection_id := '22222'H
	},
	rtp_payload_type := 98,
	rtp_sdp_format := "AMR/8000",
	mgw_drop_dlcx := false,
	stop_after_cc_setup := false,
	ran_clear_when_alerting := false,
	expect_release := false,
	mgcp_call_id := omit,
	mgcp_ep := "rtpbridge/1@mgw",
	use_osmux := false,
	got_osmux_count := 0
};

/* Allocate a call reference and send SETUP via MNCC to MSC */
function f_mt_call_initate(inout CallParameters cpars)
runs on BSC_ConnHdlr {
	cpars.mo_call := false;
	cpars.mncc_callref := f_rnd_int(2147483648);
	MNCC.send(ts_MNCC_SETUP_req(cpars.mncc_callref, hex2str(g_pars.msisdn),
					hex2str(cpars.called_party), hex2str(g_pars.imsi)));
}

private template (value) SDP_Message ts_SDP_CRCX_CN(CallParameters cpars) :=
	ts_SDP(cpars.mgw_conn_2.mgw_rtp_ip, cpars.mgw_conn_2.mgw_rtp_ip,
		hex2str(cpars.mgcp_call_id), "42",
		cpars.mgw_conn_2.mgw_rtp_port,
		{ int2str(cpars.rtp_payload_type) },
		{ valueof(ts_SDP_rtpmap(cpars.rtp_payload_type,
		  cpars.rtp_sdp_format)),
		  valueof(ts_SDP_ptime(20)) });

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

	f_ran_register_imsi(g_pars.imsi, g_pars.tmsi);

	f_establish_fully(EST_TYPE_PAG_RESP);

	log("f_mt_call_complete 1");

	cpars.got_osmux_count := 0;

	/* MS <- MSC: Expect CC SETUP */
	BSSAP.receive(tr_PDU_DTAP_MT(tr_ML3_MT_CC_SETUP(cpars.transaction_id, *, cpars.called_party)));

	/* MS -> MSC: ALERTING */
	BSSAP.send(ts_PDU_DTAP_MO(ts_ML3_MO_CC_ALERTING(cpars.transaction_id)));
	MNCC.receive(tr_MNCC_ALERT_ind(cpars.mncc_callref));
	log("f_mt_call_complete 2");

	/* Create MGCP expect */
	f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
	/* Ask MSC via MNCC to create the RTP socket on the MSC/MGW side */
	MNCC.send(ts_MNCC_RTP_CREATE(cpars.mncc_callref));

	/* First MGCP CRCX */
	MGCP.receive(tr_CRCX) -> value mgcp_cmd {
		log("f_mt_call_complete 3");
		if (not f_handle_crcx(cpars, mgcp_cmd)) {
			return;
		}
		}


	if (g_pars.ran_is_geran) {
		var template BSSMAP_IE_AoIP_TransportLayerAddress tla_ass :=
			tr_BSSMAP_IE_AoIP_TLA4(f_inet_addr(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 := valueof(ts_BSSMAP_IE_AoIP_TLA4(f_inet_addr(cpars.bss_rtp_ip), cpars.bss_rtp_port));
			codec := valueof(ts_BSSMAP_IE_SpeechCodec({ts_CodecFR}));

			if (cpars.use_osmux) {
				if (not ispresent(bssap.pdu.bssmap.assignmentRequest.osmuxCID)) {
					setverdict(fail, "MSC sent AssignReq without expected OsmuxCID IE");
					mtc.stop;
				}
				osmuxCID := valueof(ts_OsmuxCID(0));
				if (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");
			MNCC.send(ts_MNCC_RTP_CONNECT(cpars.mncc_callref,
						      /* ip 42.23.11.5 */ hex2int('42231105'H),
						      /* port 423 */ 423,
						      /* payload type 3 = GSM FR */ 3));
			}

		/* MDCX setting up the RAN side remote RTP address received from Assignment Complete */
		[] MGCP.receive(tr_MDCX) -> value mgcp_cmd {
			log("f_mt_call_complete 8");
			var SDP_Message sdp := valueof(ts_SDP(cpars.mgw_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)) }));
			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_2.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");
			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));
			}

		}
	} 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");
			MNCC.send(ts_MNCC_RTP_CONNECT(cpars.mncc_callref,
						      /* ip 42.23.11.5 */ hex2int('42231105'H),
						      /* port 423 */ 423,
						      /* payload type 3 = GSM FR */ 3));
			}

		/* MDCX setting up the RAN side remote RTP address received from Assignment Complete */
		[] MGCP.receive(tr_MDCX) -> value mgcp_cmd {
			log("f_mt_call_complete 8.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)) }));
			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_2.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 :=
		tr_BSSMAP_IE_AoIP_TLA4(f_inet_addr(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(ts_BSSMAP_IE_AoIP_TLA4(f_inet_addr(cpars.bss_rtp_ip), cpars.bss_rtp_port));
		codec := valueof(ts_BSSMAP_IE_SpeechCodec({ts_CodecFR}));
		if (cpars.use_osmux) {
			if (not ispresent(bssap.pdu.bssmap.assignmentRequest.osmuxCID)) {
				setverdict(fail, "MSC sent AssignReq without expected OsmuxCID IE");
				mtc.stop;
			}
			osmuxCID := valueof(ts_OsmuxCID(0));
			if (cpars.use_osmux and not match(bssap.pdu.bssmap.assignmentRequest.osmuxCID, osmuxCID)) {
				setverdict(fail, "MSC sent AssignReq without expected OsmuxCID IE");
				mtc.stop;
			}
			bssap := valueof(ts_BSSMAP_AssignmentComplete(omit, tla, codec, osmuxCID));
		} else {
			bssap := valueof(ts_BSSMAP_AssignmentComplete(omit, tla, codec));
		}
		BSSAP.send(bssap);
		}
	[] BSSAP.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_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)) }));

		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_2.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 */
		MNCC.send(ts_MNCC_RTP_CONNECT(cpars.mncc_callref,
					      /* ip 42.23.11.5 */ hex2int('42231105'H),
					      /* port 423 */ 423,
					      /* payload type 3 = GSM FR */ 3));
		MNCC.send(ts_MNCC_SETUP_rsp(cpars.mncc_callref));
		}

	[] MNCC.receive(tr_MNCC_SETUP_COMPL_ind(?)) -> value mncc {
		log("f_mo_call_establish 8: rx MNCC SETUP COMPLETE ind");
		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) runs on BSC_ConnHdlr {
	timer T := t;

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

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

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

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

type record SmsParametersTp {
	OCT1		msg_ref,
	TP_DA		da,
	OCT1		pid,
	OCT1		dcs,
	integer		udl,
	octetstring	ud
}
type record SmsParametersRp {
	OCT1		msg_ref,
	RP_NumberingPlan_and_NumberDigits 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);
}


}
