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

/* 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();
	var charstring local_rtp_addr;

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

	/* 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,
	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 {
	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 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,
	charstring	host_aoip_tla,
	TestHdlrParamsMSCPool mscpool,
	boolean		media_mgw_offer_ipv6,
	OCT3		last_used_eutran_plmn optional,
	boolean		expect_channel_mode_modify
};

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

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

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

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



}
