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 BSSAP_LE_Emulation all;
import from BSSAP_LE_Types all;
import from BSSMAP_LE_Templates 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 StatsD_Checker 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;
import from TCCConversion_Functions all;


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

/* TODO: import OSMUX_Types.ttcn */
type INT1 OsmuxCID	(0 .. 255);

/* 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 */
	OsmuxCID local_osmux_cid optional,
	OsmuxCID remote_osmux_cid optional
};

/* 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,
	OsmuxCID local_osmux_cid optional,
	OsmuxCID remote_osmux_cid optional
};

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 := -,
		local_osmux_cid := nr,
		remote_osmux_cid := omit
	}

	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 := -,
		local_osmux_cid := nr,
		remote_osmux_cid := omit
	}

	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[i].local_osmux_cid := i;
		g_media.mgcp_conn[i].remote_osmux_cid := omit;
	}

	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(RSL_DCHAN_PT rsl_pt := RSL, RSL_DCHAN_PT rsl_pt_ho_target := RSL1) 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_pt.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;
		}
		if (f_rsl_find_ie(rsl, RSL_IE_OSMO_OSMUX_CID, ie)) {
			if (not g_pars.use_osmux_bts) {
				Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Rx unexpected IPAC CRCX with Osmux CID IE");
			}
			g_media.bts.remote_osmux_cid := ie.osmux_cid.cid;
		} else {
			if (g_pars.use_osmux_bts) {
				Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Rx unexpected IPAC CRCX without Osmux CID IE");
			}
			g_media.bts.local_osmux_cid := omit;
			g_media.bts.remote_osmux_cid := omit;
		}
		rsl_pt.send(ts_RSL_IPA_CRCX_ACK(g_chan_nr, g_media.bts.conn_id,
						f_inet_addr(g_media.bts.bts.host),
						g_media.bts.bts.port_nr,
						g_media.bts.rtp_pt,
						g_media.bts.local_osmux_cid));
		g_media.bts.ipa_crcx_seen := true;
		repeat;
		}
	[g_media.bts.ipa_crcx_seen] rsl_pt.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(ie.ipa_remote_ip);
		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;
		}
		if (f_rsl_find_ie(rsl, RSL_IE_OSMO_OSMUX_CID, ie)) {
			if (not g_pars.use_osmux_bts) {
				Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Rx unexpected IPAC MDCX with Osmux CID IE");
			}
			g_media.bts.remote_osmux_cid := ie.osmux_cid.cid;
		} else {
			if (g_pars.use_osmux_bts) {
				Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Rx unexpected IPAC MDCX without Osmux CID IE");
			}
			g_media.bts.local_osmux_cid := omit;
			g_media.bts.remote_osmux_cid := omit;
		}
		rsl_pt.send(ts_RSL_IPA_MDCX_ACK(g_chan_nr, g_media.bts.conn_id,
						f_inet_addr(g_media.bts.peer.host),
						g_media.bts.peer.port_nr,
						g_media.bts.rtp_pt,
						g_media.bts.local_osmux_cid));
		g_media.bts.ipa_mdcx_seen := true;
		repeat;
		}

	/* on second (new) BTS during hand-over */
	[not g_media.bts1.ipa_crcx_seen] rsl_pt_ho_target.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;
		}
		if (f_rsl_find_ie(rsl, RSL_IE_OSMO_OSMUX_CID, ie)) {
			if (not g_pars.use_osmux_bts) {
				Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Rx unexpected IPAC CRCX with Osmux CID IE");
			}
			g_media.bts.remote_osmux_cid := ie.osmux_cid.cid;
		} else {
			if (g_pars.use_osmux_bts) {
				Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Rx unexpected IPAC CRCX without Osmux CID IE");
			}
			g_media.bts.local_osmux_cid := omit;
			g_media.bts.remote_osmux_cid := omit;
		}
		rsl_pt_ho_target.send(ts_RSL_IPA_CRCX_ACK(g_chan_nr, g_media.bts1.conn_id,
						f_inet_addr(g_media.bts1.bts.host),
						g_media.bts1.bts.port_nr,
						g_media.bts1.rtp_pt,
						g_media.bts.local_osmux_cid));
		g_media.bts1.ipa_crcx_seen := true;
		repeat;
		}
	/* on second (new) BTS during hand-over */
	[g_media.bts1.ipa_crcx_seen] rsl_pt_ho_target.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(ie.ipa_remote_ip);
		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;
		}
		if (f_rsl_find_ie(rsl, RSL_IE_OSMO_OSMUX_CID, ie)) {
			if (not g_pars.use_osmux_bts) {
				Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Rx unexpected IPAC MDCX with Osmux CID IE");
			}
			g_media.bts.remote_osmux_cid := ie.osmux_cid.cid;
		} else {
			if (g_pars.use_osmux_bts) {
				Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Rx unexpected IPAC MDCX without Osmux CID IE");
			}
			g_media.bts.local_osmux_cid := omit;
			g_media.bts.remote_osmux_cid := omit;
		}
		rsl_pt_ho_target.send(ts_RSL_IPA_MDCX_ACK(g_chan_nr, g_media.bts1.conn_id,
						f_inet_addr(g_media.bts1.peer.host),
						g_media.bts1.peer.port_nr,
						g_media.bts1.rtp_pt,
						g_media.bts.local_osmux_cid));
		g_media.bts1.ipa_mdcx_seen := true;
		repeat;
		}


}

