module PCUIF_Components {

/*
 * Components for (RAW) PCU test cases.
 *
 * (C) 2019 Vadim Yanitskiy <axilirator@gmail.com>
 *
 * 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 IPL4asp_Types all;
import from UD_Types all;

import from PCUIF_Types all;
import from PCUIF_CodecPort all;

import from Osmocom_Types all;
import from General_Types all;
import from RLCMAC_Types all;
import from GSM_RR_Types all;

/* Component communication diagram:
 *
 * +-----+               +----------+      +---------+
 * | MTC +---------------+ PCUIF_CT +------+ OsmoPCU |
 * +--+--+               +----+-----+      +---------+
 *    |                       |
 *    |                       |
 *    |                       |
 *    |    +-----------+      |      +---------------+
 *    +----+ BTS_CT #1 +------+      | ClckGen_CT #1 |
 *    |    +-----+-----+      |      +-------+-------+
 *    |          |            |              |
 *    |          +---------------------------+
 *    |                       |
 *    |    +-----------+      |      +---------------+
 *    +----+ BTS_CT #2 +------+      | ClckGen_CT #2 |
 *    |    +-----+-----+      |      +-------+-------+
 *    |          |            |              |
 *    |          +---------------------------+
 *    |                       |
 *    |    +-----------+      |      +---------------+
 *    +----+ BTS_CT #N +------+      | ClckGen_CT #N |
 *         +-----+-----+             +-------+-------+
 *               |                           |
 *               +---------------------------+
 */

/* Events are used by the components to indicate that something
 * has happened, e.g. we have got a connection from the PCU. */
type enumerated RAW_PCU_EventType {
	/* Events related to RAW_PCUIF_CT */
	PCU_EV_DISCONNECT,		/*!< OsmoPCU has disconnected */
	PCU_EV_CONNECT,			/*!< OsmoPCU is now connected */

	/* Events related to RAW_PCU_BTS_CT */
	BTS_EV_SI13_NEGO,		/*!< SI13 negotiation complete */

	/* TDMA clock related events (TDMA frame-number in parameters) */
	TDMA_EV_PDTCH_BLOCK_BEG,	/*!< 1/4 bursts of a PDTCH block on both Uplink and Downlink */
	TDMA_EV_PDTCH_BLOCK_END,	/*!< 4/4 bursts of a PDTCH block on both Uplink and Downlink */
	TDMA_EV_PTCCH_DL_BLOCK,		/*!< 4/4 bursts of a PTCCH block on Downlink */
	TDMA_EV_PTCCH_UL_BURST,		/*!< One Access Burst on PTCCH/U */

	TDMA_EV_PDTCH_BLOCK_SENT	/*!< A PDTCH block has been sent to the PCU */
};

/* Union of all possible parameters of the events */
type union RAW_PCU_EventParam {
	integer tdma_fn
};

type record RAW_PCU_Event {
	RAW_PCU_EventType event,
	/* TODO: can we use 'anytype' here? */
	RAW_PCU_EventParam data optional
};

template (value) RAW_PCU_Event ts_RAW_PCU_EV(RAW_PCU_EventType event) := {
	event := event,
	data := omit
}
template RAW_PCU_Event tr_RAW_PCU_EV(template RAW_PCU_EventType event := ?,
				     template RAW_PCU_EventParam data := *) := {
	event := event,
	data := data
}

template (value) RAW_PCU_Event ts_RAW_PCU_CLCK_EV(RAW_PCU_EventType event, integer fn) := {
	event := event,
	data := { tdma_fn := fn }
}
template RAW_PCU_Event tr_RAW_PCU_CLCK_EV := {
	event := (TDMA_EV_PDTCH_BLOCK_BEG, TDMA_EV_PDTCH_BLOCK_END,
		  TDMA_EV_PTCCH_DL_BLOCK, TDMA_EV_PTCCH_UL_BURST,
		  TDMA_EV_PDTCH_BLOCK_SENT),
	data := { tdma_fn := ? }
}

/* Commands are mostly used by the MTC to configure the components
 * at run-time, e.g. to enable or disable some optional features. */
type enumerated RAW_PCU_CommandType {
	GENERAL_CMD_SHUTDOWN,		/*!< Shut down component and all its child components */
	TDMA_CMD_ENABLE_PTCCH_UL_FWD	/*!< Enable forwarding of TDMA_EV_PTCCH_UL_BURST to the MTC */
};

type record RAW_PCU_Command {
	RAW_PCU_CommandType cmd,
	anytype data optional
};

template (value) RAW_PCU_Command ts_RAW_PCU_CMD(RAW_PCU_CommandType cmd) := {
	cmd := cmd,
	data := omit
}
template RAW_PCU_Command tr_RAW_PCU_CMD(template RAW_PCU_CommandType cmd := ?,
					template anytype data := *) := {
	cmd := cmd,
	data := data
}

/* PCUIF req_data containing decoded rlcmac/rr, for users to be able to match
 * directly on receive()
 */
type record BTS_PDTCH_Block {
	uint8_t		bts_nr,
	PCUIF_data	raw,
	RlcmacDlBlock	dl_block optional
};
type record BTS_PTCCH_Block {
	uint8_t		bts_nr,
	PCUIF_data	raw,
	PTCCHDownlinkMsg dl_block optional
};
type record BTS_CCCH_Block {
	uint8_t		bts_nr,
	PCUIF_data	raw,
	OCT4		tlli optional,
	charstring	imsi optional,
	GsmRrMessage	rr_msg
};
template BTS_PDTCH_Block tr_PCUIF_DATA_PDTCH(template uint8_t bts_nr,
					    template PCUIF_data raw,
					    template RlcmacDlBlock dl_block := ?) := {
	bts_nr := bts_nr,
	raw := raw,
	dl_block := dl_block
};
template BTS_PTCCH_Block tr_PCUIF_DATA_PTCCH(template uint8_t bts_nr,
					    template PCUIF_data raw,
					    template PTCCHDownlinkMsg dl_block := ?) := {
	bts_nr := bts_nr,
	raw := raw,
	dl_block := dl_block
};
template BTS_CCCH_Block tr_PCUIF_DATA_RR(template uint8_t bts_nr,
					    template PCUIF_data raw,
					    template GsmRrMessage rr_msg := ?,
					    template OCT4 tlli := *,
					    template charstring imsi := *) := {
	bts_nr := bts_nr,
	raw := raw,
	tlli := tlli,
	imsi := imsi,
	rr_msg := rr_msg
};

/* Generic port for messages and events */
type port RAW_PCU_MSG_PT message {
	inout RAW_PCU_Command;
	inout RAW_PCU_Event;
	inout PCUIF_Message;
	inout BTS_PDTCH_Block;
	inout BTS_PTCCH_Block;
	inout BTS_CCCH_Block;
} with { extension "internal" };

/* TDMA frame clock generator */
type component RAW_PCU_ClckGen_CT {
	/* One TDMA frame is 4.615 ms long */
	timer T_TDMAClock := 4.615 / 1000.0;
	port RAW_PCU_MSG_PT CLCK;
	var integer fn := 0;
}

/* Derive PTCCH/U sub-slot from a given TDMA frame-number */
function f_tdma_ptcch_fn2ss(integer fn) return integer
{
	var integer ss := -1;

	/* See 3GPP TS 45.002, table 6 */
	select (fn mod 416) {
	case (12) { ss := 0; }
	case (38) { ss := 1; }
	case (64) { ss := 2; }
	case (90) { ss := 3; }

	case (116) { ss := 4; }
	case (142) { ss := 5; }
	case (168) { ss := 6; }
	case (194) { ss := 7; }

	case (220) { ss := 8; }
	case (246) { ss := 9; }
	case (272) { ss := 10; }
	case (298) { ss := 11; }

	case (324) { ss := 12; }
	case (350) { ss := 13; }
	case (376) { ss := 14; }
	case (402) { ss := 15; }
	}

	return ss;
}

function f_ClckGen_CT_handler(integer start_fn := 0)
runs on RAW_PCU_ClckGen_CT {
	var integer fn104, fn52, fn13;

	fn := start_fn;

	while (true) {
		fn104 := fn mod 104;
		fn52 := fn mod 52;
		fn13 := fn mod 13;

		if (fn13 == 0 or fn13 == 4 or fn13 == 8) {
			/* 1/4 bursts of a PDTCH block on both Uplink and Downlink */
			CLCK.send(ts_RAW_PCU_CLCK_EV(TDMA_EV_PDTCH_BLOCK_BEG, fn));
		} else if (fn13 == 3 or fn13 == 7 or fn13 == 11) {
			/* 4/4 bursts of a PDTCH block on both Uplink and Downlink */
			CLCK.send(ts_RAW_PCU_CLCK_EV(TDMA_EV_PDTCH_BLOCK_END, fn));
		} else if (fn52 == 12 or fn52 == 38) {
			/* 4/4 bursts of a PTCCH (Timing Advance Control) block on Downlink */
			if (fn104 == 90) {
				CLCK.send(ts_RAW_PCU_CLCK_EV(TDMA_EV_PTCCH_DL_BLOCK, fn));
			}
			/* One Access Burst on PTCCH/U (goes 3 time-slots after PTCCH/D) */
			CLCK.send(ts_RAW_PCU_CLCK_EV(TDMA_EV_PTCCH_UL_BURST, fn));
		}

		/* TDMA hyperframe period is (2048 * 51 * 26) frames */
		fn := (fn + 1) mod (2048 * 51 * 26);

		/* (Re)start TDMA clock timer and wait */
		T_TDMAClock.start;
		T_TDMAClock.timeout;
	}
}

type record of PCUIF_Message PCUIF_MsgQueue;

/* Enqueue a given message to the end of a given queue */
private function f_PCUIF_MsgQueue_enqueue(inout PCUIF_MsgQueue queue,
					  in PCUIF_Message msg)
{
	queue := queue & { msg };
}

/* Dequeue the first message of a given queue */
private function f_PCUIF_MsgQueue_dequeue(inout PCUIF_MsgQueue queue,
					  out PCUIF_Message msg)
{
	var integer len := lengthof(queue);

	if (len == 0) {
		setverdict(fail, "Failed to dequeue a message: the queue is empty!");
		mtc.stop;
	}

	/* Store the first message */
	msg := queue[0];

	/* Remove the first message from queue */
	if (len > 1) {
		queue := substr(queue, 1, len - 1);
	} else {
		queue := { };
	}
}

/* Get first message from queue. true if non-empty, false otherwise */
private function f_PCUIF_MsgQueue_first(inout PCUIF_MsgQueue queue,
					out PCUIF_Message msg) return boolean
{
	if (lengthof(queue) == 0) {
		return false;
	}

	msg := queue[0];
	return true;
}

/* Multiple base stations can be connected to the PCU. This component
 * represents one BTS with an associated TDMA clock generator. */
type component RAW_PCU_BTS_CT {
	/* TDMA clock generator */
	var RAW_PCU_ClckGen_CT vc_CLCK_GEN;
	port RAW_PCU_MSG_PT CLCK;

	/* Queues of PCUIF messages to be sent
	 * TODO: we may have multiple PDCH time-slots */
	var PCUIF_MsgQueue pdtch_data_queue := { };
	var PCUIF_MsgQueue pdtch_rts_queue := { };
	var PCUIF_MsgQueue ptcch_rts_queue := { };

	/* Connection towards the PCU interface */
	port RAW_PCU_MSG_PT PCUIF;
	/* Connection towards the test case */
	port RAW_PCU_MSG_PT TC;

	/* Whether to forward PTCCH/U burst events to the TC */
	var boolean cfg_ptcch_burst_fwd := false;

	var PCUIF_info_ind g_info_ind;
}

/* Queue received messages from Test Case, they will eventually be scheduled and
 * sent according to their FN. FN value of 0 has the special meaning of "schedule
 * as soon as possible". */
private altstep as_BTS_CT_MsgQueue(integer bts_nr)
runs on RAW_PCU_BTS_CT {
	var PCUIF_Message pcu_msg;

	/* Enqueue DATA.ind and RTS.req messages */
	[] TC.receive(tr_PCUIF_MSG(PCU_IF_MSG_DATA_IND, bts_nr)) -> value pcu_msg {
		if (pcu_msg.u.data_ind.sapi == PCU_IF_SAPI_BCCH) {
			PCUIF.send(pcu_msg); /* Forward directly ASAP */
		} else {
			f_PCUIF_MsgQueue_enqueue(pdtch_data_queue, pcu_msg);
		}
		repeat;
		}
	[] TC.receive(tr_PCUIF_RTS_REQ(bts_nr, sapi := PCU_IF_SAPI_PDTCH)) -> value pcu_msg {
		f_PCUIF_MsgQueue_enqueue(pdtch_rts_queue, pcu_msg);
		repeat;
		}
	[] TC.receive(tr_PCUIF_RTS_REQ(bts_nr, sapi := PCU_IF_SAPI_PTCCH)) -> value pcu_msg {
		f_PCUIF_MsgQueue_enqueue(ptcch_rts_queue, pcu_msg);
		repeat;
		}
	/* Forward other messages directly to the PCU */
	[] TC.receive(tr_PCUIF_MSG(?, bts_nr)) -> value pcu_msg {
		PCUIF.send(pcu_msg);
		repeat;
		}
}

/* Submit empty data on any available TS, to set up initial TDMA clock */
private function f_tx_first_data_ind(integer bts_nr, PCUIF_info_ind info_ind, integer start_fn)
runs on RAW_PCU_BTS_CT
{
	var PCUIF_Message pcu_msg;

	/* Find an active TS: */
	for (var uint8_t ts_nr := 0; ts_nr < 8; ts_nr := ts_nr + 1) {
		for (var integer trx_nr := 0; trx_nr < lengthof(g_info_ind.trx); trx_nr := trx_nr + 1) {
			if (g_info_ind.trx[trx_nr].pdch_mask[ts_nr] == '0'B) {
				continue; /* TRX+TS not activated */
			}

			/* Send empty DATA.ind to set up FN */
			pcu_msg := valueof(ts_PCUIF_DATA_IND(bts_nr, trx_nr, ts_nr, 0 /* FIXME */,
							     PCU_IF_SAPI_PDTCH, ''O, start_fn,
							     g_info_ind.trx[trx_nr].arfcn,
							     rssi := -80, ber10k := 0,
							     ta_offs_qbits := 0, lqual_cb := 10));
			PCUIF.send(pcu_msg);
			return;
		}
	}
}

private function fn2macblock(uint32_t fn)  return uint8_t
{
	return (fn mod 52) / 4;
}

/* Get first message from queue. true if non-empty, false otherwise */
private function f_tx_data_ind_fn(integer bts_nr, integer fn)
runs on RAW_PCU_BTS_CT
{
	var PCUIF_Message pcu_msg;
	var boolean has_msg, use_msg;

	for (var uint8_t ts_nr := 0; ts_nr < 8; ts_nr := ts_nr + 1) {
		for (var integer trx_nr := 0; trx_nr < lengthof(g_info_ind.trx); trx_nr := trx_nr + 1) {
			//var charstring prefix := "BTS=" & int2str(bts_nr) & ",TRX=" & int2str(trx_nr) & ",TS=" & int2str(ts_nr) & ",FN=" & int2str(fn) & ": ";
			if (g_info_ind.trx[trx_nr].pdch_mask[ts_nr] == '0'B) {
				//log(prefix, "disabled");
				continue; /* TRX+TS not activated */
			}

			/* Check if we reached time to serve the first DATA.ind message in the queue: */
			has_msg := f_PCUIF_MsgQueue_first(pdtch_data_queue, pcu_msg) and
				   pcu_msg.u.data_ind.trx_nr == trx_nr and
				   pcu_msg.u.data_ind.ts_nr == ts_nr;
			use_msg := has_msg and (pcu_msg.u.data_ind.fn == 0 or pcu_msg.u.data_ind.fn == fn);
			if (use_msg) {
				/* Dequeue a DATA.ind message */
				f_PCUIF_MsgQueue_dequeue(pdtch_data_queue, pcu_msg);
				/* Patch TDMA frame / block number */
				pcu_msg.u.data_ind.fn := fn;
				pcu_msg.u.data_ind.block_nr := fn2macblock(fn);
				//log(prefix, "DATA.ind");
			} else if (has_msg and pcu_msg.u.data_ind.fn < fn) {
				setverdict(fail, "We are late scheduling the block! ", pcu_msg.u.data_ind.fn, " < ", fn);
				mtc.stop;
			} else {
				/* NOPE.ind: */
				pcu_msg := valueof(ts_PCUIF_DATA_IND(bts_nr, trx_nr, ts_nr, 0 /* FIXME */,
								     PCU_IF_SAPI_PDTCH, ''O, fn,
								     g_info_ind.trx[trx_nr].arfcn,
								     rssi := -80, ber10k := 0,
								     ta_offs_qbits := 0, lqual_cb := 10));
				//log(prefix, "DATA.ind (len=0)");
			}

			PCUIF.send(pcu_msg); /* Send to the PCU and notify the TC */
			if (use_msg) {
				TC.send(ts_RAW_PCU_CLCK_EV(TDMA_EV_PDTCH_BLOCK_SENT, fn));
			}
		}
	}
}

/* Handle schedule events and manage actions: Send msgs over PCUIF to PCU,
 * advertise Test Case about sent messages, etc. */
private altstep as_BTS_CT_TDMASched(integer bts_nr)
runs on RAW_PCU_BTS_CT {
	var PCUIF_Message pcu_msg;
	var RAW_PCU_Event event;
	var integer ev_begin_fn;

	[] CLCK.receive(tr_RAW_PCU_EV(TDMA_EV_PDTCH_BLOCK_BEG)) -> value event {
		/* If the RTS queue for PDTCH is not empty, send a message */
		if (lengthof(pdtch_rts_queue) > 0) {
			f_PCUIF_MsgQueue_dequeue(pdtch_rts_queue, pcu_msg);

			/* Patch TDMA frame / block number and send */
			pcu_msg.u.rts_req.fn := event.data.tdma_fn;
			pcu_msg.u.rts_req.block_nr := fn2macblock(event.data.tdma_fn);
			PCUIF.send(pcu_msg);
		}

		/* We don't really need to send every frame to OsmoPCU, because
		 * it omits frame numbers not starting at a MAC block. */
		PCUIF.send(ts_PCUIF_TIME_IND(bts_nr, event.data.tdma_fn));
		repeat;
		}
	[] CLCK.receive(tr_RAW_PCU_EV(TDMA_EV_PDTCH_BLOCK_END)) -> value event {
		/* FN matching the beginning of current block: */
		ev_begin_fn := event.data.tdma_fn - 3;
		f_tx_data_ind_fn(bts_nr, ev_begin_fn);
		repeat;
		}
	[lengthof(ptcch_rts_queue) > 0] CLCK.receive(tr_RAW_PCU_EV(TDMA_EV_PTCCH_DL_BLOCK)) -> value event {
		/* FN matching the beginning of current block (PTCCH is interleaved over 4 non-consecutive bursts): */
		ev_begin_fn := event.data.tdma_fn - 78;
		/* Dequeue an RTS.req message for PTCCH */
		f_PCUIF_MsgQueue_dequeue(ptcch_rts_queue, pcu_msg);

		/* Patch TDMA frame / block number and send */
		pcu_msg.u.rts_req.fn := ev_begin_fn;
		pcu_msg.u.rts_req.block_nr := fn2macblock(ev_begin_fn);
		PCUIF.send(pcu_msg);
		repeat;
		}
	/* Optional forwarding of PTCCH/U burst indications to the test case */
	[cfg_ptcch_burst_fwd] CLCK.receive(tr_RAW_PCU_EV(TDMA_EV_PTCCH_UL_BURST)) -> value event {
		TC.send(event);
		repeat;
		}
	/* Ignore other clock events (and guard against an empty queue) */
	[] CLCK.receive(tr_RAW_PCU_CLCK_EV) { repeat; }
}

function f_BTS_CT_handler(integer bts_nr, PCUIF_info_ind info_ind, boolean decode_data_req := false)
runs on RAW_PCU_BTS_CT {
	var PCUIF_Message pcu_msg;
	var RAW_PCU_Command cmd;
	var RAW_PCU_Event event;
	var BTS_PDTCH_Block pcu_msg_pdtch;
	var BTS_PTCCH_Block pcu_msg_ptcch;
	var BTS_CCCH_Block pcu_msg_rr;

	g_info_ind := info_ind;

	/* Init TDMA clock generator (so we can stop and start it) */
	vc_CLCK_GEN := RAW_PCU_ClckGen_CT.create("ClckGen-" & int2str(bts_nr)) alive;
	connect(vc_CLCK_GEN:CLCK, self:CLCK);

	/* Wait until the PCU is connected */
	PCUIF.receive(tr_RAW_PCU_EV(PCU_EV_CONNECT));

	var template PCUIF_Sapi tr_ccch_sapi := (PCU_IF_SAPI_PCH, PCU_IF_SAPI_PCH_DT, PCU_IF_SAPI_AGCH);
	alt {
	/* Wait for TXT.ind (PCU_VERSION) and respond with INFO.ind (SI13) */
	[] PCUIF.receive(tr_PCUIF_TXT_IND(bts_nr, PCU_VERSION, ?)) -> value pcu_msg {
		log("Rx TXT.ind from the PCU, version is ", pcu_msg.u.txt_ind.text);

		/* Send System Information 13 to the PCU */
		PCUIF.send(PCUIF_Message:{
			msg_type := PCU_IF_MSG_INFO_IND,
			bts_nr := bts_nr,
			spare := '0000'O,
			u := { info_ind := info_ind }
		});

		const integer start_fn := 0;
		f_tx_first_data_ind(bts_nr, info_ind, start_fn);

		/* Notify the test case that we're done with SI13 */
		TC.send(ts_RAW_PCU_EV(BTS_EV_SI13_NEGO));

		/* Start feeding clock to the PCU */
		vc_CLCK_GEN.start(f_ClckGen_CT_handler(start_fn));
		repeat;
		}
	/* PCU -> TS becomes active */
	[] PCUIF.receive(tr_PCUIF_ACT_REQ(bts_nr, ?, ?)) -> value pcu_msg {
		log("Rx ACT.req from the PCU: TRX" & int2str(pcu_msg.u.act_req.trx_nr) &
		    "/TS" & int2str(pcu_msg.u.act_req.ts_nr));
		repeat;
		}
	/* PCU -> TS becomes inactive */
	[] PCUIF.receive(tr_PCUIF_DEACT_REQ(bts_nr, ?, ?)) -> value pcu_msg {
		log("Rx DEACT.req from the PCU: TRX" & int2str(pcu_msg.u.act_req.trx_nr) &
		    "/TS" & int2str(pcu_msg.u.act_req.ts_nr));
		repeat;
		}
	[decode_data_req] PCUIF.receive(tr_PCUIF_DATA_REQ(bts_nr, ?, ?, sapi := tr_ccch_sapi)) -> value pcu_msg {
		var octetstring data;
		var PCUIF_pch_dt pch_dt;
		/* On PCH the payload is prefixed with paging group (3 octets): skip it.
		 * TODO: add an additional template parameter, so we can match it. */
		if (pcu_msg.u.data_req.sapi == PCU_IF_SAPI_PCH) {
			data := substr(pcu_msg.u.data_req.data, 3, pcu_msg.u.data_req.len - 3);
		} else if (pcu_msg.u.data_req.sapi == PCU_IF_SAPI_AGCH) {
			data := pcu_msg.u.data_req.data;
		}
		pcu_msg_rr.bts_nr := bts_nr;
		pcu_msg_rr.raw := pcu_msg.u.data_req;

		if (pcu_msg_rr.raw.sapi == PCU_IF_SAPI_PCH_DT) {
			pch_dt := dec_PCUIF_pch_dt(pcu_msg_rr.raw.data);
			pcu_msg_rr.tlli := pch_dt.tlli;
			pcu_msg_rr.imsi := pch_dt.imsi;
			pcu_msg_rr.rr_msg := dec_GsmRrMessage(pch_dt.data);
		} else {
			pcu_msg_rr.tlli := omit;
			pcu_msg_rr.imsi := omit;
			pcu_msg_rr.rr_msg := dec_GsmRrMessage(data);
		}
		TC.send(pcu_msg_rr);
		repeat;
	}
	[decode_data_req] PCUIF.receive(tr_PCUIF_DATA_REQ(bts_nr, ?, ?, sapi := PCU_IF_SAPI_PDTCH)) -> value pcu_msg {
		pcu_msg_pdtch.bts_nr := bts_nr;
		pcu_msg_pdtch.raw := pcu_msg.u.data_req;
		if (pcu_msg_pdtch.raw.len != 0) {
			pcu_msg_pdtch.dl_block := dec_RlcmacDlBlock(pcu_msg_pdtch.raw.data);
		} else {
			pcu_msg_pdtch.dl_block := omit;
		}
		TC.send(pcu_msg_pdtch);
		repeat;
	}
	[decode_data_req] PCUIF.receive(tr_PCUIF_DATA_REQ(bts_nr, ?, ?, sapi := PCU_IF_SAPI_PTCCH)) -> value pcu_msg {
		pcu_msg_ptcch.bts_nr := bts_nr;
		pcu_msg_ptcch.raw := pcu_msg.u.data_req;
		if (pcu_msg_ptcch.raw.len != 0) {
			pcu_msg_ptcch.dl_block := dec_PTCCHDownlinkMsg(pcu_msg_ptcch.raw.data);
		} else {
			pcu_msg_ptcch.dl_block := omit;
		}
		TC.send(pcu_msg_ptcch);
		repeat;
	}
	/* PCU -> test case forwarding (filter by the BTS number) */
	[] PCUIF.receive(tr_PCUIF_MSG(?, bts_nr)) -> value pcu_msg {
		TC.send(pcu_msg);
		repeat;
		}

	/* TC -> [Queue] -> PCU forwarding */
	[] as_BTS_CT_MsgQueue(bts_nr);
	/* TDMA scheduler (clock and queue handling) */
	[] as_BTS_CT_TDMASched(bts_nr);

	/* Command handling */
	[] TC.receive(tr_RAW_PCU_CMD(GENERAL_CMD_SHUTDOWN)) {
		log("Shutting down virtual BTS #", bts_nr, "...");
		vc_CLCK_GEN.stop;
		break;
		}
	[] TC.receive(tr_RAW_PCU_CMD(TDMA_CMD_ENABLE_PTCCH_UL_FWD)) {
		log("Enabling forwarding of PTCCH/U TDMA events to the TC");
		cfg_ptcch_burst_fwd := true;
		repeat;
		}
	[] TC.receive(tr_RAW_PCU_CMD) -> value cmd {
		log("Ignore unhandled command: ", cmd);
		repeat;
		}

	/* TODO: handle events (e.g. disconnection) from the PCU interface */
	[] PCUIF.receive(tr_RAW_PCU_EV) -> value event {
		log("Ignore unhandled event: ", event);
		repeat;
		}
	}
}

/* PCU interface (UNIX domain socket) handler */
type component RAW_PCUIF_CT {
	var ConnectionId g_pcu_conn_id := -1;
	var boolean g_pcu_connected := false;
	port PCUIF_CODEC_PT PCU;

	/* Connection towards BTS component(s) */
	port RAW_PCU_MSG_PT BTS;
	/* Connection to the MTC (test case) */
	port RAW_PCU_MSG_PT MTC;
};

/* All received messages and events from OsmoPCU can be additionally sent
 * directly to the MTC component. Pass direct := true to enable this mode. */
function f_PCUIF_CT_handler(charstring pcu_sock_path, boolean direct := false)
runs on RAW_PCUIF_CT {
	var PCUIF_send_data pcu_sd_msg;
	var PCUIF_Message pcu_msg;
	timer T_Conn := 10.0;

	log("Init PCU interface on '" & pcu_sock_path & "', waiting for connection...");
	g_pcu_conn_id := f_pcuif_listen(PCU, pcu_sock_path);

	/* Wait for connection */
	T_Conn.start;
	alt {
	[not g_pcu_connected] PCU.receive(UD_connected:?) {
		log("OsmoPCU is now connected");
		/* Duplicate this event to the MTC if requested */
		if (direct) { MTC.send(ts_RAW_PCU_EV(PCU_EV_CONNECT)); }
		BTS.send(ts_RAW_PCU_EV(PCU_EV_CONNECT));
		g_pcu_connected := true;
		setverdict(pass);
		T_Conn.stop;
		repeat;
		}
	/* PCU -> BTS / MTC message forwarding */
	[g_pcu_connected] PCU.receive(PCUIF_send_data:?) -> value pcu_sd_msg {
		/* Send to the BTSes if at least one is connected */
		if (BTS.checkstate("Connected")) { BTS.send(pcu_sd_msg.data); }
		/* Duplicate this message to the MTC if requested */
		if (direct) { MTC.send(pcu_sd_msg.data); }
		repeat;
		}
	/* MTC -> PCU message forwarding */
	[g_pcu_connected] MTC.receive(PCUIF_Message:?) -> value pcu_msg {
		PCU.send(t_SD_PCUIF(g_pcu_conn_id, pcu_msg));
		repeat;
		}
	/* BTS -> PCU message forwarding */
	[g_pcu_connected] BTS.receive(PCUIF_Message:?) -> value pcu_msg {
		PCU.send(t_SD_PCUIF(g_pcu_conn_id, pcu_msg));
		repeat;
		}
	[not g_pcu_connected] MTC.receive(PCUIF_Message:?) -> value pcu_msg {
		log("PCU is not connected, dropping ", pcu_msg);
		repeat;
		}
	[not g_pcu_connected] BTS.receive(PCUIF_Message:?) -> value pcu_msg {
		log("PCU is not connected, dropping ", pcu_msg);
		repeat;
		}
	/* TODO: handle disconnect and reconnect of the PCU */
	[] PCU.receive {
		log("Unhandled message on PCU interface");
		repeat;
		}
	[not g_pcu_connected] T_Conn.timeout {
		setverdict(fail, "Timeout waiting for PCU connection");
		mtc.stop;
		}
	}
}

}
