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

modulepar {
	boolean mp_send_all_data_ind := true;
}

/* 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
};
type record BTS_PTCCH_Block {
	uint8_t		bts_nr,
	PCUIF_data	raw,
	PTCCHDownlinkMsg dl_block
};
type record BTS_CCCH_Block {
	uint8_t		bts_nr,
	PCUIF_data	raw,
	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 := ?) := {
	bts_nr := bts_nr,
	raw := raw,
	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)");
			}

			if (use_msg or mp_send_all_data_ind) {
				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_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;
		if (mp_send_all_data_ind) {
			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;
		/* 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;
		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;
		pcu_msg_pdtch.dl_block := dec_RlcmacDlBlock(pcu_msg_pdtch.raw.data);
		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;
		pcu_msg_ptcch.dl_block := dec_PTCCHDownlinkMsg(pcu_msg_ptcch.raw.data);
		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;
		}
	}
}

}