function f_rx_crcx(MgcpCommand mgcp_cmd)
	 runs on MSC_ConnHdlr return template MgcpResponse {
	var SDP_Message sdp;
	var integer cid := f_get_free_mgcp_conn();
	var charstring local_rtp_addr;
	var MgcpOsmuxCID osmux_cid;

	if (g_pars.media_mgw_offer_ipv6 == true) {
		local_rtp_addr := host_mgw_rtp_v6; /* Use IPv6 by default if no remote addr is provided by client */
	} else {
		local_rtp_addr := host_mgw_rtp_v4; /* Use IPv4 by default if no remote addr is provided by client */
	}

	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;
		if (sdp.connection.addr_type == "IP6") {
			local_rtp_addr := host_mgw_rtp_v6;
		} else {
			local_rtp_addr := host_mgw_rtp_v4;
		}
	}
	var MgcpConnState mgcp_conn := g_media.mgcp_conn[cid];
	sdp := valueof(ts_SDP(mgcp_conn.mgw.host, local_rtp_addr, "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_cn or g_pars.use_osmux_bts) and
	    f_MgcpCmd_contains_par(mgcp_cmd, "X-OSMUX")) {
		osmux_cid := f_MgcpCmd_extract_osmux_cid(mgcp_cmd);
		if (osmux_cid != -1) {
			mgcp_conn.remote_osmux_cid := osmux_cid;
		}
		mgcp_resp := ts_CRCX_ACK_osmux(mgcp_cmd.line.trans_id, mgcp_conn.conn_id, mgcp_conn.local_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));
	var charstring local_rtp_addr;
	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;
		if (sdp.connection.addr_type == "IP6") {
			local_rtp_addr := host_mgw_rtp_v6;
		} else {
			local_rtp_addr := host_mgw_rtp_v4;
		}
	} 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, local_rtp_addr, "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, boolean fail_on_dlcx := true) 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_dlcx := {
		command := tr_DLCX
	}
	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;
		}
	}

	[fail_on_dlcx and g_pars.aoip] MGCP.receive(tr_DLCX) {
		setverdict(fail, "Unexpected DLCX received");
	}

	[fail_on_dlcx and not g_pars.aoip] MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_dlcx)) {
		setverdict(fail, "Unexpected DLCX received");
	}
}

/* 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(boolean fail_on_dlcx := true) runs on MSC_ConnHdlr {
	[] as_Media_ipacc();
	[] as_Media_mgw(fail_on_dlcx := fail_on_dlcx);
}

type port Coord_PT message
{
	inout charstring;
} with { extension "internal" };

/* 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, BSSAP_LE_ConnHdlr, StatsD_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;
	port Coord_PT COORD;
	port Coord_PT COORD2;

	/* 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_mgcp := "127.0.0.3";
	var charstring host_mgw_rtp_v4 := "127.0.0.5";
	var charstring host_mgw_rtp_v6 := "::1";
	var charstring host_msc := "127.0.0.4";

	var boolean g_vty_initialized := false;
}

function f_MscConnHdlr_init_vty() runs on MSC_ConnHdlr {
	if (not g_vty_initialized) {
		map(self:BSCVTY, system:BSCVTY);
		f_vty_set_prompts(BSCVTY);
		f_vty_transceive(BSCVTY, "enable");
		g_vty_initialized := true;
	}
}

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

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

/* Callback function from general BSSAP_LE_Emulation whenever a connectionless
 * BSSAP_LE message arrives.  Can return a PDU_BSSAP_LE that should be sent in return */
