module MSC_ConnectionHandler {

/* MSC Connection HAndler of BSC Tests in TTCN-3
 * (C) 2017-2019 Harald Welte <laforge@gnumonks.org>
 * contributions by sysmocom - s.f.m.c. GmbH
 * 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
 */

import from Misc_Helpers all;
import from General_Types all;
import from Osmocom_Types all;
import from GSM_Types all;
import from IPA_Emulation all;
import from SCCPasp_Types all;
import from BSSAP_Types all;
import from RAN_Emulation all;
import from BSSMAP_Templates all;

import from IPL4asp_Types all;
import from Native_Functions all;

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

import from RSL_Emulation all;
import from RSL_Types all;

import from MobileL3_Types all;
import from MobileL3_CommonIE_Types all;
import from MobileL3_RRM_Types all;
import from L3_Templates all;

import from TELNETasp_PortType all;
import from Osmocom_VTY_Functions all;


/***********************************************************************
 * Media related handling
 ***********************************************************************/

/* Get the matching payload type for a specified BSSAP codec type
 * (see also: BSSAP_Types.ttcn */
private function f_get_mgcp_pt(BSSMAP_FIELD_CodecType codecType) return SDP_FIELD_PayloadType {
	if (codecType == GSM_FR) {
		return PT_GSM;
	} else if (codecType == GSM_HR) {
		return PT_GSMHR;
	} else if (codecType == GSM_EFR) {
		return PT_GSMEFR;
	} else if (codecType == FR_AMR or codecType == HR_AMR) {
		return PT_AMR;
	} else if (codecType == FR_AMR_WB or codecType == OHR_AMR or codecType == OFR_AMR_WB or codecType == OHR_AMR_WB) {
		return PT_AMRWB;
	}

	return PT_PCMU;
}

/* Tuple containing host/ip and port */
type record HostPort {
	HostName	host,
	PortNumber	port_nr
};

/* State encapsulating one MGCP Connection */
type record MgcpConnState {
	integer crcx_seen,		/* Counts how many CRCX operations happend */
	integer mdcx_seen,		/* Counts how many MDCX operations happend C */
	integer crcx_seen_exp,		/* Sets the expected number of CRCX operations */
	integer mdcx_seen_exp,		/* Sets the expected number of MDCX operations */
	MgcpConnectionId conn_id,
	charstring mime_type,		/* e.g. AMR */
	integer sample_rate,		/* 8000 */
	integer ptime,			/* 20 */
	uint7_t rtp_pt,			/* RTP Payload Type */
	HostPort mgw,			/* MGW side */
	HostPort peer			/* CA side */
};

/* BTS media state */
type record BtsMediaState {
	boolean ipa_crcx_seen,
	boolean ipa_mdcx_seen,
	uint16_t conn_id,
	uint7_t rtp_pt,
	HostPort bts,
	HostPort peer
};

type record MediaState {
	MgcpEndpoint	mgcp_ep,
	MgcpConnState	mgcp_conn[2],
	BtsMediaState	bts,
	BtsMediaState	bts1 /* only during hand-over */
};

function f_MediaState_init(inout MediaState g_media, integer nr, HostName bts, HostName mgw, BSSMAP_FIELD_CodecType codecType) {
	/* BTS Side */
	g_media.bts := {
		ipa_crcx_seen := false,
		ipa_mdcx_seen := false,
		conn_id := nr,
		rtp_pt := 0,
		bts := {
			host := bts,
			port_nr := 9000 + nr*2
		},
		peer := -
	}

	g_media.bts1 := {
		ipa_crcx_seen := false,
		ipa_mdcx_seen := false,
		conn_id := nr,
		rtp_pt := 0,
		bts := {
			host := bts, /* FIXME */
			port_nr := 9000 + nr*2
		},
		peer := -
	}

	g_media.mgcp_ep := "rtpbridge/" & int2str(nr) & "@mgw";

	for (var integer i:= 0; i < sizeof(g_media.mgcp_conn); i := i+1) {
		g_media.mgcp_conn[i].mime_type := f_encoding_name_from_pt(f_get_mgcp_pt(codecType));
		g_media.mgcp_conn[i].sample_rate := 8000;
		g_media.mgcp_conn[i].ptime := 20;
		g_media.mgcp_conn[i].rtp_pt := enum2int(f_get_mgcp_pt(codecType));
		g_media.mgcp_conn[i].crcx_seen := 0;
		g_media.mgcp_conn[i].mdcx_seen := 0;
		g_media.mgcp_conn[i].crcx_seen_exp := 0;
		g_media.mgcp_conn[i].mdcx_seen_exp := 0;
		g_media.mgcp_conn[i].conn_id := f_mgcp_alloc_conn_id();
	}

	g_media.mgcp_conn[0].mgw := {
		host := mgw,
		port_nr := 10000 + nr*2
	}
	g_media.mgcp_conn[1].mgw := {
		host := mgw,
		port_nr := 11000 + nr*2
	}
}

/* Helper function to get the next free MGCP connection identifier. We can
 * recognize free connection identifiers by the fact that no CRCX happend yet */
private function f_get_free_mgcp_conn() runs on MSC_ConnHdlr return integer {
	for (var integer i:= 0; i < sizeof(g_media.mgcp_conn); i := i+1) {
		if (not g_media.mgcp_conn[i].crcx_seen >= 1) {
			return i;
		}
	}
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Only 2 Connections per EP!");
	/* Should never be reached */
	return -1;
}

/* Helper function to pick a specific connection by its cid. Since we reach out
 * for a connection that is in-use we also check if there was already exactly
 * one CRCX happening on that connection. */
private function f_get_mgcp_conn(MgcpConnectionId cid) runs on MSC_ConnHdlr return integer {
	for (var integer i:= 0; i < sizeof(g_media.mgcp_conn); i := i+1) {
		if (g_media.mgcp_conn[i].conn_id == cid and g_media.mgcp_conn[i].crcx_seen == 1) {
			return i;
		}
	}
	Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("No Connection for ID ", cid));
	/* Should not be reached */
	return -1;
}

/* altstep for handling of IPACC media related commands. Activated by as_Media() to test
 * RSL level media handling */
