module MSC_ConnectionHandler {

import from General_Types all;
import from Osmocom_Types all;
import from GSM_Types all;
import from SCCPasp_Types all;
import from BSSAP_Types all;
import from BSSMAP_Emulation all;
import from BSSMAP_Templates all;

import from IPL4asp_Types all;
import from Native_Functions all;

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

import from RSL_Emulation all;
import from RSL_Types all;

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

import from TELNETasp_PortType all;
import from Osmocom_VTY_Functions all;


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

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

/* State encapsulating one MGCP Connection */
type record MgcpConnState {
	boolean crcx_seen,
	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,
	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) {
	/* BTS Side */
	g_media.bts := {
		ipa_crcx_seen := false,
		conn_id := nr,
		rtp_pt := 0,
		bts := {
			host := bts,
			port_nr := 9000 + nr*2
		},
		peer := -
	}

	g_media.bts1 := {
		ipa_crcx_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 := "AMR";
		g_media.mgcp_conn[i].sample_rate := 8000;
		g_media.mgcp_conn[i].ptime := 20;
		g_media.mgcp_conn[i].rtp_pt := 98;
		g_media.mgcp_conn[i].crcx_seen := false;
		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
	}
}

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) {
			return i;
		}
	}
	setverdict(fail, "Only 2 Connections per EP!");
	self.stop;
	return -1;
}

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) {
			return i;
		}
	}
	setverdict(fail, "No Connection for ID ", cid);
	self.stop;
	return -1;
}


/* altstep for handling of IPA + MGCP 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 {
	var RSL_Message rsl;
	var MgcpCommand mgcp_cmd;
	var RSL_IE_Body ie;
	[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 */
		f_rsl_find_ie(rsl, RSL_IE_IPAC_CONN_ID, ie);
		if (g_media.bts.conn_id != ie.ipa_conn_id) {
			setverdict(fail, "IPA MDCX for unknown ConnId", rsl);
			self.stop;
		}
		/* mandatory */
		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));
		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 */
		f_rsl_find_ie(rsl, RSL_IE_IPAC_CONN_ID, ie);
		if (g_media.bts1.conn_id != ie.ipa_conn_id) {
			setverdict(fail, "IPA MDCX for unknown ConnId", rsl);
			self.stop;
		}
		/* mandatory */
		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));
		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;
		}

	[] MGCP.receive(tr_CRCX) -> value mgcp_cmd {
		var SDP_Message sdp;
		var integer cid := f_get_free_mgcp_conn();
		if (match(mgcp_cmd.line.ep, t_MGCP_EP_wildcard)) {
			if (cid != 0) {
				setverdict(fail, "MGCP wildcard EP only works in first CRCX");
				self.stop;
			}
			/* we keep the endpoint name allocated during MediaState_init */
		} else {
			/* Call Agent allocated endpoint, trust/use it always */
			g_media.mgcp_ep := mgcp_cmd.line.ep;
		}
		if (isvalue(mgcp_cmd.sdp)) {
			sdp := mgcp_cmd.sdp;
			g_media.mgcp_conn[cid].peer.host := sdp.connection.conn_addr.addr;
			g_media.mgcp_conn[cid].peer.port_nr := sdp.media_list[0].media_field.ports.port_number;
		}
		var MgcpConnState mgcp_conn := g_media.mgcp_conn[cid];
		sdp := valueof(ts_SDP(mgcp_conn.mgw.host, mgcp_conn.mgw.host, "foo", "21",
					mgcp_conn.mgw.port_nr, { int2str(mgcp_conn.rtp_pt) },
				{valueof(ts_SDP_rtpmap(mgcp_conn.rtp_pt,
							mgcp_conn.mime_type & "/" &
							int2str(mgcp_conn.sample_rate))),
				valueof(ts_SDP_ptime(mgcp_conn.ptime)) } ));
		var template MgcpResponse mgcp_resp;
		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));
		MGCP.send(mgcp_resp);
		g_media.mgcp_conn[cid].crcx_seen := true;
		repeat;
		}
	[] MGCP.receive(tr_MDCX) -> value mgcp_cmd {
		var SDP_Message sdp;
		var integer cid := f_get_mgcp_conn(f_MgcpCmd_extract_conn_id(mgcp_cmd));
		if (isvalue(mgcp_cmd.sdp)) {
			sdp := mgcp_cmd.sdp;
			g_media.mgcp_conn[cid].peer.host := sdp.connection.conn_addr.addr;
			g_media.mgcp_conn[cid].peer.port_nr := sdp.media_list[0].media_field.ports.port_number;
		} else {
			setverdict(fail, "MDCX has no [recognizable] SDP");
		}
		var MgcpConnState mgcp_conn := g_media.mgcp_conn[cid];
		sdp := valueof(ts_SDP(mgcp_conn.peer.host, mgcp_conn.peer.host, "foo", "21",
					mgcp_conn.peer.port_nr, { int2str(mgcp_conn.rtp_pt) },
				{valueof(ts_SDP_rtpmap(mgcp_conn.rtp_pt,
							mgcp_conn.mime_type & "/" &
							int2str(mgcp_conn.sample_rate))),
				valueof(ts_SDP_ptime(mgcp_conn.ptime)) } ));
		MGCP.send(ts_MDCX_ACK(mgcp_cmd.line.trans_id, mgcp_conn.conn_id, sdp));
		//g_media.mgcp_mdcx_seen := true;
		repeat;
	}
}




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

	/* procedure port back to our parent (BSSMAP_Emulation_CT) for control */
	port BSSMAPEM_PROC_PT BSSMAPEM;
	port TELNETasp_PT BSCVTY;

	var MediaState g_media;
	var TestHdlrParams g_pars;
}

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