private function BSSAP_LE_UnitdataCallback(PDU_BSSAP_LE bssap)
runs on BSSAP_LE_Emulation_CT return template PDU_BSSAP_LE {
	var template PDU_BSSAP_LE resp := omit;

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

	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,
	bssap_reset_retries := 1,
	sccp_addr_local := omit,
	sccp_addr_peer := omit
}

const BssapLeOps SMLC_BssapLeOps := {
	create_cb := refers(BSSAP_LE_Emulation.ExpectedCreateCallback),
	unitdata_cb := refers(BSSAP_LE_UnitdataCallback),
	decode_dtap := false,
	role_ms := 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 */
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 {
	/* A mask of multiple encryption algorithms, for Encryption Information IE. */
	OCT1		enc_alg_permitted,
	/* Expect this encryption algorithm in Channel Activation from the BSC.
	 * To expect no encryption, set to '01'O == A5/0. */
	OCT1		enc_alg_expect,
	/* In BSSMAP, the Chosen Encryption Algorithm IE that the test sends to the BSC.
	 * When set to omit, the MSC will not send a Chosen Encryption Algorithm IE. */
	OCT1		enc_alg_chosen optional,
	octetstring	enc_key,
	octetstring	enc_kc128 optional
};

template (value) TestHdlrEncrParams t_EncrParams(OCT1 alg_permitted,
						 octetstring key, template (omit) octetstring kc128 := omit) := {
	enc_alg_permitted := alg_permitted,
	enc_alg_expect := alg_permitted, /* <- for compat with tests before enc_alg_expect was added */
	enc_alg_chosen := alg_permitted, /* <- for compat with tests before enc_alg_chosen was added */
	enc_key := key,
	enc_kc128 := kc128
}

template (value) TestHdlrEncrParams t_EncrParams2(OCT1 alg_permitted,
						  OCT1 alg_expect,
						  template(omit) OCT1 alg_chosen,
						  octetstring key,
						  template (omit) octetstring kc128 := omit) := {
	enc_alg_permitted := alg_permitted,
	enc_alg_expect := alg_expect,
	enc_alg_chosen := alg_chosen,
	enc_key := key,
	enc_kc128 := kc128
}

/* Convenience for common t_EncrParams2 usage.
 *
 * To test a scenario where only A5/3 is permitted:
 *   f_encr_params('08'O);
 * To test a scenario where A5/3 is chosen from A5/0,A5/1,A5/3 (1 | 2 | 8 = 11 = 0xb):
 *   f_encr_params('0b'O, '08'O);
 * To test the same, but the Chosen Encryption Algorithm IE should reflect A5/1:
 *   f_encr_params('0b'O, '08'O, '02'O);
 * To test the same, but the MSC sends no Chosen Encryption Algorithm IE:
 *   f_encr_params('0b'O, '08'O, omit);
 *
 * Set alg_chosen and alg_expect magically when == '00'O:
 * - enc_alg_expect is set to alg_chosen if present, else to alg_permitted.
 * - enc_alg_chosen is set to alg_permitted.
 * When only alg_permitted is given, alg_permitted must reflect only one algorithm, or f_cipher_mode_bssmap_to_rsl()
 * will fail.
 * When alg_chosen is passed as omit, the messages from the MSC will not contain a Chosen Encryption Algorithm IE.
 */
function f_encr_params(OCT1 alg_permitted, OCT1 alg_expect := '00'O, template (omit) OCT1 alg_chosen := '00'O,
		       boolean kc128 := false)
	 return TestHdlrEncrParams
{
	if (not istemplatekind(alg_chosen, "omit")) {
		if (valueof(alg_chosen) == '00'O) {
			if (alg_expect != '00'O) {
				alg_chosen := alg_expect;
			} else {
				/* In this case, alg_permitted should have only one permitted algo */
				alg_chosen := alg_permitted;
			}
		}
		if (alg_expect == '00'O) {
			alg_expect := valueof(alg_chosen);
		}
	}
	if (alg_expect == '00'O) {
		/* In this case, alg_permitted should have only one permitted algo */
		alg_expect := valueof(alg_permitted);
	}
	var template (omit) octetstring kc := omit;
	if (kc128) {
		kc := f_rnd_octstring(16);
	}
	return valueof(t_EncrParams2(alg_permitted, alg_expect, alg_chosen, f_rnd_octstring(8), kc));
}

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 TestHdlrParamsMSCPool {
	integer bssap_idx,
	integer rsl_idx,
	PDU_ML3_MS_NW l3_info optional
}

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,
	SCCP_PAR_Address sccp_addr_msc optional,
	SCCP_PAR_Address sccp_addr_bsc optional,
	uint5_t 	exp_ms_power_level,
	boolean         exp_ms_power_params,
	boolean		aoip,
	boolean		use_osmux_cn,
	boolean		use_osmux_bts,
	charstring	host_aoip_tla,
	TestHdlrParamsMSCPool mscpool,
	boolean		media_mgw_offer_ipv6,
	OCT3		last_used_eutran_plmn optional,
	boolean		exp_fast_return, /* RR Release expected to contain CellSelectInd ? */
	boolean		expect_channel_mode_modify,
	uint3_t		expect_tsc optional,
	BSSMAP_IE_CellIdentifier	cell_id_source,
	boolean		expect_ho_fail,
	boolean		inter_bsc_ho_in__ho_req_in_initial_sccp_cr
};