altstep as_Media_ipacc() runs on MSC_ConnHdlr {
	var RSL_Message rsl;
	var RSL_IE_Body ie;
	var boolean b_unused;
	[not g_media.bts.ipa_crcx_seen] RSL.receive(tr_RSL_IPA_CRCX(g_chan_nr)) -> value rsl {
		/* Extract parameters from request + use in response */
		if (f_rsl_find_ie(rsl, RSL_IE_IPAC_RTP_PAYLOAD, ie)) {
			g_media.bts.rtp_pt := ie.ipa_rtp_pt;
		}
		if (f_rsl_find_ie(rsl, RSL_IE_IPAC_RTP_PAYLOAD2, ie)) {
			g_media.bts.rtp_pt := ie.ipa_rtp_pt2;
		}
		RSL.send(ts_RSL_IPA_CRCX_ACK(g_chan_nr, g_media.bts.conn_id,
						oct2int(f_inet_addr(g_media.bts.bts.host)),
						g_media.bts.bts.port_nr,
						g_media.bts.rtp_pt));
		g_media.bts.ipa_crcx_seen := true;
		repeat;
		}
	[g_media.bts.ipa_crcx_seen] RSL.receive(tr_RSL_IPA_MDCX(g_chan_nr, ?)) -> value rsl{
		/* Extract conn_id, ip, port, rtp_pt2 from request + use in response */
		b_unused := f_rsl_find_ie(rsl, RSL_IE_IPAC_CONN_ID, ie);
		if (g_media.bts.conn_id != ie.ipa_conn_id) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("IPA MDCX for unknown ConnId", rsl));
		}
		/* mandatory */
		b_unused := f_rsl_find_ie(rsl, RSL_IE_IPAC_REMOTE_IP, ie);
		g_media.bts.peer.host := f_inet_ntoa(int2oct(ie.ipa_remote_ip, 4));
		b_unused := f_rsl_find_ie(rsl, RSL_IE_IPAC_REMOTE_PORT, ie);
		g_media.bts.peer.port_nr := ie.ipa_remote_port;
		/* optional */
		if (f_rsl_find_ie(rsl, RSL_IE_IPAC_RTP_PAYLOAD, ie)) {
			g_media.bts.rtp_pt := ie.ipa_rtp_pt;
		}
		if (f_rsl_find_ie(rsl, RSL_IE_IPAC_RTP_PAYLOAD2, ie)) {
			g_media.bts.rtp_pt := ie.ipa_rtp_pt2;
		}
		RSL.send(ts_RSL_IPA_MDCX_ACK(g_chan_nr, g_media.bts.conn_id,
						oct2int(f_inet_addr(g_media.bts.peer.host)),
						g_media.bts.peer.port_nr,
						g_media.bts.rtp_pt));
		g_media.bts.ipa_mdcx_seen := true;
		repeat;
		}

	/* on second (new) BTS during hand-over */
	[not g_media.bts1.ipa_crcx_seen] RSL1.receive(tr_RSL_IPA_CRCX(g_chan_nr)) -> value rsl {
		/* Extract parameters from request + use in response */
		if (f_rsl_find_ie(rsl, RSL_IE_IPAC_RTP_PAYLOAD, ie)) {
			g_media.bts1.rtp_pt := ie.ipa_rtp_pt;
		}
		if (f_rsl_find_ie(rsl, RSL_IE_IPAC_RTP_PAYLOAD2, ie)) {
			g_media.bts1.rtp_pt := ie.ipa_rtp_pt2;
		}
		RSL1.send(ts_RSL_IPA_CRCX_ACK(g_chan_nr, g_media.bts1.conn_id,
						oct2int(f_inet_addr(g_media.bts1.bts.host)),
						g_media.bts1.bts.port_nr,
						g_media.bts1.rtp_pt));
		g_media.bts1.ipa_crcx_seen := true;
		repeat;
		}
	/* on second (new) BTS during hand-over */
	[g_media.bts1.ipa_crcx_seen] RSL1.receive(tr_RSL_IPA_MDCX(g_chan_nr, ?)) -> value rsl{
		/* Extract conn_id, ip, port, rtp_pt2 from request + use in response */
		b_unused := f_rsl_find_ie(rsl, RSL_IE_IPAC_CONN_ID, ie);
		if (g_media.bts1.conn_id != ie.ipa_conn_id) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("IPA MDCX for unknown ConnId", rsl));
		}
		/* mandatory */
		b_unused := f_rsl_find_ie(rsl, RSL_IE_IPAC_REMOTE_IP, ie);
		g_media.bts1.peer.host := f_inet_ntoa(int2oct(ie.ipa_remote_ip, 4));
		b_unused := f_rsl_find_ie(rsl, RSL_IE_IPAC_REMOTE_PORT, ie);
		g_media.bts1.peer.port_nr := ie.ipa_remote_port;
		/* optional */
		if (f_rsl_find_ie(rsl, RSL_IE_IPAC_RTP_PAYLOAD, ie)) {
			g_media.bts1.rtp_pt := ie.ipa_rtp_pt;
		}
		if (f_rsl_find_ie(rsl, RSL_IE_IPAC_RTP_PAYLOAD2, ie)) {
			g_media.bts1.rtp_pt := ie.ipa_rtp_pt2;
		}
		RSL1.send(ts_RSL_IPA_MDCX_ACK(g_chan_nr, g_media.bts1.conn_id,
						oct2int(f_inet_addr(g_media.bts1.peer.host)),
						g_media.bts1.peer.port_nr,
						g_media.bts1.rtp_pt));
		g_media.bts1.ipa_mdcx_seen := true;
		repeat;
		}


}

function f_rx_crcx(MgcpCommand mgcp_cmd)
	 runs on MSC_ConnHdlr return template MgcpResponse {
	var MgcpOsmuxCID osmux_cid;
	var SDP_Message sdp;
	var integer cid := f_get_free_mgcp_conn();
	if (match(mgcp_cmd.line.ep, t_MGCP_EP_wildcard)) {
		if (cid != 0) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "MGCP wildcard EP only works in first CRCX");
		}
		/* we keep the endpoint name allocated during MediaState_init */
	} else {
		/* Call Agent allocated endpoint, trust/use it always */
		g_media.mgcp_ep := mgcp_cmd.line.ep;
	}
	if (isvalue(mgcp_cmd.sdp)) {
		sdp := mgcp_cmd.sdp;
		g_media.mgcp_conn[cid].peer.host := sdp.connection.conn_addr.addr;
		g_media.mgcp_conn[cid].peer.port_nr := sdp.media_list[0].media_field.ports.port_number;
	}
	var MgcpConnState mgcp_conn := g_media.mgcp_conn[cid];
	sdp := valueof(ts_SDP(mgcp_conn.mgw.host, mgcp_conn.mgw.host, "foo", "21",
				mgcp_conn.mgw.port_nr, { int2str(mgcp_conn.rtp_pt) },
			{valueof(ts_SDP_rtpmap(mgcp_conn.rtp_pt,
						mgcp_conn.mime_type & "/" &
						int2str(mgcp_conn.sample_rate))),
			valueof(ts_SDP_ptime(mgcp_conn.ptime)) } ));
	var template MgcpResponse mgcp_resp;
	if (g_pars.use_osmux and f_MgcpCmd_contains_par(mgcp_cmd, "X-OSMUX")) {
		osmux_cid := f_MgcpCmd_extract_osmux_cid(mgcp_cmd);
		mgcp_resp := ts_CRCX_ACK_osmux(mgcp_cmd.line.trans_id, mgcp_conn.conn_id, osmux_cid, sdp);
	} else {
		mgcp_resp := ts_CRCX_ACK(mgcp_cmd.line.trans_id, mgcp_conn.conn_id, sdp);
	}
	f_mgcp_par_append(mgcp_resp.params, ts_MgcpParSpecEP(g_media.mgcp_ep));
	g_media.mgcp_conn[cid].crcx_seen := g_media.mgcp_conn[cid].crcx_seen + 1;
	return mgcp_resp;
}