/* Callback function from general BSSMAP_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 BSSMAP_Emulation_CT return template PDU_BSSAP {
	var template PDU_BSSAP resp := omit;

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

	return resp;
}

const BssmapOps MSC_BssmapOps := {
	create_cb := refers(BSSMAP_Emulation.ExpectedCreateCallback),
	unitdata_cb := refers(UnitdataCallback),
	decode_dtap := false,
	role_ms := false
}

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

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

type record TestHdlrParams {
	OCT1		ra,
	GsmFrameNumber	fn,
	hexstring	imsi,
	RslLinkId	link_id
};

template (value) TestHdlrParams t_def_TestHdlrPars := {
	ra := '23'O,
	fn := 23,
	imsi := '001019876543210'H,
	link_id := valueof(ts_RslLinkID_DCCH(0))
}

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 OCT1
{
	/* A5 0 */
	if (alg_bssmap == '01'O) {
		return '01'O;
	}
	/* A5 1 */
	else if (alg_bssmap == '02'O) {
		return '02'O;
	}
	/* A5 2 */
	else if (alg_bssmap == '04'O) {
		return '03'O;
	}
	/* A5 3 */
	else if (alg_bssmap == '08'O) {
		return '04'O;
	}
	/* A5 4 */
	else if (alg_bssmap == '10'O) {
		return '05'O;
	}
	/* A5 5 */
	else if (alg_bssmap == '20'O) {
		return '06'O;
	}
	/* A5 6 */
	else if (alg_bssmap == '40'O) {
		return '07'O;
	}
	/* A5 7 */
	else if (alg_bssmap == '80'O) {
		return '08'O;
	} else {
		setverdict(fail, "Unexpected Encryption Algorithm");
		return '00'O;
	}
}

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 OCT1 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) {
			setverdict(fail, "Unexpected Cipher Mode Complete");
		} else {
			setverdict(pass);
		}
		}
	[] BSSAP.receive(tr_BSSMAP_CipherModeRej) -> value bssap {
		if (exp_fail == false) {
			setverdict(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;

	chan_nr.tn := bit2int(ch_desc.timeslotNumber);

	if (match(inp, '00001'B)) { /* TCH/F */
		chan_nr.u.ch0 := RSL_CHAN_NR_Bm_ACCH;
	}
	else if (match(inp, '0001?'B)) { /* TCH/H */
		chan_nr.u.lm.sub_chan := bit2int(substr(inp, 4, 1));
	}
	else if (match(inp, '001??'B)) { /* SDCCH/4 */
		chan_nr.u.sdcch4.sub_chan := bit2int(substr(inp, 3, 2));
	}
	else if (match(inp, '01???'B)) { /* SDCCH/8 */
		chan_nr.u.sdcch8.sub_chan := bit2int(substr(inp, 2, 3));
	}
	else {
		setverdict(fail, "Unknown ChDesc!");
		self.stop;
	}

	if (ch_desc.octet3 and4b '10'O == '10'O) {
		setverdict(fail, "No support for Hopping");
		self.stop;
	} 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 assignment_done,
	RslChannelNr old_chan_nr,
	/* Modify related bits */
	boolean rr_modify_seen,
	boolean modify_done
}

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

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

			/* register our component for this channel number at the RSL Emulation */
			f_rslem_register(0, new_chan_nr);
			var PDU_ML3_MS_NW l3_tx := valueof(ts_RRM_AssignmentComplete('00'O));
			/* send assignment complete over the new channel */
			RSL.send(ts_RSL_DATA_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;
			repeat;
		} else {
			setverdict(fail, "Unexpected L3 received", l3);
			self.stop;
		}
		}
	[st.rr_ass_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_ass_cmpl_seen] RSL.receive(tr_RSL_RF_CHAN_REL(st.old_chan_nr)) {
		RSL.send(ts_RSL_RF_CHAN_REL_ACK(st.old_chan_nr));
		/* unregister for old channel number in RSL emulation */
		/* FIXME: Determine TRX NR by ARFCN, instead of hard-coded TRX0! */
		f_rslem_unregister(0, st.old_chan_nr);
		st.assignment_done := true;
		repeat;
		}
}

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

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

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