/* 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 (aoip 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
	},
	sccp_addr_msc := omit,
	sccp_addr_bsc := omit,
	exp_ms_power_level := 7, /* calculated from osmo-bsc.cfg "ms max power" */
	exp_ms_power_params := false,
	aoip := true,
	use_osmux_cn := false,
	use_osmux_bts := false,
	host_aoip_tla := "1.2.3.4",
	mscpool := {
		bssap_idx := 0,
		rsl_idx := 0,
		l3_info := omit
	},
	media_mgw_offer_ipv6 := true,
	last_used_eutran_plmn := omit,
	exp_fast_return := false,
	expect_channel_mode_modify := false,
	expect_tsc := omit,
	cell_id_source := valueof(ts_CellID_LAC_CI(1, 1)),
	expect_ho_fail := false,
	inter_bsc_ho_in__ho_req_in_initial_sccp_cr := true
}

function f_create_chan_and_exp(template (present) PDU_BSSAP exp_l3_compl := ?)
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);
	var template uint3_t tsc := ?;
	timer T;

	if (not istemplatekind(g_pars.expect_tsc, "omit")) {
		tsc := g_pars.expect_tsc;
	}

	if (istemplatekind(exp_l3_compl, "?")) {
		if (g_pars.aoip == false) {
			exp_l3_compl := tr_BSSMAP_ComplL3(l3_enc, codec_list := omit);
		} else {
			exp_l3_compl := tr_BSSMAP_ComplL3(l3_enc, codec_list := ?);
		}
	}

	f_create_bssmap_exp(l3_enc);
	/* 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, tsc);
	/* wait for a COMPL_L3 from the BSC to ensure that the SCCP connection is up */
	T.start(2.0);
	alt {
	[] BSSAP.receive(exp_l3_compl);
	[] BSSAP.receive(tr_BSSMAP_ComplL3) {
		setverdict(fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
		}
	}
}

function f_rsl_send_l3(template PDU_ML3_MS_NW l3, template (omit) RslLinkId link_id := omit,
			template (omit) RslChannelNr chan_nr := omit, RSL_DCHAN_PT rsl_pt := RSL) 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_pt.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, RSL_DCHAN_PT rsl_pt := RSL) 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, rsl_pt := rsl_pt);
}