function f_rx_mdcx(MgcpCommand mgcp_cmd)
	runs on MSC_ConnHdlr return template MgcpResponse {
	var SDP_Message sdp;
	var integer cid := f_get_mgcp_conn(f_MgcpCmd_extract_conn_id(mgcp_cmd));
	if (isvalue(mgcp_cmd.sdp)) {
		sdp := mgcp_cmd.sdp;
		g_media.mgcp_conn[cid].peer.host := sdp.connection.conn_addr.addr;
		g_media.mgcp_conn[cid].peer.port_nr := sdp.media_list[0].media_field.ports.port_number;
	} else {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "MDCX has no [recognizable] SDP");
	}
	var MgcpConnState mgcp_conn := g_media.mgcp_conn[cid];
	sdp := valueof(ts_SDP(mgcp_conn.peer.host, mgcp_conn.peer.host, "foo", "21",
				mgcp_conn.peer.port_nr, { int2str(mgcp_conn.rtp_pt) },
			{valueof(ts_SDP_rtpmap(mgcp_conn.rtp_pt,
						mgcp_conn.mime_type & "/" &
						int2str(mgcp_conn.sample_rate))),
			valueof(ts_SDP_ptime(mgcp_conn.ptime)) } ));
	g_media.mgcp_conn[cid].mdcx_seen := g_media.mgcp_conn[cid].mdcx_seen + 1;
	return ts_MDCX_ACK(mgcp_cmd.line.trans_id, mgcp_conn.conn_id, sdp);
}

function tr_MGCP_RecvFrom_any(template MgcpMessage msg)
runs on MSC_ConnHdlr return template MGCP_RecvFrom {
	var template MGCP_RecvFrom mrf := {
		connId := ?,
		remName := ?,
		remPort := ?,
		locName := ?,
		locPort := ?,
		msg := msg
	}
	return mrf;
}

/* altstep for handling of MGCP media related commands. Activated by as_Media() to test
 * MGW level media handling */

altstep as_Media_mgw(boolean norepeat := false) runs on MSC_ConnHdlr {
	var MgcpCommand mgcp_cmd;
	var template MgcpResponse mgcp_resp;
	var MGCP_RecvFrom mrf;
	var template MgcpMessage msg_crcx := {
		command := tr_CRCX
	}
	var template MgcpMessage msg_mdcx := {
		command := tr_MDCX
	}
	var template MgcpMessage msg_resp;

	[g_pars.aoip] MGCP.receive(tr_CRCX) -> value mgcp_cmd {
		mgcp_resp := f_rx_crcx(mgcp_cmd);
		MGCP.send(mgcp_resp);
		if(norepeat == false) {
			repeat;
		}
	}

	[not g_pars.aoip] MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_crcx)) -> value mrf {
		mgcp_resp := f_rx_crcx(mrf.msg.command);
		msg_resp := {
			response := mgcp_resp
		}
		MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, msg_resp));
		if(norepeat == false) {
			repeat;
		}
	}

	[g_pars.aoip] MGCP.receive(tr_MDCX) -> value mgcp_cmd {
		mgcp_resp := f_rx_mdcx(mgcp_cmd);
		MGCP.send(mgcp_resp);
		if(norepeat == false) {
			repeat;
		}
	}

	[not g_pars.aoip] MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_mdcx)) -> value mrf {
		mgcp_resp := f_rx_mdcx(mrf.msg.command);
		msg_resp := {
			response := mgcp_resp
		}
		MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, msg_resp));
		if(norepeat == false) {
			repeat;
		}
	}
}

/* Altsteps for handling of media related commands. Can be activated by a given
 * test case if it expects to see media related handling (i.e. voice calls) */
altstep as_Media() runs on MSC_ConnHdlr {
	[] as_Media_ipacc();
	[] as_Media_mgw();
}

/* this component represents a single subscriber connection at the MSC.
 * There is a 1:1 mapping between SCCP connections and RAN_ConnHdlr components.
 * We inherit all component variables, ports, functions, ... from RAN_ConnHdlr */
type component MSC_ConnHdlr extends RAN_ConnHdlr, RSL_DchanHdlr, MGCP_ConnHdlr {
	/* SCCP Connecction Identifier for the underlying SCCP connection */
	var integer g_sccp_conn_id;

	/* procedure port back to our parent (RAN_Emulation_CT) for control */
	port RAN_PROC_PT RAN;
	port TELNETasp_PT BSCVTY;

	/* Proxy MGCP-over-IPA and MGCP-over-UDP */
	port IPA_MGCP_PT MGCP_MSC_CLIENT;
	var integer g_trans_id := 0;

	var MediaState g_media;
	var TestHdlrParams g_pars;

	var charstring host_bts := "127.0.0.2";
	var charstring host_mgw := "127.0.0.3";
	var charstring host_msc := "127.0.0.4";

	var boolean g_vty_initialized := false;
}

/* initialize all parameters */
function f_MscConnHdlr_init(integer i, HostName bts, HostName mgw, BSSMAP_FIELD_CodecType codecType) runs on MSC_ConnHdlr {
	f_MediaState_init(g_media, i, bts, mgw, codecType);
	if (not g_vty_initialized) {
		map(self:BSCVTY, system:BSCVTY);
		f_vty_set_prompts(BSCVTY);
		f_vty_transceive(BSCVTY, "enable");
		g_vty_initialized := true;
	}
}

private function get_next_trans_id() runs on MSC_ConnHdlr return MgcpTransId {
	var MgcpTransId tid := int2str(g_trans_id);
	g_trans_id := g_trans_id + 1;
	return tid;
}

/* Callback function from general RAN_Emulation whenever a connectionless
 * BSSMAP message arrives.  Can retunr a PDU_BSSAP that should be sent in return */
private function UnitdataCallback(PDU_BSSAP bssap)
runs on RAN_Emulation_CT return template PDU_BSSAP {
	var template PDU_BSSAP resp := omit;
	var boolean append_osmux_support := g_ran_ops.use_osmux and
					    (g_ran_ops.transport == BSSAP_TRANSPORT_AoIP);

	/* answer all RESET with a RESET ACK */
	if (match(bssap, tr_BSSMAP_Reset(append_osmux_support))) {
		resp := ts_BSSMAP_ResetAck(append_osmux_support);
	}

	return resp;
}