/* establish a channel fully, expecting an assignment matching 'exp' */
function f_establish_fully(PDU_BSSAP ass_cmd, template PDU_BSSAP exp_ass_cpl)
runs on MSC_ConnHdlr return PDU_BSSAP {
	var PDU_BSSAP bssap;
	timer T := 10.0;
	var boolean exp_compl := ischosen(exp_ass_cpl.pdu.bssmap.assignmentComplete);
	var boolean exp_fail := ischosen(exp_ass_cpl.pdu.bssmap.assignmentFailure);
	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;
	}
	/* 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;
	}

	f_MscConnHdlr_init(1, "127.0.0.2", "127.0.0.3");

	f_create_chan_and_exp();
	/* we should now have a COMPL_L3 at the MSC */
	BSSAP.receive(tr_BSSMAP_ComplL3);
	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] 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)] 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)) and
	 exp_compl] BSSAP.receive(tr_BSSMAP_AssignmentComplete) {
		setverdict(fail, "Received non-matching ASSIGNMENT COMPLETE");
		}
	[exp_compl] BSSAP.receive(tr_BSSMAP_AssignmentFail) {
		setverdict(fail, "Received unexpected ASSIGNMENT FAIL");
		}
	[not exp_compl] BSSAP.receive(tr_BSSMAP_AssignmentComplete) {
		setverdict(fail, "Received unexpected ASSIGNMENT COMPLETE");
		}
	[not exp_compl] BSSAP.receive(tr_BSSMAP_AssignmentFail) {
		setverdict(fail, "Received non-matching ASSIGNMENT FAIL");
		}
	[] T.timeout {
		setverdict(fail, "Timeout waiting for ASSIGNMENT COMPLETE");
		}
	}
	log("g_media ", g_media);
	if (not isbound(bssap)) {
		self.stop;
	}
	return bssap;
}

type record HandoverState {
	/* Assignment related bits */
	boolean rr_ho_cmpl_seen,
	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 complete over the new channel */
			var PDU_ML3_MS_NW l3_tx := valueof(ts_RRM_HandoverComplete('00'O));
			RSL1.send(ts_RSL_DATA_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;
			repeat;
		} else {
			setverdict(fail, "Unexpected L3 received", l3);
			self.stop;
		}
		}
	[st.rr_ho_cmpl_seen] as_Media();
	[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);
		st.handover_done := true;
		}
}



}
