module BSSGP_Emulation {

/* BSSGP Emulation in TTCN-3
 * (C) 2018-2020 Harald Welte <laforge@gnumonks.org>
 * 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
 *
 * This code implements BSSGP asa hierarchy of components:
 *  - the main BSSGP_CT which runs on top of a NSE (NS Entity).
 *    - demultiplex based on BVCI.  BVCI=0 is handled to a user port
 *  - a per-BVC BSSGP_BVC_CT which runs on top of BSSGP_CT, it handles
 *    one PTP BVCI (i.e. one cell)
 *    - demultiplex based on TLLI
 *  - a per-TLLI BSSGP_Client_CT which runs on top of BSSGP_BVC_CT
 */

import from General_Types all;
import from Osmocom_Types all;
import from NS_Types all;
import from NS_Emulation all;
import from BSSGP_Types all;
import from Osmocom_Gb_Types all;
import from IPL4asp_Types all;

#ifdef BSSGP_EM_L3
import from MobileL3_GMM_SM_Types all;
import from MobileL3_Types all;
#endif

import from LLC_Types all;
import from LLC_Templates all;

import from SNDCP_Types all;


modulepar {
	/* tolerate CellID absence/presence in BVC-RESET in violation to spec */
	boolean mp_tolerate_bvc_reset_cellid := false;
}

/***********************************************************************
 * Communication between Client Components and per-BVC component
 ***********************************************************************/

type record BssgpStatusIndication {
	Nsei		nsei optional,
	BssgpBvci	bvci,
	BvcState	state
};

type record BssgpResetIndication {
	BssgpBvci	bvci
};

template (value) BssgpStatusIndication
ts_BssgpStsInd(template (omit) Nsei nsei, template (value) BssgpBvci bvci,
	       template (value) BvcState state) := {
	nsei := nsei,
	bvci := bvci,
	state := state
}

template (present) BssgpStatusIndication
tr_BssgpStsInd(template Nsei nsei, template (present) BssgpBvci bvci,
		template (present) BvcState state) := {
	nsei := nsei,
	bvci := bvci,
	state := state
}

type enumerated BvcState {
	/* SGSN role: waiting to be reset by the peer */
	BVC_S_WAIT_RESET,
	/* PCU role: waiting for NS_ALIVE_UNBLOCKED */
	BVC_S_WAIT_NS_ALIVE_UNBLOCKED,
	/* BVC-BLOCKED state */
	BVC_S_BLOCKED,
	/* BVC-UNBLOCKED state */
	BVC_S_UNBLOCKED
};

/* port from our (internal) point of view */
type port BSSGP_SP_PT message {
	in	PDU_BSSGP,
		PDU_LLC
#ifdef BSSGP_EM_L3
		,
		PDU_L3_MS_SGSN,
		PDU_L3_SGSN_MS
#endif
		;
	out	PDU_BSSGP,
		PDU_LLC,
		PDU_SN,
		NsStatusIndication,
		BssgpStatusIndication,
		ASP_Event
#ifdef BSSGP_EM_L3
		,
		PDU_L3_MS_SGSN,
		PDU_L3_SGSN_MS
#endif
		;
} with { extension "internal" };

/* port from the user point of view */
type port BSSGP_PT message {
	in	ASP_Event,
		NsStatusIndication,
		BssgpStatusIndication,
		PDU_BSSGP,
		PDU_LLC,
		PDU_SN
#ifdef BSSGP_EM_L3
		,
		PDU_L3_MS_SGSN,
		PDU_L3_SGSN_MS
#endif
		;
	out	PDU_BSSGP,
		PDU_LLC
#ifdef BSSGP_EM_L3
		,
		PDU_L3_SGSN_MS,
		PDU_L3_MS_SGSN
#endif
		;
} with { extension "internal" };

signature BSSGP_register_client(hexstring imsi, OCT4 tlli);
signature BSSGP_unregister_client(hexstring imsi);
signature BSSGP_llgmm_assign(OCT4 tlli_old, OCT4 tlli);

type port BSSGP_PROC_PT procedure {
	inout BSSGP_register_client, BSSGP_unregister_client, BSSGP_llgmm_assign;
} with { extension "internal" };



/***********************************************************************
 * Client Component for a single MS/TLLI
 ***********************************************************************
 * This is what most users will want to derive their test cases from. It
 * provides a set of three different ports (PTP, signaling, procedure)
 * for (currently up to 3) different Cells.  Those ports are all connected
 * to one or multiple different per-BVC compoennts, depending on whether
 * they share the same BSS or not.
 ***********************************************************************/

type component BSSGP_Client_CT {
	/* one port array for each client; allows talking to up to 3 BVC/Cell (handover, ...) */
	port BSSGP_PT BSSGP[3];			/* PTP-BVC */
	port BSSGP_PT BSSGP_SIG[3];		/* Signaling BVC */
	port BSSGP_PROC_PT BSSGP_PROC[3];	/* registration / deregistration */
};

function f_bssgp_client_register(hexstring imsi, OCT4 tlli, BSSGP_PROC_PT PT := BSSGP_PROC[0])
runs on BSSGP_Client_CT {
	PT.call(BSSGP_register_client:{imsi, tlli}) {
		[] PT.getreply(BSSGP_register_client:{imsi, tlli}) {};
	}
}

function f_bssgp_client_unregister(hexstring imsi, BSSGP_PROC_PT PT := BSSGP_PROC[0])
runs on BSSGP_Client_CT {
	PT.call(BSSGP_unregister_client:{imsi}) {
		[] PT.getreply(BSSGP_unregister_client:{imsi}) {};
	}
}

/* TS 44.064 7.2.1.1 LLGMM-ASSIGN */
function f_bssgp_client_llgmm_assign(OCT4 tlli_old, OCT4 tlli_new, BSSGP_PROC_PT PT := BSSGP_PROC[0])
runs on BSSGP_Client_CT {
	PT.call(BSSGP_llgmm_assign:{tlli_old, tlli_new}) {
		[] PT.getreply(BSSGP_llgmm_assign:{tlli_old, tlli_new}) {};
	}
}

/***********************************************************************
 * Main Component
 ***********************************************************************
 * This component exists once, and it runs on to of the NS_Emulation.
 * It handles the BVC-RESET for the signaling BVCI, and dispatches messages
 * to the per-BVC components running above it. Messages are routed by:
 *  - PTP BVCI in NS header (if non-0)
 *  - BVCI IE in messages on BVCI=0 in NS header
 * Messages for which no unique BVC can be identified (like paging without
 * a BVCI IE set) are broadcast to all BVC components.
 * We also broadcast state changes (BssgpStatusIndication) and reset events
 * (BssgpResetIndication) of the signaling BVC to all per-BVC components.
 ***********************************************************************/

function BssgpStart(BssgpConfig cfg, charstring id) runs on BSSGP_CT {
	g_cfg := cfg;

	/* create the per-BVC components based on the configuration */
	for (var integer i := 0; i < lengthof(g_cfg.bvc); i := i+1) {
		var BssgpBvcConfig bvc_cfg := g_cfg.bvc[i];
		var charstring bvc_id := id & "-BVCI" & int2str(bvc_cfg.bvci);
		/* create, connect and start the BVC component */
		var BSSGP_BVC_CT bvc_ct := BSSGP_BVC_CT.create(bvc_id);
		connect(bvc_ct:BVC, self:BVC);
		bvc_ct.start(f_bssgp_bvc_main(bvc_cfg, g_cfg.sgsn_role, g_cfg.nsei, bvc_id));
		/* populate the BVC state table */
		BvcTable[i] := {
			bvci := bvc_cfg.bvci,
			cell_id := bvc_cfg.cell_id,
			comp_ref := bvc_ct
		};
	}

	if (g_cfg.sgsn_role) {
		/* The SGSN side waits for an inbound BVC-RESET on the signaling BVC */
		f_sign_change_state(BVC_S_WAIT_RESET);
	} else {
		/* The BSS/PCU side waits for an inbound NsStatusIndication to Tx BVC-RESET */
		f_sign_change_state(BVC_S_WAIT_NS_ALIVE_UNBLOCKED);
	}

	/* main loop */
	f_bssgp_ScanEvents();
}

/* master component, exists once per BSSGP instance (NSE) */
type component BSSGP_CT {
	/* UDP ports towards the bottom (IUT) */
	port NS_PT BSCP;

	/* control by the user */
	port BSSGP_CT_PROC_PT PROC;

	/* global port for procedures without any relation to a BVC
	 * (currently only) SUSPEND/RESUME */
	port BSSGP_SP_PT GLOBAL;

	/* port to a management instance */
	port BSSGP_BVC_MGMT_SP_PT MGMT;

	var BssgpConfig g_cfg;

	/* Signaling BVC (BVCI=0) */
	var BvcState g_sign_bvc_state := BVC_S_WAIT_RESET;
	timer g_T2 := 60.0;

	/* port to per-BVC components */
	port BSSGP_BVC_SP_PT BVC;
	/* per-BVC state table */
	var BvcEntity BvcTable[16];
};

/* one element in the per-BVC state table */
type record BvcEntity {
	/* PTP BVCI of this BVC/Cell */
	BssgpBvci bvci,
	/* Cell Identity of this cell */
	BssgpCellId cell_id,
	/* reference to the per-BVC/cell component */
	BSSGP_BVC_CT comp_ref
};

/* find the per-BVC component for a given BVCI */
private function f_comp_for_bvci(BssgpBvci bvci) runs on BSSGP_CT return BSSGP_BVC_CT {
	var integer i;

	for (i := 0; i < lengthof(BvcTable); i := i+1) {
		if (BvcTable[i].bvci == bvci) {
			return BvcTable[i].comp_ref;
		}
	}
	return null;
}

/* We are in BVC_S_WAIT_RSET state (only happens in SGSN role) */
altstep as_sig_wait_reset() runs on BSSGP_CT {
	var NsUnitdataIndication udi;

	/* Respond to RESET for signalling BVCI 0 */
	[] BSCP.receive(f_BnsUdInd(tr_BVC_RESET(?, 0, omit), 0)) -> value udi {
		log("Rx BVC-RESET for Signaling BVCI=0");
		f_sign_change_state(BVC_S_UNBLOCKED);
		if (MGMT.checkstate("Connected")) {
			MGMT.send(BssgpResetIndication:{0});
		}
		BSCP.send(f_BnsUdReq(ts_BVC_RESET_ACK(0, omit), 0, 0));
	}

	/* work-around for old, buggy libosmogb before Change-Id Ie87820537d6d616da4fd4bbf73eab06e28fda5e1 */
	[mp_tolerate_bvc_reset_cellid] BSCP.receive(f_BnsUdInd(tr_BVC_RESET(?, 0, g_cfg.bvc[0].cell_id), 0)) -> value udi {
		log("Rx BVC-RESET for Signaling BVCI=0");
		f_sign_change_state(BVC_S_UNBLOCKED);
		if (MGMT.checkstate("Connected")) {
			MGMT.send(BssgpResetIndication:{0});
		}
		BSCP.send(f_BnsUdReq(ts_BVC_RESET_ACK(0, omit), 0, 0));
	}
}

private template PDU_BSSGP tr_GLOBAL := (
	{pDU_BSSGP_SUSPEND:=?}, {pDU_BSSGP_SUSPEND_ACK:=?}, {pDU_BSSGP_SUSPEND_NACK:=?},
	{pDU_BSSGP_RESUME:=?}, {pDU_BSSGP_RESUME_ACK:=?}, {pDU_BSSGP_RESUME_NACK:=?},
	{pDU_BSSGP_SGSN_INVOKE_TRACE:=?}, {pDU_BSSGP_OVERLOAD:=?}
);

/* We are in BVC_S_UNBLOCKED state */
altstep as_sig_unblocked() runs on BSSGP_CT {
	var BSSGP_BVC_CT bvc_comp_ref;
	var BSSGP_Client_CT vc_conn;
	var NsUnitdataIndication udi;
	var NsUnitdataRequest udr;
	var PDU_BSSGP bssgp;

	/* Messages PTP BVCI in BVCI field of NS: dispatch by that */
	[] BSCP.receive(f_BnsUdInd(?, (2..65535))) -> value udi {
		bvc_comp_ref := f_comp_for_bvci(valueof(udi.bvci));
		if (isbound(bvc_comp_ref) and bvc_comp_ref != null) {
			/* dispatch to BVC component */
			BVC.send(udi) to bvc_comp_ref;
		} else {
			setverdict(fail, "Rx BSSGP for unknown PTP BVCI ", udi.bvci, ": ", udi.bssgp);
			BSCP.send(f_BnsUdReq(ts_BSSGP_STATUS(udi.bvci, BSSGP_CAUSE_BVCI_UNKNOWN, udi.bssgp), udi.bvci, 0));
		}
	}

	/* Messages with BVCI = 0 (Signaling) in BVCI field of NS */
	[] BSCP.receive(f_BnsUdInd(tr_GLOBAL, 0)) -> value udi {
		GLOBAL.send(udi.bssgp);
		}

	/* Route based on PTP BVCI in payload/IE of signaling PDU */
	[] BSCP.receive(f_BnsUdInd(?, 0)) -> value udi {
		var template (omit) BssgpBvci ptp_bvci := f_BSSGP_BVCI_get(udi.bssgp);
		if (istemplatekind(ptp_bvci, "omit")) {
			log("Rx on SIG BVCI without PTP BVCI: broadcasting");
			for (var integer i := 0; i < lengthof(BvcTable); i := i+1) {
				if (isbound(BvcTable[i].comp_ref) and BvcTable[i].comp_ref != null) {
					BVC.send(udi) to BvcTable[i].comp_ref;
				}
			}
		} else {
			bvc_comp_ref := f_comp_for_bvci(valueof(ptp_bvci));
			if (isbound(bvc_comp_ref) and bvc_comp_ref != null) {
				/* dispatch to BVC component */
				BVC.send(udi) to bvc_comp_ref;
			} else {
				setverdict(fail, "Rx SIG BSSGP for unknown PTP BVCI ", ptp_bvci, ": ", udi.bssgp);
				BSCP.send(f_BnsUdReq(ts_BSSGP_STATUS(udi.bvci, BSSGP_CAUSE_BVCI_UNKNOWN, udi.bssgp), 0, 0));
                        }
		}
	}

	/* Handle PS-PAGING on SIGN BVCI with no conditional BVCI IE */
	[] BSCP.receive(f_BnsUdInd(PDU_BSSGP:{pDU_BSSGP_PAGING_PS:=?}, 0)) -> value udi {
		/* FIXME: use LA, RA or BSS Area to dispatch instead of broadcast */
		for (var integer i := 0; i < lengthof(BvcTable); i := i+1) {
			if (isbound(BvcTable[i].comp_ref) and BvcTable[i].comp_ref != null) {
				BVC.send(udi) to BvcTable[i].comp_ref;
			}
		}
	}
	/* Handle CS-PAGING on SIGN BVCI with no conditional BVCI IE  */
	[] BSCP.receive(f_BnsUdInd(PDU_BSSGP:{pDU_BSSGP_PAGING_CS:=?}, 0)) -> value udi {
		/* FIXME: use LA, RA or BSS Area to dispatch instead of broadcast */
		for (var integer i := 0; i < lengthof(BvcTable); i := i+1) {
			if (isbound(BvcTable[i].comp_ref) and BvcTable[i].comp_ref != null) {
				BVC.send(udi) to BvcTable[i].comp_ref;
			}
		}
	}

	/* per-BVC component sends us something; forward to NS without any validation */
	[] BVC.receive(NsUnitdataRequest:?) -> value udr {
		/* patch in the NSEI, as the per-BVC components have no idea about it */
		udr.nsei := g_cfg.nsei;
		BSCP.send(udr);
	}

	[] GLOBAL.receive(tr_GLOBAL) -> value bssgp {
		BSCP.send(f_BnsUdReq(bssgp, 0, 0));
		}
}

/* We are in BVC_S_WAIT_NS_ALIVE_UNBLOCKED (only happens in BSS role) */
altstep as_sig_wait_ns_alive_unblocked() runs on BSSGP_CT {
	var NsStatusIndication nsi;
	[] BSCP.receive(NsStatusIndication:{g_cfg.nsei,?, complement (NSVC_S_ALIVE_UNBLOCKED), NSVC_S_ALIVE_UNBLOCKED, true}) -> value nsi {
		/* if we just became NS-unblocked, send a BCC-RESET */
		if (g_cfg.sgsn_role == false) {
			BSCP.send(f_BnsUdReq(ts_BVC_RESET(BSSGP_CAUSE_OM_INTERVENTION, 0, omit), 0, 0));
			g_T2.start;
			/* The BVC_RESET_ACK is handled in the as_sig_allstate() below */
		}
		/* Idea: We could send BVC-UNBLOCK here like some SGSN do */
	}

}

/* handling of events irrespective of BVC state (before state-specific handling) */
altstep as_sig_allstate_pre() runs on BSSGP_CT {
	var NsUnitdataIndication udi;

	/* Respond to RESET for signalling BVCI 0 */
	[] BSCP.receive(f_BnsUdInd(tr_BVC_RESET(?, 0, omit), 0)) -> value udi {
		log("Rx BVC-RESET for Signaling BVCI=0");
		if (MGMT.checkstate("Connected")) {
			MGMT.send(BssgpResetIndication:{0});
		}
		BSCP.send(f_BnsUdReq(ts_BVC_RESET_ACK(0, omit), 0, 0));
		for (var integer i := 0; i < sizeof(BvcTable); i := i+1) {
			if (isbound(BvcTable[i].comp_ref) and BvcTable[i].comp_ref != null) {
				BVC.send(BssgpResetIndication:{0}) to BvcTable[i].comp_ref;
			}
		}
	}

	/* any BLOCK or UNBLOCK for the SIGNALING BVCI are illegal */
	[] BSCP.receive(f_BnsUdInd(t_BVC_BLOCK(0, ?), 0)) -> value udi {
		setverdict(fail, "Rx BVC-BLOCK illegal for BVCI=0: ", udi);
	}
	[] BSCP.receive(f_BnsUdInd(t_BVC_UNBLOCK(0), 0)) -> value udi {
		setverdict(fail, "Rx BVC-UNBLOCK illegal for BVCI=0: ", udi);
	}
	[] BSCP.receive(f_BnsUdInd(t_BVC_BLOCK_ACK(0), 0)) -> value udi {
		setverdict(fail, "Rx BVC-BLOCK-ACK illegal for BVCI=0: ", udi);
	}
	[] BSCP.receive(f_BnsUdInd(t_BVC_UNBLOCK_ACK(0), 0)) -> value udi {
		setverdict(fail, "Rx BVC-UNBLOCK-ACK illegal for BVCI=0: ", udi);
	}

	/* BVC-RESET-ACK for BVCI=0 while T2 is running: Answer to a BVC-RESET we sent earlier */
	[g_T2.running] BSCP.receive(f_BnsUdInd(tr_BVC_RESET_ACK(0, omit), 0)) -> value udi {
		log("BVCI(0) Rx BVC-RESET-ACK");
		g_T2.stop;
		f_sign_change_state(BVC_S_UNBLOCKED);
		for (var integer i := 0; i < sizeof(BvcTable); i := i+1) {
			if (isbound(BvcTable[i].comp_ref) and BvcTable[i].comp_ref != null) {
				BVC.send(BssgpResetIndication:{0}) to BvcTable[i].comp_ref;
			}
		}
	}
	[] g_T2.timeout {
		setverdict(fail, "Timeout waiting for BVC-RESET-ACK on BVCI=0");
		BSCP.send(f_BnsUdReq(ts_BSSGP_STATUS(udi.bvci, BSSGP_CAUSE_BVCI_UNKNOWN, udi.bssgp), 0, 0));
		g_T2.start;
	}
}

/* handling of events irrespective of BVC state (after state-specific handling) */
altstep as_sig_allstate_post() runs on BSSGP_CT {
	var BSSGP_Client_CT vc_conn;
	var NsUnitdataIndication udi;
	var NsStatusIndication nsi;
	var ASP_Event evt;
	var BSSGP_BVC_CT bvc_comp_ref;
	var BssgpBvci bvci;
	var BssgpResetRequest brr;

	/* Respond to RESET for signalling BVCI 0 */
	[] BSCP.receive(f_BnsUdInd(tr_BVC_RESET(?, 0, omit), 0)) -> value udi {
		log("Rx BVC-RESET for Signaling BVCI=0");
		if (MGMT.checkstate("Connected")) {
			MGMT.send(BssgpResetIndication:{0});
		}
		BSCP.send(f_BnsUdReq(ts_BVC_RESET_ACK(0, omit), 0, 0));
		for (var integer i := 0; i < sizeof(BvcTable); i := i+1) {
			if (isbound(BvcTable[i].comp_ref) and BvcTable[i].comp_ref != null) {
				BVC.send(BssgpResetIndication:{0}) to BvcTable[i].comp_ref;
			}
		}
	}

	/* any BLOCK or UNBLOCK for the SIGNALING BVCI are illegal */
	[] BSCP.receive(f_BnsUdInd(t_BVC_BLOCK(0, ?), 0)) -> value udi {
		setverdict(fail, "Rx BVC-BLOCK illegal for BVCI=0: ", udi);
	}
	[] BSCP.receive(f_BnsUdInd(t_BVC_UNBLOCK(0), 0)) -> value udi {
		setverdict(fail, "Rx BVC-UNBLOCK illegal for BVCI=0: ", udi);
	}
	[] BSCP.receive(f_BnsUdInd(t_BVC_BLOCK_ACK(0), 0)) -> value udi {
		setverdict(fail, "Rx BVC-BLOCK-ACK illegal for BVCI=0: ", udi);
	}
	[] BSCP.receive(f_BnsUdInd(t_BVC_UNBLOCK_ACK(0), 0)) -> value udi {
		setverdict(fail, "Rx BVC-UNBLOCK-ACK illegal for BVCI=0: ", udi);
	}

	/* Respond to BLOCK for wrong BVCI */
	[] BSCP.receive(f_BnsUdInd(t_BVC_BLOCK(?, ?), 0)) -> value udi {
		setverdict(fail, "Rx BVC-BLOCK for unknown BVCI");
		BSCP.send(f_BnsUdReq(ts_BSSGP_STATUS(0, BSSGP_CAUSE_BVCI_UNKNOWN, udi.bssgp), 0, 0));
	}

	/* Respond to RESET with wrong BVCI */
	[] BSCP.receive(f_BnsUdInd(tr_BVC_RESET(?, ?, ?), 0)) -> value udi {
		var BssgpBvci ptp_bvci := oct2int(udi.bssgp.pDU_BSSGP_BVC_RESET.bVCI.unstructured_value);
		setverdict(fail, "Rx BVC-RESET for unknown BVCI ", ptp_bvci);
		BSCP.send(f_BnsUdReq(ts_BSSGP_STATUS(ptp_bvci, BSSGP_CAUSE_BVCI_UNKNOWN, udi.bssgp), 0, 0));
	}

	/* Forwarding of ASP_Event to per-BVC components */
	[] BSCP.receive(ASP_Event:?) -> value evt {
		for (var integer i := 0; i < sizeof(BvcTable); i := i+1) {
			if (isbound(BvcTable[i].comp_ref) and BvcTable[i].comp_ref != null) {
				BVC.send(evt) to BvcTable[i].comp_ref;
			}
		}
	}
	/* Keep NS Status Indicaitons to us; no need to inform per-BVC components [for now?] */
	[] BSCP.receive(tr_NsStsInd(g_cfg.nsei)) -> value nsi { }
	/* We should never see any different NSEI: There's one BSSGP_CT per NSE */
	[] BSCP.receive(tr_NsStsInd(?)) -> value nsi {
		setverdict(fail, "Rx NsStatusInd for wrong NSEI ", nsi);
	}

	/* Procedure port request to resolve the per-BVC component for a given ptp BVCI */
	[] PROC.getcall(BSSGP_get_bvci_ct:{?}) -> param(bvci) sender vc_conn {
		for (var integer i := 0; i < sizeof(BvcTable); i := i+1) {
			if (BvcTable[i].bvci == bvci) {
				PROC.reply(BSSGP_get_bvci_ct:{bvci} value BvcTable[i].comp_ref) to vc_conn;
				return;
			}
		}
	}

	/* default case of handling unknown PDUs */
	[] BSCP.receive(f_BnsUdInd(?, ?)) -> value udi {
		setverdict(fail, "Rx Unexpected BSSGP PDU ", udi.bssgp,"  in state ", g_sign_bvc_state);
		BSCP.send(f_BnsUdReq(ts_BSSGP_STATUS(0, BSSGP_CAUSE_PDU_NOT_COMPATIBLE_WITH_PROTOCOL_STATE, udi.bssgp), 0, 0));
	}

	[] MGMT.receive(BssgpResetRequest:?) -> value brr {
		BSCP.send(f_BnsUdReq(ts_BVC_RESET(brr.cause, 0, omit), 0, 0));
		g_T2.start;
		}
}

/* send the highest decoded layer of the message through given port */
private function f_send_bssgp_dec(BssgpDecoded dec, BSSGP_Client_CT vc_conn, BSSGP_SP_PT pt) {
#ifdef BSSGP_EM_L3
	if (ispresent(dec.l3_mt)) {
		pt.send(dec.l3_mt) to vc_conn;
	} else if (ispresent(dec.l3_mo)) {
		pt.send(dec.l3_mo) to vc_conn;
	} else
#endif
	if (ispresent(dec.sndcp)) {
		pt.send(dec.sndcp) to vc_conn;
	} else if (ispresent(dec.llc)) {
		pt.send(dec.llc) to vc_conn;
	} else {
		pt.send(dec.bssgp) to vc_conn;
	}
}


function f_llc_get_n_u_tx(inout LLC_Entity llc) return uint9_t {
	var uint9_t ret := llc.n_u_tx_next;
	llc.n_u_tx_next := llc.n_u_tx_next + 1;
	return ret;
}

#ifdef BSSGP_EM_L3
function f_llc_sapi_by_l3_mo(PDU_L3_MS_SGSN l3_mo) return BIT4 {
	if (ischosen(l3_mo.msgs.gprs_mm)) {
		return c_LLC_SAPI_LLGMM;
	} else if (ischosen(l3_mo.msgs.gprs_sm)) {
		return c_LLC_SAPI_LLGMM;
	} else if (ischosen(l3_mo.msgs.sms)) {
		return c_LLC_SAPI_LLSMS;
	}
	setverdict(fail, "No LLC SAPI for ", l3_mo);
	mtc.stop;
}

private function f_llc_sapi_by_l3_mt(PDU_L3_SGSN_MS l3_mt) return BIT4 {
	if (ischosen(l3_mt.msgs.gprs_mm)) {
		return c_LLC_SAPI_LLGMM;
	} else if (ischosen(l3_mt.msgs.gprs_sm)) {
		return c_LLC_SAPI_LLGMM;
	} else if (ischosen(l3_mt.msgs.sms)) {
		return c_LLC_SAPI_LLSMS;
	}
	setverdict(fail, "No LLC SAPI for ", l3_mt);
	mtc.stop;
}
#endif

/* main loop of BSSGP_CT */
private function f_bssgp_ScanEvents() runs on BSSGP_CT {
	while (true) {
		alt {
		[g_sign_bvc_state == BVC_S_WAIT_RESET] as_sig_wait_reset();
		[] as_sig_allstate_pre();
		[g_sign_bvc_state == BVC_S_WAIT_NS_ALIVE_UNBLOCKED] as_sig_wait_ns_alive_unblocked();
		[g_sign_bvc_state == BVC_S_UNBLOCKED] as_sig_unblocked();
		[g_sign_bvc_state == BVC_S_WAIT_RESET] as_sig_wait_reset();
		[] as_sig_allstate_post();
		}
	} /* while */
}

/* generate a send template. Cannot be a real template as we want to use g_cfg.nsei */
private function f_BnsUdReq(template PDU_BSSGP pdu, BssgpBvci bvci, integer lsp)
runs on BSSGP_CT return NsUnitdataRequest {
	var NsUnitdataRequest udr := {
		bvci := bvci,
		nsei := g_cfg.nsei,
		lsp := lsp,
		/* for some weird reason we get "Dynamic test case error: Text encoder: Encoding an
		 * unbound integer value." when trying to send the reocrd rather than the octetstring */
		//sdu := omit,
		//bssgp := valueof(pdu)
		sdu := enc_PDU_BSSGP(valueof(pdu)),
		bssgp := omit
	}
	return udr;
}

/* generate a receive template. Cannot be a real template as we want to use g_cfg.nsei */
private function f_BnsUdInd(template PDU_BSSGP pdu, template BssgpBvci bvci)
runs on BSSGP_CT return template (present) NsUnitdataIndication {
	var template (present) NsUnitdataIndication udi := {
		bvci := bvci,
		nsei := g_cfg.nsei,
		nsvci := ?,
		sdu := *,
		bssgp := pdu
	}
	return udi;
}

/* change state of signaling BVCI; notify per-BVC components */
private function f_sign_change_state(BvcState new_state) runs on BSSGP_CT {
	if (new_state == g_sign_bvc_state) {
		return;
	}
	log("BVCI(0) State Transition: ", g_sign_bvc_state, " -> ", new_state);
	g_sign_bvc_state := new_state;
	for (var integer i := 0; i < sizeof(BvcTable); i := i+1) {
		if (isbound(BvcTable[i].comp_ref) and BvcTable[i].comp_ref != null) {
			BVC.send(ts_BssgpStsInd(g_cfg.nsei, 0, g_sign_bvc_state)) to BvcTable[i].comp_ref;
		}
	}
}

/* User wants to get per-BVC component reference from BSSGP_CT */
signature BSSGP_get_bvci_ct(BssgpBvci bvci) return BSSGP_BVC_CT;

type port BSSGP_CT_PROC_PT procedure {
	inout BSSGP_get_bvci_ct
} with { extension "internal" };

/* convenience wrapper function for user */
function f_bssgp_get_bvci_ct(BssgpBvci bvci, BSSGP_CT_PROC_PT PT) return BSSGP_BVC_CT {
	var BSSGP_BVC_CT res;
	PT.call(BSSGP_get_bvci_ct:{bvci}) {
		[] PT.getreply(BSSGP_get_bvci_ct:{bvci})-> value res {
			return res;
		}
	}
}

/***********************************************************************
 * per-BVC (Cell) Component
 ***********************************************************************
 * Any number of these components runs on top of the BSSGP_CT, each
 * representing one PTP BVC within this NSE.  Users (test cases) can
 * register with TLLI and/or IMSI via the procedure port.
 ***********************************************************************/

/* per-BVC component. Exists once per cell within a BSSGP_CT */
type component BSSGP_BVC_CT {
	/* port towards the underlying BSSGP_CT */
	port BSSGP_BVC_PT BVC;

	/* port to a management instance */
	port BSSGP_BVC_MGMT_SP_PT MGMT;

	/* BSSGP-User SAP towards the user (Client) */
	port BSSGP_SP_PT BSSGP_SP;
	port BSSGP_SP_PT BSSGP_SP_SIG;
	port BSSGP_PROC_PT BSSGP_PROC;

	var BssgpBvcConfig g_cfg;
	var boolean g_sgsn_role;
	var Nsei g_nsei;

	/* default Link Selector Parameter for this BVC (for traffic unrelated to a TLLI) */
	var integer g_bvc_lsp;

	var BvcState g_ptp_bvc_state := BVC_S_BLOCKED;
	timer g_T1 := 15.0;
	timer g_T2 := 60.0;
	var boolean g_t1_waits_for_block_ack := false;
	/* for re-transmissions */
	var BssgpCause g_last_block_cause;
	var BssgpCause g_last_reset_cause;

	var ClientEntity ClientTable[16];
};

/* port between global BSSGP_CT and per-BVC BSSGP_BVC_CT */
type port BSSGP_BVC_SP_PT message {
	in	NsUnitdataRequest;
	out	ASP_Event,
		BssgpStatusIndication,
		BssgpResetIndication,
		NsUnitdataIndication;
} with { extension "internal" };
type port BSSGP_BVC_PT message {
	in	ASP_Event,
		BssgpStatusIndication,
		BssgpResetIndication,
		NsUnitdataIndication;
	out	NsUnitdataRequest;
} with { extension "internal" };

/* port between BSSGP_BVC_CT and a management instance */
type port BSSGP_BVC_MGMT_SP_PT message {
	in	BssgpResetRequest,
		BssgpBlockRequest,
		BssgpUnblockRequest;
	out	BssgpStatusIndication,
		BssgpResetIndication;
} with { extension "internal" };
type port BSSGP_BVC_MGMT_PT message {
	in	BssgpStatusIndication,
		BssgpResetIndication;
	out	BssgpResetRequest,
		BssgpBlockRequest,
		BssgpUnblockRequest;
} with { extension "internal" };

type record BssgpResetRequest {
	BssgpCause cause
};
type record BssgpBlockRequest {
	BssgpCause cause
};
type record BssgpUnblockRequest {
};

/* one element in the per-TLLI state table */
type record ClientEntity {
	OCT4 tlli,
	OCT4 tlli_old optional,
	hexstring imsi,
	BSSGP_Client_CT comp_ref,
	/* LLC entities, one for each SAPI */
	LLC_Entity llc[16]
};
type record LLC_Entity {
	boolean sgsn_role,
	/* N(U) on transmit side for next PDU */
	uint9_t n_u_tx_next,
	/* N(U) on receive side, last PDU */
	uint9_t n_u_rx_last optional
};
type record length(16) of LLC_Entity LLC_Entities;

function f_llc_create(boolean sgsn_role := false) return LLC_Entities {
	var LLC_Entities llc;
	for (var integer i := 0; i < 16; i := i+1) {
		llc[i] := valueof(t_LLC_init(sgsn_role));
	}
	return llc;
}

private template LLC_Entity t_LLC_init(boolean sgsn_role := false) := {
	sgsn_role := sgsn_role,
	n_u_tx_next := 0,
	n_u_rx_last := -
}

/* configuration of BSSGP_CT */
type record BssgpConfig {
	Nsvci nsei,
	boolean sgsn_role,
	BssgpBvcConfigs bvc
};
/* Configuration of one BVC (Cell) BSSGP_BVC_CT */
type record BssgpBvcConfig {
	BssgpBvci bvci,
	BssgpCellId cell_id,
	BssgpDecodeDepth depth,
	BssgpCreateCallback create_cb
};
type record of BssgpBvcConfig BssgpBvcConfigs;
type enumerated BssgpDecodeDepth {
	BSSGP_DECODE_DEPTH_BSSGP,
	BSSGP_DECODE_DEPTH_LLC,
	BSSGP_DECODE_DEPTH_SNDCP
#ifdef BSSGP_EM_L3
	,
	BSSGP_DECODE_DEPTH_L3
#endif
};
/* call-back function type: Called for inbound BSSGP for unknown TLLIs; could create BSSGP_ClienT_CT */
type function BssgpCreateCallback(BssgpBvci bvci, BssgpCellId cell_id, OCT4 tlli, BssgpDecoded dec) runs on BSSGP_BVC_CT;

/* Default Create Callback function: Fail and terminate */
function DefaultCreateCallback(BssgpBvci bvci, BssgpCellId cell_id, OCT4 tlli, BssgpDecoded dec) runs on BSSGP_BVC_CT {
	setverdict(fail, "Couldn't find Component for TLLI ", tlli);
	mtc.stop;
}

/*
private function f_tbl_init() runs on BSSGP_BVC_CT {
	var integer i;
	for (i := 0; i < sizeof(ImsiTable); i := i+1) {
		ImsiTable[i] := -;
	}

	for (i := 0; i < sizeof(TlliTable); i := i+1) {
		TlliTable[i] := -;
	}
}
*/

private function f_tbl_client_add(hexstring imsi, OCT4 tlli, BSSGP_Client_CT vc_conn)
runs on BSSGP_BVC_CT {
	var integer i;
	for (i := 0; i < sizeof(ClientTable); i := i+1) {
		if (not isvalue(ClientTable[i].comp_ref)) {
			log("Adding Client=", vc_conn, ", IMSI=", imsi, ", TLLI=", tlli, ", index=", i);
			ClientTable[i] := {
				tlli := tlli,
				tlli_old := omit,
				imsi := imsi,
				comp_ref := vc_conn,
				llc := -
			};
			for (var integer j := 0; j < sizeof(ClientTable[i].llc); j := j+1) {
				ClientTable[i].llc[j] := valueof(t_LLC_init(g_sgsn_role));
			}
			return;
		}
	}
	testcase.stop("Client Table full");
}

private function f_tbl_client_del(hexstring imsi, BSSGP_Client_CT vc_conn) runs on BSSGP_BVC_CT {
	var integer i;
	for (i := 0; i < sizeof(ClientTable); i := i+1) {
		if (isvalue(ClientTable[i].imsi) and ClientTable[i].imsi == imsi) {
			if (ClientTable[i].comp_ref != vc_conn) {
				setverdict(fail, "Cannot unregister index=", i, " IMSI ", imsi, " registred to ",
					   ClientTable[i].comp_ref, " from ", vc_conn);
				mtc.stop;
			}
			log("Removing Client IMSI=", imsi, ", index=", i);
			ClientTable[i] := {
				tlli := -,
				tlli_old := omit,
				imsi := ''H,
				comp_ref := null,
				llc := - };
			return;
		}
	}
	log("Warning: Could not find client for IMSI ", imsi);
	return;
}

/* TS 44.064 7.2.1.1 LLGMM-ASSIGN */
private function f_tbl_client_llgmm_assign(OCT4 tlli_old, OCT4 tlli_new, BSSGP_Client_CT vc_conn)
runs on BSSGP_BVC_CT {
	var integer i := f_tbl_idx_by_comp(vc_conn);

	if (tlli_old == 'FFFFFFFF'O and tlli_new != 'FFFFFFFF'O) {
		/* TLLI assignment */
		ClientTable[i].tlli := tlli_new;
		ClientTable[i].tlli_old := omit;
	} else if (tlli_old != 'FFFFFFFF'O and tlli_new != 'FFFFFFFF'O) {
		/* TLLI change: both active */
		ClientTable[i].tlli := tlli_new;
		ClientTable[i].tlli_old := tlli_old;
	} else if (tlli_old != 'FFFFFFFF'O and tlli_new == 'FFFFFFFF'O) {
		/* TLLI unassignment: old shall be unassigned; new stays */
		ClientTable[i].tlli_old := omit;
	}
}

private function f_tbl_comp_by_imsi(hexstring imsi) runs on BSSGP_BVC_CT return BSSGP_Client_CT {
	var integer i;
	for (i := 0; i < sizeof(ClientTable); i := i+1) {
		if (isvalue(ClientTable[i].imsi) and isvalue(ClientTable[i].comp_ref)
		    and ClientTable[i].imsi == imsi) {
			return ClientTable[i].comp_ref;
		}
	}
	setverdict(fail, "Couldn't find Component for IMSI ", imsi);
	mtc.stop;
}

private function f_tbl_comp_by_tlli(OCT4 tlli) runs on BSSGP_BVC_CT return BSSGP_Client_CT {
	var integer i;
	for (i := 0; i < sizeof(ClientTable); i := i+1) {
		if (isvalue(ClientTable[i].comp_ref) and
		    (isvalue(ClientTable[i].tlli) and (ClientTable[i].tlli == tlli or
		     isvalue(ClientTable[i].tlli_old) and ClientTable[i].tlli_old == tlli) )) {
			return ClientTable[i].comp_ref;
		}
	}
	return null;
}

private function f_tbl_idx_by_comp(BSSGP_Client_CT comp_ref) runs on BSSGP_BVC_CT return integer {
	var integer i;
	for (i := 0; i < sizeof(ClientTable); i := i+1) {
		if (isvalue(ClientTable[i].comp_ref) and ClientTable[i].comp_ref == comp_ref) {
			return i;
		}
	}
	setverdict(fail, "Couldn't find Client for Component ", comp_ref);
	mtc.stop;
}

private function f_tbl_tlli_by_comp(BSSGP_Client_CT comp_ref) runs on BSSGP_BVC_CT return OCT4 {
	var integer i;
	for (i := 0; i < sizeof(ClientTable); i := i+1) {
		if (isvalue(ClientTable[i].tlli) and isvalue(ClientTable[i].comp_ref)
		    and ClientTable[i].comp_ref == comp_ref) {
			return ClientTable[i].tlli;
		}
	}
	setverdict(fail, "Couldn't find TLLI for Component ", comp_ref);
	mtc.stop;
}

/* PDU_BSSGP enhanced with LLC and possibly L3 decoded payloads */
type record BssgpDecoded {
	PDU_BSSGP bssgp,
	PDU_LLC llc optional,
#ifdef BSSGP_EM_L3
	PDU_L3_MS_SGSN l3_mo optional,
	PDU_L3_SGSN_MS l3_mt optional,
#endif
	PDU_SN sndcp optional
}

/* Decode a PDU_BSSGP into a BssgpDecoded (i.e. with LLC/L3 decoded, as applicable) */
private function f_dec_bssgp(PDU_BSSGP bssgp) runs on BSSGP_BVC_CT return BssgpDecoded {
	var BssgpDecoded dec := {
		bssgp := bssgp,
		llc := omit,
#ifdef BSSGP_EM_L3
		l3_mo := omit,
		l3_mt := omit,
#endif
		sndcp := omit
	};

	/* Decode LLC, if it is a PDU that contains LLC */
	if (g_cfg.depth >= BSSGP_DECODE_DEPTH_LLC) {
		if (ischosen(bssgp.pDU_BSSGP_DL_UNITDATA)) {
			dec.llc := dec_PDU_LLC(bssgp.pDU_BSSGP_DL_UNITDATA.lLC_PDU.lLC_PDU);
		} else if (ischosen(bssgp.pDU_BSSGP_UL_UNITDATA)) {
			dec.llc := dec_PDU_LLC(bssgp.pDU_BSSGP_UL_UNITDATA.lLC_PDU.lLC_PDU);
		}
	}

	/* Decode SNDCP, if it is a LLC PDU containing user plane data */
	if (g_cfg.depth >= BSSGP_DECODE_DEPTH_SNDCP) {
		if (isvalue(dec.llc) and match(dec.llc, tr_LLC_UI_USER)) {
			dec.sndcp := dec_PDU_SN(dec.llc.pDU_LLC_UI.information_field_UI);
		}
	}

#ifdef BSSGP_EM_L3
	/* Decode L3, if it is a LLC PDU containing L3 */
	if (g_cfg.depth >= BSSGP_DECODE_DEPTH_L3) {
		if (isvalue(dec.llc) and match(dec.llc, tr_LLC_UI_L3)) {
			if (g_sgsn_role) {
				dec.l3_mo := dec_PDU_L3_MS_SGSN(dec.llc.pDU_LLC_UI.information_field_UI);
			} else {
				dec.l3_mt := dec_PDU_L3_SGSN_MS(dec.llc.pDU_LLC_UI.information_field_UI);
			}
		}
	}
#endif

	return dec;
}

private function f_ptp_sendUnblock() runs on BSSGP_BVC_CT {
	BVC.send(ts_ptp_BnsUdReq(t_BVC_UNBLOCK(g_cfg.bvci), 0, g_bvc_lsp));
	g_t1_waits_for_block_ack := false;
	g_T1.start;
}

private function f_ptp_sendBlock(BssgpCause cause) runs on BSSGP_BVC_CT {
	BVC.send(ts_ptp_BnsUdReq(t_BVC_BLOCK(g_cfg.bvci, cause), 0, g_bvc_lsp));
	g_t1_waits_for_block_ack := true;
	g_T1.start;
	g_last_block_cause := cause;
}

private function f_ptp_sendStatus(BssgpCause cause, PDU_BSSGP pdu) runs on BSSGP_BVC_CT {
	/* FIXME: Make sure correct Signaling or PTP BVCI is used! */
	BVC.send(ts_ptp_BnsUdReq(ts_BSSGP_STATUS(g_cfg.bvci, cause, pdu), g_cfg.bvci, g_bvc_lsp));
}

private function f_ptp_sendReset(BssgpCause cause := BSSGP_CAUSE_OM_INTERVENTION) runs on BSSGP_BVC_CT {
	var PDU_BSSGP pdu;

	/* The Cell Identifier IE is mandatory in the BVC-RESET PDU sent from BSS to
	 * SGSN in order to reset a BVC corresponding to a PTP functional entity. The
	 * Cell Identifier IE shall not be used in any other BVC-RESET PDU. */
	if (g_sgsn_role) {
		pdu := valueof(ts_BVC_RESET(cause, g_cfg.bvci, omit));
	} else {
		pdu := valueof(ts_BVC_RESET(cause, g_cfg.bvci, g_cfg.cell_id));
	}

	/* BVC-RESET is always sent via the SIGNALLING BVCI, see Table 5.4.1 */
	BVC.send(ts_ptp_BnsUdReq(pdu, 0, g_bvc_lsp));
	g_T2.start;
	//f_change_state(BVC_S_WAIT_RESET);
	g_last_reset_cause := cause;
}

/* PTP-BVC is in BVC_S_BLOCKED state */
private altstep as_ptp_blocked() runs on BSSGP_BVC_CT {
	var NsUnitdataIndication udi;

	[g_T1.running and not g_t1_waits_for_block_ack] BVC.receive(tr_ptp_BnsUdInd(t_BVC_UNBLOCK_ACK(g_cfg.bvci), 0)) {
		g_T1.stop;
		f_ptp_change_state(BVC_S_UNBLOCKED);
	}

	/* Inbound  BVC-UNBLOCK from peer */
	[g_sgsn_role] BVC.receive(tr_ptp_BnsUdInd(t_BVC_UNBLOCK(g_cfg.bvci), 0)) {
		BVC.send(ts_ptp_BnsUdReq(t_BVC_UNBLOCK_ACK(g_cfg.bvci), 0, g_bvc_lsp));
		f_ptp_change_state(BVC_S_UNBLOCKED);
	}

	/* RESET-ACK before T2 timeout: reset successful. In SGSN role, CellID must be present */
	[g_T2.running and g_sgsn_role] BVC.receive(tr_ptp_BnsUdInd(tr_BVC_RESET_ACK(g_cfg.bvci, g_cfg.cell_id), 0)) -> value udi {
		g_T2.stop;
		f_ptp_change_state(BVC_S_UNBLOCKED);
	}
	/* RESET-ACK before T2 timeout: reset successful. In BSS role, CellID must be absent */
	[g_T2.running and not g_sgsn_role] BVC.receive(tr_ptp_BnsUdInd(tr_BVC_RESET_ACK(g_cfg.bvci, omit), 0)) -> value udi {
		g_T2.stop;
		f_ptp_change_state(BVC_S_UNBLOCKED);
	}

	[] as_ptp_handle_inbound_reset();

	[] g_T2.timeout {
		/* BVC-RESET-ACK PDU was not received within T2: retransmit */
		f_ptp_sendReset(g_last_reset_cause);
	}

	[] MGMT.receive(BssgpUnblockRequest:?) {
		f_ptp_sendUnblock();
		}
}

/* PTP-BVC is in UNBLOCKED state */
private altstep as_ptp_unblocked() runs on BSSGP_BVC_CT {
	var NsUnitdataIndication udi;
	var NsStatusIndication nsi;
	var BssgpBlockRequest bbr;
	var BSSGP_Client_CT vc_conn;
	var ASP_Event evt;
	var PDU_BSSGP bs_pdu;
	var PDU_LLC llc;
#ifdef BSSGP_EM_L3
	var PDU_L3_MS_SGSN l3_mo;
	var PDU_L3_SGSN_MS l3_mt;
#endif

	/* bogus unblock, just respond with ACK */
	[] BVC.receive(tr_ptp_BnsUdInd(t_BVC_UNBLOCK(g_cfg.bvci), 0)) -> value udi {
		BVC.send(ts_ptp_BnsUdReq(t_BVC_UNBLOCK_ACK(g_cfg.bvci), 0, g_bvc_lsp));
	}
	/* Respond to BLOCK with BLOCK-ACK + change state */
	[] BVC.receive(tr_ptp_BnsUdInd(t_BVC_BLOCK(g_cfg.bvci, ?), 0)) -> value udi {
		BVC.send(ts_ptp_BnsUdReq(t_BVC_BLOCK_ACK(g_cfg.bvci), 0, g_bvc_lsp));
		g_T1.stop;
		f_ptp_change_state(BVC_S_BLOCKED);
	}
	/* BLOCK-ACK before T1 timeout: mark as blocked */
	[g_T1.running and g_t1_waits_for_block_ack] BVC.receive(tr_ptp_BnsUdInd(t_BVC_BLOCK_ACK(g_cfg.bvci), 0)) -> value udi {
		g_T1.stop;
		f_ptp_change_state(BVC_S_BLOCKED);
	}
	/* Re-transmit BLOCK / UNBLOCK on T1 timeout */
	[not g_t1_waits_for_block_ack] g_T1.timeout {
		f_ptp_sendUnblock();
	}
	[g_t1_waits_for_block_ack] g_T1.timeout {
		f_ptp_sendBlock(g_last_block_cause);
	}

	[] as_ptp_handle_inbound_reset();

	/* simply acknowledge all per-BVC Flow Control Messages */
	[g_sgsn_role] BVC.receive(tr_ptp_BnsUdInd(tr_BVC_FC_BVC, g_cfg.bvci)) -> value udi {
		var OCT1 tag := udi.bssgp.pDU_BSSGP_FLOW_CONTROL_BVC.tag.unstructured_Value;
		BVC.send(ts_ptp_BnsUdReq(t_BVC_FC_BVC_ACK(tag), g_cfg.bvci, g_bvc_lsp));
	}
/*
	[g_sgsn_role] BVC.receive(tr_ptp_BnsUdInd(t_BVC_FC_MS, g_cfg.bvci)) {
		BVC.send(ts_ptp_BnsUdReq(t_BVC_FC_MS_ACK, g_cfg.bvci));
	}
*/
	/* Any other PTP BSSGP message: If it has TLLI, route to component; otherwise broadcast */
	[] BVC.receive(tr_ptp_BnsUdInd(?, g_cfg.bvci)) -> value udi {
		var BssgpDecoded dec := f_dec_bssgp(udi.bssgp);
		var template OCT4 tlli := f_bssgp_get_tlli(udi.bssgp);
		if (isvalue(tlli)) {
			vc_conn := f_tbl_comp_by_tlli(valueof(tlli));
			if (vc_conn == null) {
				g_cfg.create_cb.apply(g_cfg.bvci, g_cfg.cell_id, valueof(tlli), dec);
			} else {
				f_send_bssgp_dec(dec, vc_conn, BSSGP_SP);
			}
		} else {
			log("No TLLI: Broadcasting ", dec);
			/* broadcast this message to all components */
			// TITAN DOESN'T DO THIS, *SIGH*: "BSSGP_SP.send(dec) to all component;"
			for (var integer i := 0; i < sizeof(ClientTable); i := i+1) {
				if (isbound(ClientTable[i].comp_ref) and ClientTable[i].comp_ref != null) {
					f_send_bssgp_dec(dec, ClientTable[i].comp_ref, BSSGP_SP);
				}
			}
		}
	}

	/* Any other SIG BSSGP message: If it has TLLI, route to component; otherwise broadcast */
	[] BVC.receive(tr_ptp_BnsUdInd(?, 0)) -> value udi {
		var BssgpDecoded dec := f_dec_bssgp(udi.bssgp);
		var template OCT4 tlli := f_bssgp_get_tlli(udi.bssgp);
		if (isvalue(tlli)) {
			vc_conn := f_tbl_comp_by_tlli(valueof(tlli));
			if (vc_conn == null) {
				g_cfg.create_cb.apply(g_cfg.bvci, g_cfg.cell_id, valueof(tlli), dec);
			} else {
				f_send_bssgp_dec(dec, vc_conn, BSSGP_SP_SIG);
			}
		} else {
			log("No TLLI: Broadcasting ", dec);
			/* broadcast this message to all components */
			// TITAN DOESN'T DO THIS, *SIGH*: "BSSGP_SP.send(dec) to all component;"
			for (var integer i := 0; i < sizeof(ClientTable); i := i+1) {
				if (isbound(ClientTable[i].comp_ref) and ClientTable[i].comp_ref != null) {
					f_send_bssgp_dec(dec, ClientTable[i].comp_ref, BSSGP_SP_SIG);
				}
			}
		}
	}

	/* ConnHdlr sends BSSGP on BVCI=0 port: forward it to BSSGP_CT */
	[] BSSGP_SP_SIG.receive(PDU_BSSGP:?)-> value bs_pdu sender vc_conn {
		BVC.send(ts_ptp_BnsUdReq(bs_pdu, 0, g_bvc_lsp));
	}

	/* ConnHdlr sends BSSGP on BVCI=PTP port: forward it to BSSGP_CT */
	[] BSSGP_SP.receive(PDU_BSSGP:?)-> value bs_pdu sender vc_conn {
		BVC.send(ts_ptp_BnsUdReq(bs_pdu, g_cfg.bvci, g_bvc_lsp));
	}

#ifdef BSSGP_EM_L3
	/* ConnHdlr sends L3: Encode and send as UL_UD / DL_UD */
	[g_sgsn_role] BSSGP_SP.receive(PDU_L3_SGSN_MS:?) -> value l3_mt sender vc_conn {
		var integer idx := f_tbl_idx_by_comp(vc_conn);
		var OCT4 tlli := ClientTable[idx].tlli;
		var octetstring l3_enc := enc_PDU_L3_SGSN_MS(l3_mt);
		var BIT4 sapi := f_llc_sapi_by_l3_mt(l3_mt);
		var integer n_u := f_llc_get_n_u_tx(ClientTable[idx].llc[bit2int(sapi)]);
		var octetstring llc_enc := enc_PDU_LLC(valueof(ts_LLC_UI(l3_enc, sapi, '1'B, n_u)));
		BVC.send(ts_ptp_BnsUdReq(ts_BSSGP_DL_UD(tlli, llc_enc), g_cfg.bvci, oct2int(tlli)));
	}
	[not g_sgsn_role] BSSGP_SP.receive(PDU_L3_MS_SGSN:?) -> value l3_mo sender vc_conn {
		var integer idx := f_tbl_idx_by_comp(vc_conn);
		var OCT4 tlli := ClientTable[idx].tlli;
		var octetstring l3_enc := enc_PDU_L3_MS_SGSN(l3_mo);
		var BIT4 sapi := f_llc_sapi_by_l3_mo(l3_mo);
		var integer n_u := f_llc_get_n_u_tx(ClientTable[idx].llc[bit2int(sapi)]);
		var octetstring llc_enc := enc_PDU_LLC(valueof(ts_LLC_UI(l3_enc, sapi, '1'B, n_u)));
		BVC.send(ts_ptp_BnsUdReq(ts_BSSGP_UL_UD(tlli, g_cfg.cell_id, llc_enc), g_cfg.bvci, oct2int(tlli)));
	}
#endif

	/* ConnHdlr sends raw LLC: Encode and send as UL_UD / DL_UD */
	[not g_sgsn_role] BSSGP_SP.receive(PDU_LLC:?) -> value llc sender vc_conn {
		var integer idx := f_tbl_idx_by_comp(vc_conn);
		var OCT4 tlli := ClientTable[idx].tlli;
		var octetstring llc_enc := enc_PDU_LLC(llc);
		BVC.send(ts_ptp_BnsUdReq(ts_BSSGP_UL_UD(tlli, g_cfg.cell_id, llc_enc), g_cfg.bvci, oct2int(tlli)));
	}
	[g_sgsn_role] BSSGP_SP.receive(PDU_LLC:?) -> value llc sender vc_conn {
		var integer idx := f_tbl_idx_by_comp(vc_conn);
		var OCT4 tlli := ClientTable[idx].tlli;
		var octetstring llc_enc := enc_PDU_LLC(llc);
		BVC.send(ts_ptp_BnsUdReq(ts_BSSGP_DL_UD(tlli, llc_enc), g_cfg.bvci, oct2int(tlli)));
	}

	[] MGMT.receive(BssgpBlockRequest:?) -> value bbr {
		f_ptp_sendBlock(bbr.cause);
		}
}

private altstep as_ptp_handle_inbound_reset() runs on BSSGP_BVC_CT {
	var NsUnitdataIndication udi;
	/* we are a SGSN: BSS/PCU-originated RESET must have a cell ID */
	[g_sgsn_role] BVC.receive(tr_ptp_BnsUdInd(tr_BVC_RESET(?, g_cfg.bvci, g_cfg.cell_id), 0)) -> value udi {
		log("Rx BVC-RESET from BVCI=", g_cfg.bvci);
		if (MGMT.checkstate("Connected")) {
			MGMT.send(BssgpResetIndication:{g_cfg.bvci});
		}
		/* Respond to RESET with correct BVCI but without CellID */
		BVC.send(ts_ptp_BnsUdReq(ts_BVC_RESET_ACK(g_cfg.bvci, omit), 0, g_bvc_lsp));
		/* FIXME: reset all state? What about clients? */
		f_ptp_change_state(BVC_S_UNBLOCKED);
	}
	/* we are a BSS/PCU: SGSN-originated RESET must not have a cell ID */
	[not g_sgsn_role] BVC.receive(tr_ptp_BnsUdInd(tr_BVC_RESET(?, g_cfg.bvci, omit), 0)) -> value udi {
		log("Rx BVC-RESET from BVCI=", g_cfg.bvci);
		if (MGMT.checkstate("Connected")) {
			MGMT.send(BssgpResetIndication:{g_cfg.bvci});
		}
		/* Respond to RESET with correct BVCI with CellID */
		BVC.send(ts_ptp_BnsUdReq(ts_BVC_RESET_ACK(g_cfg.bvci, g_cfg.cell_id), 0, g_bvc_lsp));
		/* FIXME: reset all state? What about clients? */
		f_ptp_change_state(BVC_S_UNBLOCKED);
	}
}

/* Events permitted in all states */
private altstep as_ptp_allstate() runs on BSSGP_BVC_CT {
	var NsUnitdataIndication udi;
	var BssgpResetRequest brr;
	var BSSGP_Client_CT vc_conn;
	var OCT4 tlli, tlli_old;
	var hexstring imsi;

	/* Signaling BVC was reset */
	[] BVC.receive(BssgpResetIndication:{0}) {
		if (MGMT.checkstate("Connected")) {
			MGMT.send(BssgpResetIndication:{0});
		}
		if (not g_sgsn_role) {
			f_ptp_change_state(BVC_S_BLOCKED);
			/* when the BSS side signaling PTP is RESET, all PTP BVC must start the
			 * reset procedure */
			f_ptp_sendReset();
		} else {
			f_ptp_change_state(BVC_S_UNBLOCKED);
		}
	}

	/* Ignore those for now */
	[] BVC.receive(ASP_Event:?) { }
	[] BVC.receive(BssgpStatusIndication:?) { }

	/* catch-all */
	[] BVC.receive(tr_ptp_BnsUdInd(?, 0)) -> value udi {
		setverdict(fail, "Received unexpected NS (SIG): ", udi);
	}
	[] BVC.receive(tr_ptp_BnsUdInd(?, ?)) -> value udi {
		setverdict(fail, "Received unexpected NS (PTP): ", udi);
	}
	[] BVC.receive {
		setverdict(fail, "Received unexpected message from BSSGP_CT");
	}

	/* registration/deregistration of Clients (per-TLLI components) */
	[] BSSGP_PROC.getcall(BSSGP_register_client:{?,?}) -> param(imsi, tlli) sender vc_conn {
		f_tbl_client_add(imsi, tlli, vc_conn);
		BSSGP_PROC.reply(BSSGP_register_client:{imsi, tlli}) to vc_conn;
		}
	[] BSSGP_PROC.getcall(BSSGP_unregister_client:{?}) -> param(imsi) sender vc_conn {
		f_tbl_client_del(imsi, vc_conn);
		BSSGP_PROC.reply(BSSGP_unregister_client:{imsi}) to vc_conn;
		}
	[] BSSGP_PROC.getcall(BSSGP_llgmm_assign:{?,?}) -> param(tlli_old, tlli) sender vc_conn {
		f_tbl_client_llgmm_assign(tlli_old, tlli, vc_conn);
		BSSGP_PROC.reply(BSSGP_llgmm_assign:{tlli_old, tlli}) to vc_conn;
		}

	[] MGMT.receive(BssgpResetRequest:?) -> value brr {
		f_ptp_change_state(BVC_S_BLOCKED);
		f_ptp_sendReset(brr.cause);
		}
}

/* main loop for per-BVC component */
private function f_bssgp_bvc_ScanEvents() runs on BSSGP_BVC_CT {
	while (true) {
		alt {
		[g_ptp_bvc_state == BVC_S_BLOCKED] as_ptp_blocked();
		[g_ptp_bvc_state == BVC_S_UNBLOCKED] as_ptp_unblocked();
		[] as_ptp_allstate();
		}
	}
}

/* main function for per-BVC Component */
private function f_bssgp_bvc_main(BssgpBvcConfig cfg, boolean sgsn_role, Nsei nsei, charstring id) runs on BSSGP_BVC_CT {
	g_cfg := cfg;
	g_nsei := nsei;
	g_bvc_lsp := cfg.bvci;
	g_sgsn_role := sgsn_role;
	f_bssgp_bvc_ScanEvents();
}

template (value) NsUnitdataRequest ts_ptp_BnsUdReq(template (value) PDU_BSSGP pdu, template (value) BssgpBvci bvci,
						   template (value) integer lsp) := {
	bvci := bvci,
	nsei := 0, // overwritten in BSSGP_CT
	lsp := lsp,
	/* for some weird reason we get "Dynamic test case error: Text encoder: Encoding an
	 * unbound integer value." when trying to send the reocrd rather than the octetstring */
	//sdu := omit,
	//bssgp := valueof(pdu)
	sdu := enc_PDU_BSSGP(valueof(pdu)),
	bssgp := omit
}

template (present) NsUnitdataIndication tr_ptp_BnsUdInd(template (present) PDU_BSSGP pdu, template (present) BssgpBvci bvci) := {
	bvci := bvci,
	nsei := ?,
	nsvci := ?,
	sdu := *,
	bssgp := pdu
}

/* change state of PTP BVC; broadcast state change to clients */
private function f_ptp_change_state(BvcState new_state) runs on BSSGP_BVC_CT {
	if (new_state == g_ptp_bvc_state) {
		return;
	}
	log("BVCI(", g_cfg.bvci, ") State Transition: ", g_ptp_bvc_state, " -> ", new_state);
	g_ptp_bvc_state := new_state;
	if (MGMT.checkstate("Connected")) {
		MGMT.send(ts_BssgpStsInd(g_nsei, g_cfg.bvci, g_ptp_bvc_state));
	}
	for (var integer i := 0; i < sizeof(ClientTable); i := i+1) {
		if (isbound(ClientTable[i].comp_ref) and ClientTable[i].comp_ref != null) {
			BSSGP_SP.send(ts_BssgpStsInd(g_nsei, g_cfg.bvci, g_ptp_bvc_state)) to ClientTable[i].comp_ref;
		}
	}
}

/* attempt to extract the TLLI from a BSSGP PDU */
function f_bssgp_get_tlli(PDU_BSSGP bssgp) return template OCT4 {
	if (ischosen(bssgp.pDU_BSSGP_DL_UNITDATA)) {
		return bssgp.pDU_BSSGP_DL_UNITDATA.tLLI_current;
	} else if (ischosen(bssgp.pDU_BSSGP_UL_UNITDATA)) {
		return bssgp.pDU_BSSGP_UL_UNITDATA.tLLI;
	} else if (ischosen(bssgp.pDU_BSSGP_RA_CAPABILITY)) {
		return bssgp.pDU_BSSGP_RA_CAPABILITY.tLLI.tLLI_Value;
	} else if (ischosen(bssgp.pDU_BSSGP_RA_CAPABILITY_UPDATE)) {
		return bssgp.pDU_BSSGP_RA_CAPABILITY_UPDATE.tLLI.tLLI_Value;
	} else if (ischosen(bssgp.pDU_BSSGP_RA_CAPABILITY_UPDATE_ACK)) {
		return bssgp.pDU_BSSGP_RA_CAPABILITY_UPDATE_ACK.tLLI.tLLI_Value;
	} else if (ischosen(bssgp.pDU_BSSGP_RADIO_STATUS)) {
		return bssgp.pDU_BSSGP_RADIO_STATUS.tLLI.tLLI_Value;
	} else if (ischosen(bssgp.pDU_BSSGP_SUSPEND)) {
		return bssgp.pDU_BSSGP_SUSPEND.tLLI.tLLI_Value;
	} else if (ischosen(bssgp.pDU_BSSGP_SUSPEND_ACK)) {
		return bssgp.pDU_BSSGP_SUSPEND_ACK.tLLI.tLLI_Value;
	} else if (ischosen(bssgp.pDU_BSSGP_SUSPEND_NACK)) {
		return bssgp.pDU_BSSGP_SUSPEND_NACK.tLLI.tLLI_Value;
	} else if (ischosen(bssgp.pDU_BSSGP_RESUME)) {
		return bssgp.pDU_BSSGP_RESUME.tLLI.tLLI_Value;
	} else if (ischosen(bssgp.pDU_BSSGP_RESUME_ACK)) {
		return bssgp.pDU_BSSGP_RESUME_ACK.tLLI.tLLI_Value;
	} else if (ischosen(bssgp.pDU_BSSGP_RESUME_NACK)) {
		return bssgp.pDU_BSSGP_RESUME_NACK.tLLI.tLLI_Value;
	} else if (ischosen(bssgp.pDU_BSSGP_FLUSH_LL)) {
		return bssgp.pDU_BSSGP_FLUSH_LL.tLLI.tLLI_Value;
	} else if (ischosen(bssgp.pDU_BSSGP_FLUSH_LL_ACK)) {
		return bssgp.pDU_BSSGP_FLUSH_LL_ACK.tLLI.tLLI_Value;
	} else if (ischosen(bssgp.pDU_BSSGP_LLC_DISCARDED)) {
		return bssgp.pDU_BSSGP_LLC_DISCARDED.tLLI.tLLI_Value;
	} else if (ischosen(bssgp.pDU_BSSGP_LLC_DISCARDED)) {
		return bssgp.pDU_BSSGP_LLC_DISCARDED.tLLI.tLLI_Value;
	} else if (ischosen(bssgp.pDU_BSSGP_PAGING_CS) and
		   isvalue(bssgp.pDU_BSSGP_PAGING_CS.tLLI)) {
		return bssgp.pDU_BSSGP_PAGING_CS.tLLI.tLLI_Value;
	} else if (ischosen(bssgp.pDU_BSSGP_FLOW_CONTROL_MS)) {
		return bssgp.pDU_BSSGP_FLOW_CONTROL_MS.tLLI.tLLI_Value;
	} else if (ischosen(bssgp.pDU_BSSGP_FLOW_CONTROL_MS_ACK)) {
		return bssgp.pDU_BSSGP_FLOW_CONTROL_MS_ACK.tLLI.tLLI_Value;
	}
	/* TODO: Handover, PFC, LCS */
	return omit;
}



}