const RanOps MSC_RanOps := {
	create_cb := refers(RAN_Emulation.ExpectedCreateCallback),
	unitdata_cb := refers(UnitdataCallback),
	decode_dtap := false,
	role_ms := false,
	protocol := RAN_PROTOCOL_BSSAP,
	transport := BSSAP_TRANSPORT_AoIP,
	use_osmux := false,
	sccp_addr_local := omit,
	sccp_addr_peer := omit
}

const MGCPOps MSC_MGCPOps := {
	create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
	unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
}

/* register an expect with the BSSMAP core */
private function f_create_bssmap_exp(octetstring l3_enc) runs on MSC_ConnHdlr {
	RAN.call(RAN_register:{l3_enc, self}) {
		[] RAN.getreply(RAN_register:{?, ?}) {};
	}
}

type record TestHdlrEncrParams {
	OCT1		enc_alg,
	octetstring	enc_key
};

template (value) TestHdlrEncrParams t_EncrParams(OCT1 alg, octetstring key) := {
	enc_alg := alg,
	enc_key := key
}

type record TestHdlrParamsLcls {
	GlobalCallReferenceValue gcr optional,
	/* LCLS Configuration */
	BIT4 cfg optional,
	/* LCLS Connection Status Control */
	BIT4 csc optional,
	BIT4 exp_sts optional,
	/* Whether to adjust *cx_seen_exp for LCLS tests */
	boolean adjust_cx_exp
}

type record TestHdlrParamsHandover {
	SCCP_PAR_Address sccp_addr_msc,
	SCCP_PAR_Address sccp_addr_bsc
}

type record TestHdlrParams {
	OCT1		ra,
	GsmFrameNumber	fn,
	hexstring	imsi,
	RslLinkId	link_id,
	integer		media_nr, /* determins MGCP EP, port numbers */
	BSSMAP_IE_SpeechCodecList ass_codec_list optional,
	RSL_IE_Body	expect_mr_conf_ie optional, /* typically present for AMR codecs */
	bitstring	expect_mr_s0_s7 optional, /* typically present for AMR codecs */
	TestHdlrEncrParams encr optional,
	TestHdlrParamsLcls lcls,
	TestHdlrParamsHandover handover optional,
	uint5_t 	exp_ms_power_level,
	boolean         exp_ms_power_params,
	boolean		aoip,
	boolean		use_osmux
};

/* Note: Do not use valueof() to get a value of this template, use
 * f_gen_test_hdlr_pars() instead in order to get a configuration that is
 * matched to the current test situation (aoio vs. sccplite) */
template (value) TestHdlrParams t_def_TestHdlrPars := {
	ra := '23'O,
	fn := 23,
	imsi := '001019876543210'H,
	link_id := valueof(ts_RslLinkID_DCCH(0)),
	media_nr := 1,
	ass_codec_list := omit,
	expect_mr_conf_ie := omit,
	expect_mr_s0_s7 := omit,
	encr := omit,
	lcls := {
		gcr := omit,
		cfg := omit,
		csc := omit,
		exp_sts := omit,
		adjust_cx_exp := true
	},
	handover := omit,
	exp_ms_power_level := 7, /* calculated from osmo-bsc.cfg "ms max power" */
	exp_ms_power_params := false,
	aoip := true,
	use_osmux := false
}

function f_create_chan_and_exp() runs on MSC_ConnHdlr {
	var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
	var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
	var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);

	/* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
	RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
	f_create_bssmap_exp(l3_enc);
}

function f_rsl_send_l3(template PDU_ML3_MS_NW l3, template (omit) RslLinkId link_id := omit,
			template (omit) RslChannelNr chan_nr := omit) runs on MSC_ConnHdlr {
	if (not isvalue(link_id)) {
		link_id := ts_RslLinkID_DCCH(0);
	}
	if (not isvalue(chan_nr)) {
		chan_nr := g_chan_nr;
	}
	RSL.send(ts_RSL_DATA_IND(valueof(chan_nr), valueof(link_id), enc_PDU_ML3_MS_NW(valueof(l3))));
}

function f_rsl_reply(template PDU_ML3_MS_NW l3, RSL_Message orig) runs on MSC_ConnHdlr {
	var RslChannelNr chan_nr := orig.ies[0].body.chan_nr;
	var RslLinkId link_id;
	if (orig.msg_type == RSL_MT_ENCR_CMD) {
		link_id := orig.ies[2].body.link_id;
	} else {
		link_id := orig.ies[1].body.link_id;
	}
	f_rsl_send_l3(l3, link_id, chan_nr);
}

/* Convert the chipher representation on BSSMAP to the representation used on RSL */
function f_chipher_mode_bssmap_to_rsl(OCT1 alg_bssmap) return RSL_AlgId
{
	/* A5 0 */
	if (alg_bssmap == '01'O) {
		return RSL_ALG_ID_A5_0;
	}
	/* A5 1 */
	else if (alg_bssmap == '02'O) {
		return RSL_ALG_ID_A5_1;
	}
	/* A5 2 */
	else if (alg_bssmap == '04'O) {
		return RSL_ALG_ID_A5_2;
	}
	/* A5 3 */
	else if (alg_bssmap == '08'O) {
		return RSL_ALG_ID_A5_3;
	}
	/* A5 4 */
	else if (alg_bssmap == '10'O) {
		return RSL_ALG_ID_A5_4;
	}
	/* A5 5 */
	else if (alg_bssmap == '20'O) {
		return RSL_ALG_ID_A5_5;
	}
	/* A5 6 */
	else if (alg_bssmap == '40'O) {
		return RSL_ALG_ID_A5_6;
	}
	/* A5 7 */
	else if (alg_bssmap == '80'O) {
		return RSL_ALG_ID_A5_7;
	} else {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Unexpected Encryption Algorithm");
		return RSL_ALG_ID_A5_0;
	}
}