/* Convert the cipher representation on BSSMAP to the representation used on RSL */
function f_cipher_mode_bssmap_to_rsl(OCT1 alg_bssmap) return RSL_AlgId
{
	select (alg_bssmap) {
	case ('01'O) { return RSL_ALG_ID_A5_0; }
	case ('02'O) { return RSL_ALG_ID_A5_1; }
	case ('04'O) { return RSL_ALG_ID_A5_2; }
	case ('08'O) { return RSL_ALG_ID_A5_3; }
	case ('10'O) { return RSL_ALG_ID_A5_4; }
	case ('20'O) { return RSL_ALG_ID_A5_5; }
	case ('40'O) { return RSL_ALG_ID_A5_6; }
	case ('80'O) { return RSL_ALG_ID_A5_7; }
	case else {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Unexpected Encryption Algorithm: " &
					oct2str(alg_bssmap));
		return RSL_ALG_ID_A5_0;
		}
	}
}

/* Convert the cipher representation on BSSMAP to the one used on RR (3GPP TS 44.018) */
function f_cipher_mode_bssmap_to_rr(OCT1 alg_bssmap) return BIT3
{
	select (alg_bssmap) {
	case ('01'O) /* A5/0 */ { return '000'B; } /* SC=0 */
	case ('02'O) /* A5/1 */ { return '000'B; } /* SC=1 */
	case ('04'O) /* A5/2 */ { return '001'B; } /* SC=1 */
	case ('08'O) /* A5/3 */ { return '010'B; } /* SC=1 */
	case ('10'O) /* A5/4 */ { return '011'B; } /* SC=1 */
	case ('20'O) /* A5/5 */ { return '100'B; } /* SC=1 */
	case ('40'O) /* A5/6 */ { return '101'B; } /* SC=1 */
	case ('80'O) /* A5/7 */ { return '110'B; } /* SC=1 */
	case else {
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Unexpected Encryption Algorithm: " &
					oct2str(alg_bssmap));
		return '000'B;
		}
	}
}

function f_verify_encr_info(RSL_Message rsl) runs on MSC_ConnHdlr {
	var RSL_IE_Body encr_info;
	var RSL_AlgId alg_rsl;
	var template octetstring expect_kc;

	/* If no encryption is enabled, then make sure there is no RSL_IE_ENCR_INFO */
	if (not ispresent(g_pars.encr)) {
		if (f_rsl_find_ie(rsl, RSL_IE_ENCR_INFO, encr_info)) {
			setverdict(fail, "Found Encryption IE, but expected no encryption in ", rsl.msg_type);
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
			return;
		}
		setverdict(pass);
		return;
	}

	/* RSL uses a different representation of the encryption algorithm,
	 * so we need to convert first */
	alg_rsl := f_cipher_mode_bssmap_to_rsl(g_pars.encr.enc_alg_expect);

	if (alg_rsl == RSL_ALG_ID_A5_4 and ispresent(g_pars.encr.enc_kc128)) {
		expect_kc := g_pars.encr.enc_kc128;
	} else if (alg_rsl == RSL_ALG_ID_A5_0) {
		/* When A5/0 is chosen, no encryption is active, so technically, no key is needed. However, 3GPP TS
		 * 48.058 9.3.7 Encryption Information stays quite silent about presence or absence of a key for A5/0.
		 * The only thing specified is how to indicate the length of the key; the possibility that the key may
		 * be zero length is not explicitly mentioned. So it seems that we should always send the key along,
		 * even for A5/0. Still, let's also allow a zero length key for A5/0. */
		expect_kc := (g_pars.encr.enc_key, ''O);
	} else {
		expect_kc := g_pars.encr.enc_key;
	}
	log("for encryption algo ", alg_rsl, " expect kc = ", expect_kc);

	if (not f_rsl_find_ie(rsl, RSL_IE_ENCR_INFO, encr_info)) {
		if (alg_rsl == RSL_ALG_ID_A5_0) {
			/* For A5/0, encryption is not active. It is fine to omit the Encryption Information in this
			 * case. Note that the first channel may see an RSL Encryption Command with A5/0 indicated, and
			 * a subsequent handover may activate a new channel without any Encryption Information. */
			setverdict(pass);
			return;
		}
		setverdict(fail, "Missing Encryption Information IE in ", rsl.msg_type);
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
		return;
	}

	if (not match(encr_info, tr_EncrInfo(alg_rsl, expect_kc))) {
		setverdict(fail, "Unexpected Kc in Encryption Information IE in ", rsl.msg_type);
		Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
		return;
	}
	setverdict(pass);
}