function f_cipher_mode(OCT1 alg, OCT8 key, template OCT16 kc128 := omit, boolean exp_fail := false)
runs on MSC_ConnHdlr {
	var PDU_BSSAP bssap;
	var RSL_Message rsl;
	var RSL_AlgId alg_rsl;

	if (isvalue(kc128)) {
		BSSAP.send(ts_BSSMAP_CipherModeCmdKc128(alg, key, valueof(kc128)));
	} else {
		BSSAP.send(ts_BSSMAP_CipherModeCmd(alg, key));
	}

	/* RSL uses a different representation of the encryption algorithm,
	 * so we need to convert first */
	alg_rsl := f_chipher_mode_bssmap_to_rsl(alg);

	alt {
	/* RSL/UE Side */
	[] RSL.receive(tr_RSL_ENCR_CMD(g_chan_nr, ?, alg_rsl, key)) -> value rsl {
		var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[3].body.l3_info.payload);
		log("Rx L3 from net: ", l3);
		if (ischosen(l3.msgs.rrm.cipheringModeCommand)) {
			f_rsl_reply(ts_RRM_CiphModeCompl, rsl);
		}
		repeat;
		}
	[] BSSAP.receive(tr_BSSMAP_CipherModeCompl) -> value bssap {
		// bssap.bssmap.cipherModeComplete.chosenEncryptionAlgorithm.algoritmhIdentifier
		if (exp_fail == true) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Unexpected Cipher Mode Complete");
		} else {
			setverdict(pass);
		}
		}
	[] BSSAP.receive(tr_BSSMAP_CipherModeRej) -> value bssap {
		if (exp_fail == false) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Ciphering Mode Reject");
		} else {
			setverdict(pass);
		}
		}
	}
}

/* Convert from Ericsson ChanDesc2 format to Osmocom RslChannelNr format */
function f_ChDesc2RslChanNr(ChannelDescription2_V ch_desc, out RslChannelNr chan_nr, out GsmArfcn arfcn) {
	var BIT5 inp := ch_desc.channelTypeandTDMAOffset;
	var uint3_t tn := bit2int(ch_desc.timeslotNumber);

	if (match(inp, '00001'B)) { /* TCH/F */
		chan_nr := valueof(t_RslChanNr_Bm(tn));
	}
	else if (match(inp, '0001?'B)) { /* TCH/H */
		chan_nr := valueof(t_RslChanNr_Lm(tn, bit2int(substr(inp, 4, 1))));
	}
	else if (match(inp, '001??'B)) { /* SDCCH/4 */
		chan_nr := valueof(t_RslChanNr_SDCCH4(tn, bit2int(substr(inp, 3, 2))));
	}
	else if (match(inp, '01???'B)) { /* SDCCH/8 */
		chan_nr := valueof(t_RslChanNr_SDCCH8(tn, bit2int(substr(inp, 2, 3))));
	}
	else {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Unknown ChDesc!");
	}

	if (ch_desc.octet3 and4b '10'O == '10'O) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "No support for Hopping");
	} else {
		var OCT2 concat := ch_desc.octet3 & ch_desc.octet4;
		arfcn := oct2int(concat);
	}
}

type record AssignmentState {
	/* global */
	boolean voice_call,
	boolean is_assignment,
	/* Assignment related bits */
	boolean rr_ass_cmpl_seen,
	boolean old_lchan_deact_sacch_seen,
	boolean old_lchan_rll_rel_req_seen,
	boolean assignment_done,
	RslChannelNr old_chan_nr,
	/* Modify related bits */
	boolean rr_modify_seen,
	boolean modify_done
}

template (value) AssignmentState ts_AssignmentStateInit := {
	voice_call := false,
	is_assignment := false,
	rr_ass_cmpl_seen := false,
	old_lchan_deact_sacch_seen := false,
	old_lchan_rll_rel_req_seen := false,
	assignment_done := false,
	old_chan_nr := -,
	rr_modify_seen := false,
	modify_done := false
}

private template RSL_IE_Body tr_EncrInfo(template RSL_AlgId alg, template octetstring key) := {
	encr_info := {
		len := ?,
		alg_id := alg,
		key := key
	}
}

/* ensure the RSL CHAN ACT (during assignment) contains values we expect depending on test case */
private function f_check_chan_act(AssignmentState st, RSL_Message chan_act) runs on MSC_ConnHdlr {
	var RSL_IE_Body encr_info;
	var RSL_IE_Body ms_power_param;
	var RSL_IE_Body ms_power;

	if (ispresent(g_pars.encr) and g_pars.encr.enc_alg != '01'O) {
		if (not f_rsl_find_ie(chan_act, RSL_IE_ENCR_INFO, encr_info)) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Missing Encryption IE in CHAN ACT");
		} else {
			var RSL_AlgId alg := f_chipher_mode_bssmap_to_rsl(g_pars.encr.enc_alg);
			if (not match(encr_info, tr_EncrInfo(alg, g_pars.encr.enc_key))) {
				Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Wrong Encryption IE in CHAN ACT");
			}
		}
	} else {
		if (f_rsl_find_ie(chan_act, RSL_IE_ENCR_INFO, encr_info)) {
			if (encr_info.encr_info.alg_id != RSL_ALG_ID_A5_0) {
				Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Unexpected Encryption in CHAN ACT");
			}
		}
	}
	/* FIXME: validate RSL_IE_ACT_TYPE, RSL_IE_CHAN_MODE, RSL_IE_CHAN_IDENT, RSL_IE_BS_POWER,
	 * RSL_IE_TIMING_ADVANCE */

	if (g_pars.exp_ms_power_params and not f_rsl_find_ie(chan_act, RSL_IE_MS_POWER_PARAM, ms_power_param)) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "IE MS Power Parameters not found in CHAN ACT");
	}

	if (not f_rsl_find_ie(chan_act, RSL_IE_MS_POWER, ms_power)) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "IE MS Power not found in CHAN ACT");
	} else {
		if (not match(ms_power.ms_power, tr_RSL_IE_MS_Power(g_pars.exp_ms_power_level, false))) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Wrong MS Power IE in CHAN ACT, ", ms_power.ms_power.power_level, " vs exp ", g_pars.exp_ms_power_level));
		}
	}

}

altstep as_assignment(inout AssignmentState st) runs on MSC_ConnHdlr {
	var RSL_Message rsl;
	[not st.rr_ass_cmpl_seen] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
		var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
		log("Rx L3 from net: ", l3);
		if (ischosen(l3.msgs.rrm.assignmentCommand)) {
			var RslChannelNr new_chan_nr;
			var GsmArfcn arfcn;
			f_ChDesc2RslChanNr(l3.msgs.rrm.assignmentCommand.descrOf1stChAfterTime,
					   new_chan_nr, arfcn);
			/* FIXME: Determine TRX NR by ARFCN, instead of hard-coded TRX0! */

			/* register our component for this channel number at the RSL Emulation */
			f_rslem_register(0, new_chan_nr);
			var PDU_ML3_MS_NW l3_tx := valueof(ts_RRM_AssignmentComplete('00'O));
			/* send assignment complete over the new channel */
			RSL.send(ts_RSL_EST_IND(new_chan_nr, valueof(ts_RslLinkID_DCCH(0)),
						 enc_PDU_ML3_MS_NW(l3_tx)));
			/* by default, send via the new channel from now */
			st.old_chan_nr := g_chan_nr;
			g_chan_nr := new_chan_nr;
			st.rr_ass_cmpl_seen := true;
			/* obtain channel activation from RSL_Emulation for new channel */
			var RSL_Message chan_act := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
			/* check it (e.g. for correct ciphering parameters) */
			f_check_chan_act(st, chan_act);
			repeat;
		} else {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Unexpected L3 received", l3));
		}
		}
	[st.rr_ass_cmpl_seen] RSL.receive(tr_RSL_DEACT_SACCH(st.old_chan_nr)) {
		st.old_lchan_deact_sacch_seen := true;
		repeat;
		}
	[st.rr_ass_cmpl_seen] RSL.receive(tr_RSL_REL_REQ(st.old_chan_nr, tr_RslLinkID_DCCH(0))) {
		st.old_lchan_rll_rel_req_seen := true;
		RSL.send(ts_RSL_REL_CONF(st.old_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
		repeat;
		}
	[st.rr_ass_cmpl_seen] RSL.receive(tr_RSL_RF_CHAN_REL(st.old_chan_nr)) {
		RSL.send(ts_RSL_RF_CHAN_REL_ACK(st.old_chan_nr));
		/* unregister for old channel number in RSL emulation */
		/* FIXME: Determine TRX NR by ARFCN, instead of hard-coded TRX0! */
		f_rslem_unregister(0, st.old_chan_nr);
		st.assignment_done := true;
		repeat;
		}
}

altstep as_modify(inout AssignmentState st) runs on MSC_ConnHdlr {
	/* no assignment, just mode modify */
	var RSL_Message rsl;

	[st.voice_call and not st.rr_modify_seen] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
		var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
		log("Rx L3 from net: ", l3);
		if (ischosen(l3.msgs.rrm.channelModeModify)) {
			f_rsl_reply(ts_RRM_ModeModifyAck(l3.msgs.rrm.channelModeModify.channelDescription,
							 l3.msgs.rrm.channelModeModify.channelMode), rsl);
			st.rr_modify_seen := true;
		}
		repeat;
		}
	[st.voice_call and st.rr_modify_seen] RSL.receive(tr_RSL_MsgTypeD(RSL_MT_MODE_MODIFY_REQ)) -> value rsl {
		RSL.send(ts_RSL_MODE_MODIFY_ACK(g_chan_nr));
		st.modify_done := true;
		repeat;
		}
}

/* Determine if given rsl_chan_nr is compatible with given BSSMAP ChannelType */
function f_channel_compatible(BSSMAP_IE_ChannelType bssmap, RslChannelNr rsl_chan_nr)
return boolean {
	select (bssmap.speechOrDataIndicator) {
		case ('0011'B) { /* Signalling */
			/* all channels support signalling */
			return true;
			}
		case else { /* Speech, Speech+CTM or CSD */
			select (bssmap.channelRateAndType) {
				case ('08'O) { /* TCH/F */
					select (rsl_chan_nr) {
						case (t_RslChanNr_Bm(?)) { return true; }
					}
				}
				case ('09'O) { /* TCH/H */
					select (rsl_chan_nr) {
						case (t_RslChanNr_Lm(?, ?)) { return true; }
					}
				}
				case else { /* full or half-rate */
					select (rsl_chan_nr) {
						case (t_RslChanNr_Bm(?)) { return true; }
						case (t_RslChanNr_Lm(?, ?)) { return true; }
					}
				}
			}
		}
	}
	return false;
}

/* Determine if the channel mode specified within rsl_chan_nr requires a
 * MODE MODIFY in to match the channel mode specified by given BSSMAP
 * ChannelType */
function f_channel_needs_modify(BSSMAP_IE_ChannelType bssmap, RslChannelNr rsl_chan_nr)
return boolean {

	/* FIXME: This tests the rsl_chan_nr to determine if we are on a
	 * signalling channel or not. Unfortunately this may lead to false
	 * results if we are on a TCH. The problem is that a TCH may be also
	 * used in signalling mode, but this function assumes that only SDCCH4
	 * and SDCCH8 are used as signalling channels at all. */

	var boolean current_signalling := false;
	var boolean desired_signalling := false;

	select (rsl_chan_nr) {
	       case (t_RslChanNr_SDCCH4(?, ?)) { current_signalling := true; }
	       case (t_RslChanNr_SDCCH8(?, ?)) { current_signalling := true; }
	}

	if (bssmap.speechOrDataIndicator == '0011'B) {
		desired_signalling := true;
	}

	if (current_signalling == desired_signalling) {
		/* The desired channel mode is equal to the one we currently
		 * have, there is no mode modification needed or expected */
	       return false;
	} else {
		/* The desired channel mode and the current channel mode do
		 * not match. A mode modification is required */
	       return true;
	}
}

/* patch an BSSMAP ASS REQ with LCLS related IEs, depending on g_params */
function f_ass_patch_lcls(inout template (omit) PDU_BSSAP ass_tpl,
			  inout template PDU_BSSAP ass_cpl) runs on MSC_ConnHdlr {
	if (istemplatekind(ass_tpl, "omit")) {
		return;
	}
	if (ispresent(g_pars.lcls.gcr)) {
		ass_tpl.pdu.bssmap.assignmentRequest.globalCallReference := ts_BSSMAP_IE_GCR(g_pars.lcls.gcr);
	}
	if (ispresent(g_pars.lcls.cfg)) {
		ass_tpl.pdu.bssmap.assignmentRequest.lCLS_Configuration := ts_BSSMAP_IE_LclsCfg(g_pars.lcls.cfg);
	}
	if (ispresent(g_pars.lcls.csc)) {
		ass_tpl.pdu.bssmap.assignmentRequest.lCLS_ConnectionStatusControl := ts_BSSMAP_IE_LclsCsc(g_pars.lcls.csc);
	}
	if (ischosen(ass_cpl.pdu.bssmap.assignmentComplete)) {
		if (ispresent(g_pars.lcls.exp_sts)) {
			ass_cpl.pdu.bssmap.assignmentComplete.lCLS_BSS_Status := tr_BSSMAP_IE_LclsSts(g_pars.lcls.exp_sts);
		} else {
			ass_cpl.pdu.bssmap.assignmentComplete.lCLS_BSS_Status := omit;
		}
	}
}

/* Send a MGCP request through MGCP-over-IPA from MSC side and receive a (matching!) response */
function mgcp_transceive_mgw(template MgcpCommand cmd, template MgcpResponse resp := ?) runs on MSC_ConnHdlr {
	template MgcpResponse resp_any := ?
	var MgcpResponse resp_val;
	resp.line.trans_id := cmd.line.trans_id;
	timer T := 5.0;

	BSSAP.send(cmd);
	T.start;
	alt {
		[] as_Media_mgw();
		[] BSSAP.receive(resp) -> value resp_val { }
		[] BSSAP.receive(resp_any) {
			setverdict(fail, "Response didn't match template");
			mtc.stop;
			}
		[] BSSAP.receive { repeat; }
		[] T.timeout {
			setverdict(fail, "Timeout waiting for response to ", cmd);
			mtc.stop;
			}
	}
	T.stop;
}