function f_cipher_mode(TestHdlrEncrParams enc, boolean exp_fail := false,
                       RSL_DCHAN_PT rsl_pt := RSL, RSLEM_PROC_PT rsl_proc_pt := RSL_PROC)
runs on MSC_ConnHdlr {
	var PDU_BSSAP bssap;
	var RSL_Message rsl;

	if (isvalue(enc.enc_kc128)) {
		BSSAP.send(ts_BSSMAP_CipherModeCmdKc128(enc.enc_alg_permitted, enc.enc_key, valueof(enc.enc_kc128)));
	} else {
		BSSAP.send(ts_BSSMAP_CipherModeCmd(enc.enc_alg_permitted, enc.enc_key));
	}

	alt {
	/* RSL/UE Side */
	[] rsl_pt.receive(tr_RSL_ENCR_CMD(g_chan_nr)) -> 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);

		f_verify_encr_info(rsl);

		if (ischosen(l3.msgs.rrm.cipheringModeCommand)) {
			f_rsl_reply(ts_RRM_CiphModeCompl, rsl, rsl_pt := rsl_pt);
		}
		repeat;
		}
	[] BSSAP.receive(tr_BSSMAP_CipherModeCompl) -> value bssap {
		if (exp_fail == true) {
			Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Unexpected Cipher Mode Complete");
		} else {
			setverdict(pass);
			var RSL_AlgId alg_rsl := f_cipher_mode_bssmap_to_rsl(g_pars.encr.enc_alg_expect);
			if (oct2int(bssap.pdu.bssmap.cipherModeComplete.chosenEncryptionAlgorithm.algorithmIdentifier) != enum2int(alg_rsl)) {
				setverdict(fail, "Unexpected Encryption Algorithm ID in BSSMAP Cipher Mode Complete");
			}
		}
		}
	[] 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);

	select (inp) {
	case ('00001'B) { /* TCH/F */
		chan_nr := valueof(t_RslChanNr_Bm(tn));
		}
	case ('11101'B) { /* VAMOS TCH/F */
		chan_nr := valueof(t_RslChanNr_Osmo_VAMOS_Bm(tn));
		}
	case ('0001?'B) { /* TCH/H */
		chan_nr := valueof(t_RslChanNr_Lm(tn, bit2int(substr(inp, 4, 1))));
		}
	case ('1111?'B) { /* VAMOS TCH/H */
		chan_nr := valueof(t_RslChanNr_Osmo_VAMOS_Lm(tn, bit2int(substr(inp, 4, 1))));
		}
	case ('001??'B) { /* SDCCH/4 */
		chan_nr := valueof(t_RslChanNr_SDCCH4(tn, bit2int(substr(inp, 3, 2))));
		}
	case ('01???'B) { /* SDCCH/8 */
		chan_nr := valueof(t_RslChanNr_SDCCH8(tn, bit2int(substr(inp, 2, 3))));
		}
	case 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 */
	PDU_ML3_NW_MS rr_channel_mode_modify_msg optional,
	boolean rr_modify_seen,
	RSL_Message rsl_mode_modify_msg optional,
	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_channel_mode_modify_msg := omit,
	rr_modify_seen := false,
	rsl_mode_modify_msg := omit,
	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_permitted != '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_cipher_mode_bssmap_to_rsl(g_pars.encr.enc_alg_expect);
			var octetstring expect_key;
			if (alg == RSL_ALG_ID_A5_4) {
				expect_key := g_pars.encr.enc_kc128;
			} else {
				expect_key := g_pars.encr.enc_key;
			}
			if (not match(encr_info, tr_EncrInfo(alg, expect_key))) {
				Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
							"Unexpected Kc in Encryption IE in RSL ENCR CMD");
			}
		}
	} 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));
		}
	}

}