/* Helper function to check if the activity on the MGCP matches what we
 * expected */
function f_check_mgcp_expectations() runs on MSC_ConnHdlr {
	for (var integer i:= 0; i < sizeof(g_media.mgcp_conn); i := i+1) {
		log(testcasename(), ": Check MGCP test expectations for g_media.mgcp_conn[", i , "]:",
		    " crcx_seen=", g_media.mgcp_conn[i].crcx_seen, ", crcx_seen_exp=", g_media.mgcp_conn[i].crcx_seen_exp,
		    ", mdcx_seen=", g_media.mgcp_conn[i].mdcx_seen, ", mdcx_seen_exp=", g_media.mgcp_conn[i].mdcx_seen_exp);

		if(g_media.mgcp_conn[i].crcx_seen != g_media.mgcp_conn[i].crcx_seen_exp) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "unexpected number of MGW-CRCX transactions on g_media.mgcp_conn[" & int2str(i) & "]");
		}
		if(g_media.mgcp_conn[i].mdcx_seen != g_media.mgcp_conn[i].mdcx_seen_exp) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "unexpected number of MGW-MDCX transactions on g_media.mgcp_conn[" & int2str(i) & "]");
		}
	}
}

/* establish a channel fully, expecting an assignment matching 'exp' */
function f_establish_fully(template (omit) PDU_BSSAP ass_tpl, template PDU_BSSAP exp_ass_cpl)
runs on MSC_ConnHdlr {

	var BSSMAP_FIELD_CodecType codecType;
	timer T := 10.0;

	if (isvalue(ass_tpl.pdu.bssmap.assignmentRequest.codecList)) {
		codecType := valueof(ass_tpl.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType);
	} else {
		/* Make sure a meaningful default is assigned in case the
		 * codecList is not populated */
		codecType := FR_AMR;
	}

	f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw, codecType);

	/* patch in the LCLS related items, as needed */
	f_ass_patch_lcls(ass_tpl, exp_ass_cpl);

	f_create_chan_and_exp();
	/* we should now have a COMPL_L3 at the MSC */

	var template PDU_BSSAP exp_l3_compl;
	exp_l3_compl := tr_BSSMAP_ComplL3()
	if (g_pars.aoip == false) {
		exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
	} else {
		exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
	}
	T.start;
	alt {
	[] BSSAP.receive(exp_l3_compl);
	[] BSSAP.receive(tr_BSSMAP_ComplL3) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
		}
	[] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
		}
	}

	/* start ciphering, if requested */
	if (ispresent(g_pars.encr)) {
		f_cipher_mode(g_pars.encr.enc_alg, g_pars.encr.enc_key);
	}

	/* bail out early if no assignment requested */
	if (istemplatekind(ass_tpl, "omit")) {
		return;
	}

	var PDU_BSSAP ass_cmd := valueof(ass_tpl);
	var PDU_BSSAP bssap;
	var boolean exp_compl := ischosen(exp_ass_cpl.pdu.bssmap.assignmentComplete);
	var boolean exp_fail := ischosen(exp_ass_cpl.pdu.bssmap.assignmentFailure);
	var boolean exp_modify;

	var ExpectCriteria mgcpcrit := {
		connid := omit,
		endpoint := omit,
		transid := omit
	};
	var AssignmentState st := valueof(ts_AssignmentStateInit);
	/* if the channel type is SIGNAL, we're not handling a voice call */
	if (ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechOrDataIndicator != '0011'B) {
		st.voice_call := true;
		exp_modify := true;
	}

	/* determine if the current channel can support the given service or not */
	if (not f_channel_compatible(ass_cmd.pdu.bssmap.assignmentRequest.channelType, g_chan_nr)) {
		st.is_assignment := true;

		/* We decided to assign a new channel, so we do not expect
		 * any mode modify messages on RSL */
		exp_modify := false;
	} else {
		/* We will continue working with the currently assigned
		 * channel, we must now check if the mode of the current
		 * channel is compatible. If not we expect the BSC to modify
		 * the mode */
		exp_modify := f_channel_needs_modify(ass_cmd.pdu.bssmap.assignmentRequest.channelType, g_chan_nr);
	}

	/* Some test situations will involve MGCP transactions on a media
	 * gateway. Depending on the situation, we set up how many of each MGCP
	 * message type are expected to be exchanged. */
	if (isbound(exp_ass_cpl.pdu.bssmap.assignmentFailure)) {
		/* For tests that expect the assignment to fail, assume that
		 * there will be no MGW communication as well. */
		g_media.mgcp_conn[0].crcx_seen_exp := 0;
		g_media.mgcp_conn[0].mdcx_seen_exp := 0;
		g_media.mgcp_conn[1].crcx_seen_exp := 0;
		g_media.mgcp_conn[1].mdcx_seen_exp := 0;
	} else if (st.voice_call) {
		/* For voice calls we expect the following MGCP activity */
		g_media.mgcp_conn[0].crcx_seen_exp := 1;
		g_media.mgcp_conn[0].mdcx_seen_exp := 1;
		g_media.mgcp_conn[1].crcx_seen_exp := 1;
		g_media.mgcp_conn[1].mdcx_seen_exp := 0;
	}

	f_create_mgcp_expect(mgcpcrit);
	BSSAP.send(ass_cmd);

	T.start;
	alt {
	/* assignment related bits */
	[st.is_assignment] as_assignment(st);

	/* modify related bits */
	[not st.is_assignment and exp_modify] as_modify(st);

	/* voice call related bits (IPA CRCX/MDCX + MGCP) */
	[st.voice_call] as_Media();

	/* if we receive exactly what we expected, always return + pass */
	[st.is_assignment and st.assignment_done or (not st.is_assignment and (st.modify_done or not exp_modify))] BSSAP.receive(exp_ass_cpl) -> value bssap {
		setverdict(pass);
		}
	[exp_fail] BSSAP.receive(exp_ass_cpl) -> value bssap {
		setverdict(pass);
		}
	[(st.is_assignment and st.assignment_done or
	 (not st.is_assignment and (st.modify_done or not exp_modify))) and
	 exp_compl] BSSAP.receive(tr_BSSMAP_AssignmentComplete) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching ASSIGNMENT COMPLETE");
		}
	[exp_compl] BSSAP.receive(tr_BSSMAP_AssignmentFail) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received unexpected ASSIGNMENT FAIL");
		}
	[not exp_compl] BSSAP.receive(tr_BSSMAP_AssignmentComplete) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received unexpected ASSIGNMENT COMPLETE");
		}
	[not exp_compl] BSSAP.receive(tr_BSSMAP_AssignmentFail) {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching ASSIGNMENT FAIL");
		}
	[] T.timeout {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for ASSIGNMENT COMPLETE");
		}
	}
	log("g_media ", g_media);
	if (not isbound(bssap)) {
		mtc.stop;
	}

	/* When the BSC detects that LCLS is possible it will cross the
	 * connetions that point to the PBX side of the MGW. In our case this
	 * is mgcp_conn[1]. The BSC performs this operation already before the
	 * assignment complete is generated. This means we expect another MDCX
	 * at mgcp_conn[1] when LCLS is expected. */
	if (g_pars.lcls.adjust_cx_exp and ispresent(exp_ass_cpl.pdu.bssmap.assignmentComplete.lCLS_BSS_Status.lCLS_BSS_StatusValue)) {
		if (valueof(exp_ass_cpl.pdu.bssmap.assignmentComplete.lCLS_BSS_Status.lCLS_BSS_StatusValue) == LCLS_STS_locally_switched) {
			g_media.mgcp_conn[1].mdcx_seen_exp := g_media.mgcp_conn[1].mdcx_seen_exp + 1;

		}
	}

	if (not exp_fail and st.voice_call and not g_pars.aoip) {
		/* With SCCPLite, connect to BSC-located MGW using a CRCX + SDP.
		   It is sent in MGCP over IPA in the BSC<->MSC (BSC-NAT)
		   connection. BSC will forward it to its MGW. */
		var template MgcpCommand cmd;
		var template MgcpResponse resp;
		var integer cic := f_bssmap_ie_cic_2_int(ass_cmd.pdu.bssmap.assignmentRequest.circuitIdentityCode);
		var MgcpEndpoint ep := int2str(cic) & "@mgw"; /* 1: matches value configured in BSC_Tests.ttcn pass in AssignReq */
		var MgcpCallId call_id := '51234'H;
		var SDP_attribute_list attributes := { valueof(ts_SDP_ptime(20)) };
		if (g_pars.use_osmux) {
			cmd := ts_CRCX_osmux(get_next_trans_id(), ep, "sendrecv", call_id, cic);
			resp := tr_CRCX_ACK_osmux;
		} else {
			cmd := ts_CRCX(get_next_trans_id(), ep, "sendrecv", call_id);
			resp := tr_CRCX_ACK;
		}
		cmd.sdp := ts_SDP(host_msc, host_mgw, "23", "42",
			     14000, { int2str(g_media.mgcp_conn[1].rtp_pt) },
			     { valueof(ts_SDP_ptime(20)) });
		mgcp_transceive_mgw(cmd, resp);
	}

	f_check_mgcp_expectations();

	if (st.is_assignment and st.assignment_done) {
	    if (not st.old_lchan_deact_sacch_seen) {
		setverdict(fail, "f_establish_fully(): Assignment completed, but the old lchan was not",
			   " released properly: expected a Deact SACCH on the old lchan, but saw none.");
	    }
	    if (st.old_lchan_rll_rel_req_seen) {
		setverdict(fail, "f_establish_fully(): Assignment completed, but the old lchan was not",
			   " released properly: saw an RLL Release on the old lchan, but expecting none.");
	    }
	}
}

type record HandoverState {
	/* Assignment related bits */
	boolean rr_ho_cmpl_seen,
	integer mdcx_seen_before_ho,
	boolean handover_done,
	RslChannelNr old_chan_nr
};

altstep as_handover(inout HandoverState st) runs on MSC_ConnHdlr {
	var RSL_Message rsl;
	[not st.rr_ho_cmpl_seen] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
		var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
		log("Rx L3 from net: ", l3);
		if (ischosen(l3.msgs.rrm.handoverCommand)) {
			var RslChannelNr new_chan_nr;
			var GsmArfcn arfcn;
			f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
					   new_chan_nr, arfcn);
			/* FIXME: Determine TRX NR by ARFCN, instead of hard-coded TRX0! */

			/* register our component for this channel number at the RSL Emulation */
			f_rslem_register(0, new_chan_nr, RSL1_PROC);

			/* resume processing of RSL DChan messages, which was temporarily suspended
			 * before performing a hand-over */
			f_rslem_resume(RSL1_PROC);

			/* send handover detect */
			RSL1.send(ts_RSL_HANDO_DET(new_chan_nr));
			f_sleep(0.3);

			/* send handover complete over the new channel */
			var PDU_ML3_MS_NW l3_tx := valueof(ts_RRM_HandoverComplete('00'O));
			RSL1.send(ts_RSL_EST_IND(new_chan_nr, valueof(ts_RslLinkID_DCCH(0)),
						  enc_PDU_ML3_MS_NW(l3_tx)));
			/* by default, send via the new channel from now */
			st.old_chan_nr := g_chan_nr;
			g_chan_nr := new_chan_nr;
			st.rr_ho_cmpl_seen := true;

			/* Memorize how many MDCX we have seen before. We need this number to detect
			 * that we have received the handover related MDCX */
			st.mdcx_seen_before_ho := g_media.mgcp_conn[0].mdcx_seen;
			repeat;
		} else {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Unexpected L3 received", l3));
		}
		}
	[st.rr_ho_cmpl_seen] as_Media_ipacc();
	[st.rr_ho_cmpl_seen] as_Media_mgw(true);
	[st.rr_ho_cmpl_seen] RSL.receive(tr_RSL_DEACT_SACCH(st.old_chan_nr)) {
		repeat;
		}
	[st.rr_ho_cmpl_seen] RSL.receive(tr_RSL_REL_REQ(st.old_chan_nr, tr_RslLinkID_DCCH(0))) {
		RSL.send(ts_RSL_REL_CONF(st.old_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
		repeat;
		}
	[st.rr_ho_cmpl_seen] RSL.receive(tr_RSL_RF_CHAN_REL(st.old_chan_nr)) {
		RSL.send(ts_RSL_RF_CHAN_REL_ACK(st.old_chan_nr));
		/* unregister for old channel number in RSL emulation */
		/* FIXME: Determine TRX NR by ARFCN, instead of hard-coded TRX0! */
		f_rslem_unregister(0, st.old_chan_nr);

		/* The channel release must not necessarly be synchronized to the RSL handover
		 * procedure since those events may happen independently nearly at the same
		 * time. When we receive the RSL_RF_CHAN_REL command the media negotiation on
		 * IPACC or MGCP level may be still in progress. In order to make sure that
		 * we do only stop when we have seen an MDCX on MGCP level and another a CRCX
		 * as well as an MDCX on IPACC level. */
		if (g_media.mgcp_conn[0].mdcx_seen <= st.mdcx_seen_before_ho or
		    g_media.bts1.ipa_mdcx_seen == false or g_media.bts1.ipa_crcx_seen == false) {
			repeat;
		} else {
			st.handover_done := true;
		}
		}
}



}