function rr_chan_desc_tsc(ChannelDescription2_V cd2)
	return uint3_t
{
	var uint3_t tsc := oct2int(cd2.octet3);
	tsc := tsc / 32; /* shl 5 */
	return tsc;
}

altstep as_assignment(inout AssignmentState st, RSL_DCHAN_PT rsl_pt := RSL, RSLEM_PROC_PT rsl_proc_pt := RSL_PROC) runs on MSC_ConnHdlr {
	var RSL_Message rsl;
	[not st.rr_ass_cmpl_seen] rsl_pt.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;

			if (not istemplatekind(g_pars.expect_tsc, "omit")) {
				var uint3_t got_tsc := rr_chan_desc_tsc(l3.msgs.rrm.assignmentCommand.descrOf1stChAfterTime);
				if (not match(got_tsc, g_pars.expect_tsc)) {
					setverdict(fail, "RR Assignment: unexpected TSC in Channel Description: expected ",
						   g_pars.expect_tsc, " got ", got_tsc);
					mtc.stop;
				}
			}

			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, PT := rsl_proc_pt);
			/* dispatch queued messages for this channel (if any) */
			f_rslem_dchan_queue_dispatch(PT := rsl_proc_pt);

			var PDU_ML3_MS_NW l3_tx := valueof(ts_RRM_AssignmentComplete('00'O));
			/* send assignment complete over the new channel */
			rsl_pt.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_pt, 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_pt.receive(tr_RSL_DEACT_SACCH(st.old_chan_nr)) {
		st.old_lchan_deact_sacch_seen := true;
		repeat;
		}
	[st.rr_ass_cmpl_seen] rsl_pt.receive(tr_RSL_REL_REQ(st.old_chan_nr, tr_RslLinkID_DCCH(0))) {
		st.old_lchan_rll_rel_req_seen := true;
		rsl_pt.send(ts_RSL_REL_CONF(st.old_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
		repeat;
		}
	[st.rr_ass_cmpl_seen] rsl_pt.receive(tr_RSL_RF_CHAN_REL(st.old_chan_nr)) {
		rsl_pt.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, PT := rsl_proc_pt);
		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)) {
			st.rr_channel_mode_modify_msg := l3;
			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 {
		st.rsl_mode_modify_msg := 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(TELNETasp_PT vty, BSSMAP_IE_ChannelType bssmap, RslChannelNr rsl_chan_nr)
return boolean {

	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; }
	       case (t_RslChanNr_Bm(?)) {
			/* TCH/F, always subslot 0 */
			var charstring res := f_vty_transceive_ret(vty, "show lchan 0 0 " & int2str(rsl_chan_nr.tn) & " 0");
			if (f_strstr(res, "Channel Mode / Codec: SIGNALLING", 0) >= 0) {
				current_signalling := true;
			}
	       }
	       case (t_RslChanNr_Lm(?, ?)) {
			/* TCH/H */
			var charstring res := f_vty_transceive_ret(vty, "show lchan 0 0 " & int2str(rsl_chan_nr.tn)
								   & " " & int2str(rsl_chan_nr.u.lm.sub_chan));
			if (f_strstr(res, "Channel Mode / Codec: SIGNALLING", 0) >= 0) {
				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 (not istemplatekind(ass_tpl, "omit") and 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_mgcp, codecType);

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

	f_create_chan_and_exp();

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

	/* 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 */
		st.is_assignment := false;
		exp_modify := f_channel_needs_modify(BSCVTY, 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;
	}

	/* On receipt of the BSSAP Assignment Command, the IUT (osmo-bsc) will allocate
	 * a channel and send us RR Assignment Command together with ip.access CRCX.
	 * There is a risk that the RSL Emulation component would dequeue and process
	 * ip.access CRCX faster than we process the Assignment Command and register
	 * the corresponding handler for the indicated RSL channel number. This would
	 * result in a failure, because at that moment there will be no handler for
	 * ip.access CRCX. Let's guard against this and enable additional queueing. */
	f_rslem_dchan_queue_enable();

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

	if (exp_modify) {
		/* Verify that the RR Channel Mode Modify and RSL MODE MODIFY message asked for the expected channel
		 * mode. */
		/* TODO: more precisely expect the different types of speech? */
		var OCT1 rr_channel_mode := st.rr_channel_mode_modify_msg.msgs.rrm.channelModeModify.channelMode.mode;

		if (st.voice_call and rr_channel_mode == '00'O) {
			setverdict(fail, "f_establish_fully(): Expected RR Channel Mode Modify",
				   " to a speech mode, but got channelMode == ", rr_channel_mode);
			mtc.stop;
		} else if (not st.voice_call and rr_channel_mode != '00'O) {
			setverdict(fail, "f_establish_fully(): Expected RR Channel Mode Modify",
				   " to signalling mode, but got channelMode == ", rr_channel_mode);
			mtc.stop;
		}

		var RSL_IE_Body chan_mode_ie;
		if (not f_rsl_find_ie(st.rsl_mode_modify_msg, RSL_IE_CHAN_MODE, chan_mode_ie)) {
			setverdict(fail, "RSL MODE MODIFY message lacks a Channel Mode IE");
			mtc.stop;
		}
		var RSL_SpeechDataInd rsl_spd_ind := chan_mode_ie.chan_mode.spd_ind;
		if (st.voice_call and rsl_spd_ind != RSL_SPDI_SPEECH) {
			setverdict(fail, "f_establish_fully(): Expected RSL MODE MODIFY",
				   " to a speech mode, but got spd_ind == ", rsl_spd_ind);
			mtc.stop;
		} else if (not st.voice_call and rsl_spd_ind != RSL_SPDI_SIGN) {
			setverdict(fail, "f_establish_fully(): Expected RSL MODE MODIFY",
				   " to signalling mode, but got spd_ind == ", rsl_spd_ind);
			mtc.stop;
		}

		if (not istemplatekind(g_pars.expect_tsc, "omit")) {
			var uint3_t got_tsc := rr_chan_desc_tsc(st.rr_channel_mode_modify_msg.msgs.rrm.channelModeModify.channelDescription);
			if (not match(got_tsc, g_pars.expect_tsc)) {
				setverdict(fail, "RR Channel Mode Modify: unexpected TSC in Channel Description: expected ",
					   g_pars.expect_tsc, " got ", got_tsc);
				mtc.stop;
			}
		}

	} else {
		/* not exp_modify, so this did a Channel Activate */

		/* Check the TSC */
		if (not istemplatekind(g_pars.expect_tsc, "omit")) {
			var RSL_Message chan_act := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
			var RSL_IE_Body ie;
			if (f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, ie)) {
				var uint3_t got_tsc := ie.chan_ident.ch_desc.v.tsc;
				if (not match(got_tsc, g_pars.expect_tsc)) {
					setverdict(fail, "RSL CHANnel ACTIVation: unexpected TSC in Channel Description: expected ",
						   g_pars.expect_tsc, " got ", got_tsc);
					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_cn) {
			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_rtp_v4, "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.");
	    }
	}

	var charstring lchan_info := f_vty_transceive_ret(BSCVTY, "show lchan 0 0 " & int2str(g_chan_nr.tn) & " 0");
	if (f_strstr(lchan_info, "State: ESTABLISHED") < 0) {
		log("after f_establish_fully(), 'show lchan' replied: ", lchan_info);
		setverdict(fail, "lchan is not in state ESTABLISHED");
		mtc.stop;
	}
}

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

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

			/* Verify correct TSC in handoverCommand */
			if (ispresent(st.expect_target_tsc)) {
				var uint3_t got_tsc := rr_chan_desc_tsc(l3.msgs.rrm.handoverCommand.channelDescription2);
				if (not match(got_tsc, st.expect_target_tsc)) {
					setverdict(fail, "RR Handover Command: unexpected TSC in Channel Description: expected ",
						   st.expect_target_tsc, " got ", got_tsc);
					mtc.stop;
				} else {
					log("handoverCommand: verified TSC = ", got_tsc, " (matches ",
					    st.expect_target_tsc, ")");
				}
			}

			/* 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();
	[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 ipa_crcx_seen is false, this is not a voice channel and we need not check MGCP at all.. */
		if (g_media.bts.ipa_crcx_seen
		    and (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;
		}
		}
}



}
