/* pcu_l1_if.cpp
 *
 * Copyright (C) 2012 Andreas Eversberg <jolly@eversberg.eu>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <stdio.h>
#include <unistd.h>
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <arpa/inet.h>
#include <ctype.h>

extern "C" {
#include <osmocom/core/talloc.h>
#include <osmocom/core/select.h>
#include <osmocom/core/msgb.h>
#include <osmocom/core/gsmtap_util.h>
#include <osmocom/core/gsmtap.h>
#include <osmocom/core/bitvec.h>
#include <osmocom/core/sockaddr_str.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/utils.h>
#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/gsm/l1sap.h>
#include <osmocom/gsm/protocol/gsm_04_08.h>
#include <osmocom/gsm/gsm48_rest_octets.h>
#include <osmocom/gsm/sysinfo.h>
#include <osmocom/gsm/gsm0502.h>

#include <nacc_fsm.h>
#include <pcu_l1_if_phy.h>
}

#include <gprs_rlcmac.h>
#include <pcu_l1_if.h>
#include <gprs_debug.h>
#include <gprs_bssgp_pcu.h>
#include <osmocom/pcu/pcuif_proto.h>
#include <bts.h>
#include <pdch.h>
#include <tbf_ul.h>
#include <tbf_dl.h>
#include <gprs_ms_storage.h>

extern void *tall_pcu_ctx;

struct e1_ccu_conn_pars {
	struct llist_head entry;

	/* Related air interface */
	uint8_t bts_nr;
	uint8_t trx_nr;
	uint8_t ts_nr;

	/* E1 communication parameter */
	struct e1_conn_pars e1_conn_pars;
};

/* List storage to collect E1 connection information that we receive through the pcu_sock. The collected data serves as
 * a lookup table so that we can lookup the E1 connection information for each PDCH (trx number and timeslot number)
 * when it is needed. */
static LLIST_HEAD(e1_ccu_table);

/*
 * PCU messages
 */

/* Can be used to allocate message with non-variable size */
struct msgb *pcu_msgb_alloc(uint8_t msg_type, uint8_t bts_nr)
{
	struct msgb *msg;
	struct gsm_pcu_if *pcu_prim;

	msg = msgb_alloc(sizeof(struct gsm_pcu_if), "pcu_sock_tx");
	if (!msg)
		return NULL;
	msgb_put(msg, sizeof(struct gsm_pcu_if));
	pcu_prim = (struct gsm_pcu_if *) msg->data;
	pcu_prim->msg_type = msg_type;
	pcu_prim->bts_nr = bts_nr;

	return msg;
}

/* Allocate message with extra size, only reserve pcuif msg hdr */
static struct msgb *pcu_msgb_alloc_ext_size(uint8_t msg_type, uint8_t bts_nr, size_t extra_size)
{
	struct msgb *msg;
	struct gsm_pcu_if *pcu_prim;
	msg = msgb_alloc(sizeof(struct gsm_pcu_if) + extra_size, "pcu_sock_tx");
	/* Only header is filled, caller is responible for reserving + filling
	 * message type specific contents: */
	msgb_put(msg, PCUIF_HDR_SIZE);
	pcu_prim = (struct gsm_pcu_if *) msgb_data(msg);
	pcu_prim->msg_type = msg_type;
	pcu_prim->bts_nr = bts_nr;
	return msg;
}

const struct value_string gsm_pcu_if_text_type_names[] = {
	OSMO_VALUE_STRING(PCU_VERSION),
	OSMO_VALUE_STRING(PCU_OML_ALERT),
	{ 0, NULL }
};

int pcu_tx_txt_ind(enum gsm_pcu_if_text_type t, const char *fmt, ...)
{
	struct gsm_pcu_if *pcu_prim;
	struct gsm_pcu_if_txt_ind *txt;
	va_list ap;
	char *rep;
	struct msgb *msg = pcu_msgb_alloc(PCU_IF_MSG_TXT_IND, 0);
	if (!msg)
		return -ENOMEM;

	pcu_prim = (struct gsm_pcu_if *) msg->data;
	txt = &pcu_prim->u.txt_ind;
	txt->type = t;

	va_start(ap, fmt);
	rep = talloc_vasprintf(tall_pcu_ctx, fmt, ap);
	va_end(ap);

	if (!rep)
		return -ENOMEM;

	osmo_strlcpy(txt->text, rep, TXT_MAX_LEN);
	talloc_free(rep);

	LOGP(DL1IF, LOGL_INFO, "Sending %s TXT as %s to BTS\n", txt->text,
	     get_value_string(gsm_pcu_if_text_type_names, t));

	return pcu_sock_send(msg);
}

static int pcu_tx_act_req(struct gprs_rlcmac_bts *bts, const struct gprs_rlcmac_pdch *pdch,
			  uint8_t activate)
{
	struct msgb *msg;
	struct gsm_pcu_if *pcu_prim;
	struct gsm_pcu_if_act_req *act_req;

	LOGPDCH(pdch, DL1IF, LOGL_INFO, "Sending %s request\n",
		(activate) ? "activate" : "deactivate");

	msg = pcu_msgb_alloc(PCU_IF_MSG_ACT_REQ, bts->nr);
	if (!msg)
		return -ENOMEM;
	pcu_prim = (struct gsm_pcu_if *) msg->data;
	act_req = &pcu_prim->u.act_req;
	act_req->activate = activate;
	act_req->trx_nr = pdch->trx_no();
	act_req->ts_nr = pdch->ts_no;

	return pcu_sock_send(msg);
}

static int pcu_tx_data_req(struct gprs_rlcmac_bts *bts, uint8_t trx, uint8_t ts, uint8_t sapi,
	uint16_t arfcn, uint32_t fn, uint8_t block_nr, uint8_t *data,
	uint8_t len)
{
	struct msgb *msg;
	struct gsm_pcu_if *pcu_prim;
	struct gsm_pcu_if_data *data_req;
	int current_fn = bts_current_frame_number(bts);

	LOGP(DL1IF, LOGL_DEBUG, "(bts=%u,trx=%u,ts=%u) FN=%u Sending data request: sapi=%d "
	     "arfcn=%d cur_fn=%d block=%d data=%s\n", bts->nr, trx, ts, fn, sapi,
	     arfcn, current_fn, block_nr, osmo_hexdump(data, len));

	msg = pcu_msgb_alloc(PCU_IF_MSG_DATA_REQ, bts->nr);
	if (!msg)
		return -ENOMEM;
	pcu_prim = (struct gsm_pcu_if *) msg->data;
	data_req = &pcu_prim->u.data_req;

	data_req->sapi = sapi;
	data_req->fn = fn;
	data_req->arfcn = arfcn;
	data_req->trx_nr = trx;
	data_req->ts_nr = ts;
	data_req->block_nr = block_nr;
	if (len)
		memcpy(data_req->data, data, len);
	data_req->len = len;

	return pcu_sock_send(msg);
}

void pcu_l1if_tx_pdtch(msgb *msg, struct gprs_rlcmac_bts *bts, uint8_t trx, uint8_t ts, uint16_t arfcn,
	uint32_t fn, uint8_t block_nr)
{
#ifdef ENABLE_DIRECT_PHY
	if (bts->trx[trx].fl1h) {
		if (!msg) /* Simply skip sending idle frames to L1 */
			return;
		l1if_pdch_req(bts->trx[trx].fl1h, ts, 0, fn, arfcn, block_nr,
			msg->data, msg->len);
		msgb_free(msg);
		return;
	}
#endif
	if (!msg) {
		pcu_tx_data_req(bts, trx, ts, PCU_IF_SAPI_PDTCH, arfcn, fn, block_nr,
				NULL, 0);
		return;
	}

	pcu_tx_data_req(bts, trx, ts, PCU_IF_SAPI_PDTCH, arfcn, fn, block_nr,
			msg->data, msg->len);
	msgb_free(msg);
}

void pcu_l1if_tx_ptcch(struct gprs_rlcmac_bts *bts,
		       uint8_t trx, uint8_t ts, uint16_t arfcn,
		       uint32_t fn, uint8_t block_nr,
		       uint8_t *data, size_t data_len)
{
	if (data_len && the_pcu->gsmtap_categ_mask & (1 << PCU_GSMTAP_C_DL_PTCCH))
		gsmtap_send(the_pcu->gsmtap, arfcn, ts, GSMTAP_CHANNEL_PTCCH, 0, fn, 0, 0, data, data_len);
#ifdef ENABLE_DIRECT_PHY
	if (bts->trx[trx].fl1h) {
		if (!data_len) /* Simply skip sending idle frames to L1 */
			return;
		l1if_pdch_req(bts->trx[trx].fl1h, ts, 1, fn, arfcn, block_nr, data, data_len);
		return;
	}
#endif
	if (!data_len) {
		pcu_tx_data_req(bts, trx, ts, PCU_IF_SAPI_PTCCH, arfcn, fn, block_nr, NULL, 0);
		return;
	}

	pcu_tx_data_req(bts, trx, ts, PCU_IF_SAPI_PTCCH, arfcn, fn, block_nr, data, data_len);
}

void pcu_l1if_tx_agch(struct gprs_rlcmac_bts *bts, bitvec *block, int plen)
{
	uint8_t data[GSM_MACBLOCK_LEN]; /* prefix PLEN */

	/* FIXME: why does OpenBTS has no PLEN and no fill in message? */
	bitvec_pack(block, data + 1);
	data[0] = (plen << 2) | 0x01;

	if (the_pcu->gsmtap_categ_mask & (1 << PCU_GSMTAP_C_DL_AGCH))
		gsmtap_send(the_pcu->gsmtap, 0, 0, GSMTAP_CHANNEL_AGCH, 0, 0, 0, 0, data, GSM_MACBLOCK_LEN);

	pcu_tx_data_req(bts, 0, 0, PCU_IF_SAPI_AGCH, 0, 0, 0, data, sizeof(data));
}

#define IMSI_DIGITS_FOR_PAGING 3
void pcu_l1if_tx_pch(struct gprs_rlcmac_bts *bts, bitvec *block, int plen, const char *imsi)
{
	uint8_t data[IMSI_DIGITS_FOR_PAGING + GSM_MACBLOCK_LEN];

	/* prepend last three IMSI digits (if present) from which BTS/BSC will calculate the paging group */
	if (imsi && strlen(imsi) >= IMSI_DIGITS_FOR_PAGING)
		memcpy(data, imsi + strlen(imsi) - IMSI_DIGITS_FOR_PAGING, IMSI_DIGITS_FOR_PAGING);
	else
		memset(data, '0', IMSI_DIGITS_FOR_PAGING);

	/* block provided by upper layer comes without first byte (plen),
	 * prepend it manually:
	 */
	OSMO_ASSERT(sizeof(data) >= IMSI_DIGITS_FOR_PAGING + 1 + block->data_len);
	data[3] = (plen << 2) | 0x01;
	bitvec_pack(block, data + IMSI_DIGITS_FOR_PAGING + 1);

	if (the_pcu->gsmtap_categ_mask & (1 << PCU_GSMTAP_C_DL_PCH))
		gsmtap_send(the_pcu->gsmtap, 0, 0, GSMTAP_CHANNEL_PCH, 0, 0, 0, 0, data + 3, GSM_MACBLOCK_LEN);

	pcu_tx_data_req(bts, 0, 0, PCU_IF_SAPI_PCH, 0, 0, 0, data, sizeof(data));
}

/* Send a block via the paging channel and require a confirmation by the receiving end */
void pcu_l1if_tx_pch_dt(struct gprs_rlcmac_bts *bts, bitvec *block, int plen, const char *imsi, uint32_t tlli)
{
	/* NOTE: This is in practice only used to transmit IMMEDIATE ASSIGNMENT messages through the paging channel and
	 * it is not guaranteed to work with other message types. The prepended TLLI will be used as an identifier in
	 * the confirmation message. */

	struct gsm_pcu_if_pch_dt pch_dt = { 0 };

	pch_dt.tlli = tlli;
	if (imsi)
		OSMO_STRLCPY_ARRAY(pch_dt.imsi, imsi);

	pch_dt.data[0] = (plen << 2) | 0x01;
	bitvec_pack(block, pch_dt.data + 1);

	pcu_tx_data_req(bts, 0, 0, PCU_IF_SAPI_PCH_DT, 0, 0, 0, (uint8_t*)&pch_dt, sizeof(pch_dt));
}

int pcu_tx_neigh_addr_res_req(struct gprs_rlcmac_bts *bts, const struct neigh_cache_entry_key *neigh_key)
{
	struct msgb *msg;
	struct gsm_pcu_if *pcu_prim;
	struct gsm_pcu_if_neigh_addr_req *naddr_req;

	LOGP(DL1IF, LOGL_DEBUG, "(bts=%u) Tx Neighbor Address Resolution Request: " NEIGH_CACHE_ENTRY_KEY_FMT "\n",
	     bts->nr, NEIGH_CACHE_ENTRY_KEY_ARGS(neigh_key));

	msg = pcu_msgb_alloc_ext_size(PCU_IF_MSG_CONTAINER, bts->nr, sizeof(struct gsm_pcu_if_neigh_addr_req));
	if (!msg)
		return -ENOMEM;
	pcu_prim = (struct gsm_pcu_if *) msgb_data(msg);
	naddr_req = (struct gsm_pcu_if_neigh_addr_req *)&pcu_prim->u.container.data[0];

	msgb_put(msg, sizeof(pcu_prim->u.container) + sizeof(struct gsm_pcu_if_neigh_addr_req));
	pcu_prim->u.container.msg_type = PCU_IF_MSG_NEIGH_ADDR_REQ;
	osmo_store16be(sizeof(struct gsm_pcu_if_neigh_addr_req), &pcu_prim->u.container.length);

	osmo_store16be(neigh_key->local_lac, &naddr_req->local_lac);
	osmo_store16be(neigh_key->local_ci, &naddr_req->local_ci);
	osmo_store16be(neigh_key->tgt_arfcn, &naddr_req->tgt_arfcn);
	naddr_req->tgt_bsic = neigh_key->tgt_bsic;

	return pcu_sock_send(msg);
}

void pcu_rx_block_time(struct gprs_rlcmac_bts *bts, uint16_t arfcn, uint32_t fn, uint8_t ts_no)
{
	bts_set_current_block_frame_number(bts, fn);
}

int pcu_rx_data_ind_pdtch(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_pdch *pdch, uint8_t *data,
	uint8_t len, uint32_t fn, struct pcu_l1_meas *meas)
{
	int rc;

	if (!pdch->is_enabled()) {
		LOGPDCH(pdch, DL1IF, LOGL_INFO, "Received DATA.ind (PDTCH) on disabled TS\n");
		return -EINVAL;
	}

	rc = pdch->rcv_block(data, len, fn, meas);
	pdch_ulc_expire_fn(pdch->ulc, fn);
	return rc;
}

static int list_arfcn(const struct gprs_rlcmac_bts *bts, const struct gsm_sysinfo_freq *freq, const char *text)
{
	int n = 0, i;
	for (i = 0; i < 1024; i++) {
		if (freq[i].mask) {
			if (!n)
				LOGP(DL1IF, LOGL_INFO, "BTS%d: %s", bts->nr, text);
			LOGPC(DL1IF, LOGL_INFO, " %d", i);
			n++;
		}
	}
	if (n)
		LOGPC(DL1IF, LOGL_INFO, "\n");

	return n;
}

static int pcu_rx_data_ind_bcch(struct gprs_rlcmac_bts *bts, uint8_t *data, uint8_t len)
{
	struct gsm48_system_information_type_2 *si2;
	const uint8_t *si_ro;

	switch (len) {
	case 0:
		/* Due to historical reasons also accept a completely empty message as
		 * revoke command for SI13. */
		LOGP(DL1IF, LOGL_ERROR,
		     "Received PCU data indication that contains no data -- Revoked SI13.\n");
		bts->si13_is_set = false;

		return 0;
	case 1:
		/* Revoke SI, type is identified by a single byte which is coded after
		 * enum osmo_sysinfo_type. */
		switch (data[0]) {
		case SYSINFO_TYPE_1:
			bts->si1_is_set = false;
			break;
		case SYSINFO_TYPE_2:
			bts->si2_is_set = false;
			break;
		case SYSINFO_TYPE_3:
			bts->si3_is_set = false;
			break;
		case SYSINFO_TYPE_13:
			bts->si13_is_set = false;
			break;
		default:
			LOGP(DL1IF, LOGL_ERROR,
			     "Received PCU data indication that contains an unsupported system information identifier (%02x,OSMO) -- ignored.\n", data[0]);
			return -EINVAL;
		}
		LOGP(DPCU, LOGL_DEBUG,
		     "Received PCU data indication: Revoked SI%s\n",
		     get_value_string(osmo_sitype_strs, data[0]));
		return 0;
	case GSM_MACBLOCK_LEN:
		/* Update SI, type is identified by the RR sysinfo type, which is the
		 * 3rd byte in the buffer. */
		switch (data[2]) {
		case GSM48_MT_RR_SYSINFO_1:
			memcpy(bts->si1, data, GSM_MACBLOCK_LEN);
			bts->si1_is_set = true;
			break;
		case GSM48_MT_RR_SYSINFO_2:
			memcpy(bts->si2, data, GSM_MACBLOCK_LEN);
			bts->si2_is_set = true;
			si2 = (struct gsm48_system_information_type_2 *)bts->si2;
			gsm48_decode_freq_list(bts->si2_bcch_cell_list, si2->bcch_frequency_list,
					       sizeof(si2->bcch_frequency_list), 0xce, 1);
			list_arfcn(bts, bts->si2_bcch_cell_list, "SI2 Neighbour cells in same band:");
			break;
		case GSM48_MT_RR_SYSINFO_3:
			memcpy(bts->si3, data, GSM_MACBLOCK_LEN);
			bts->si3_is_set = true;
			break;
		case GSM48_MT_RR_SYSINFO_13:
			memcpy(bts->si13, data, GSM_MACBLOCK_LEN);
			bts->si13_is_set = true;
			si_ro = ((struct gsm48_system_information_type_13*)data)->rest_octets;
			if (osmo_gsm48_rest_octets_si13_decode(&bts->si13_ro_decoded, si_ro) < 0)
				LOGP(DPCU, LOGL_ERROR, "Error decoding SI13\n");
			break;
		default:
			LOGP(DL1IF, LOGL_ERROR,
			     "Received PCU data indication that contains an unsupported system information identifier (%02x,RR) -- ignored.\n", data[2]);
			return -EINVAL;
		}
		LOGP(DPCU, LOGL_DEBUG,
		     "Received PCU data indication: Updated %s: %s\n",
		     gsm48_pdisc_msgtype_name(data[1], data[2]),
		     osmo_hexdump_nospc(data + 1, GSM_MACBLOCK_LEN));
		return 0;
	default:
		LOGP(DL1IF, LOGL_ERROR,
		     "Received PCU data indication with unexpected data length: %u -- ignored.\n",
		     len);
		return -EINVAL;
	}
}

static int pcu_rx_data_ind(struct gprs_rlcmac_bts *bts, struct gsm_pcu_if_data *data_ind)
{
	int rc;
	int current_fn = bts_current_frame_number(bts);
	struct pcu_l1_meas meas = {0};
	struct gprs_rlcmac_pdch *pdch;
	uint8_t gsmtap_chantype;

	LOGP(DL1IF, LOGL_DEBUG, "(bts=%" PRIu8 ",trx=%" PRIu8 ",ts=%" PRIu8 ") FN=%u "
		"Rx DATA.ind: sapi=%d arfcn=%d cur_fn=%d "
		"block=%d data=%s\n", bts->nr, data_ind->trx_nr, data_ind->ts_nr,
		data_ind->fn, data_ind->sapi, data_ind->arfcn, current_fn,
		data_ind->block_nr, osmo_hexdump(data_ind->data, data_ind->len));

	switch (data_ind->sapi) {
	case PCU_IF_SAPI_PDTCH:
		pdch = &bts->trx[data_ind->trx_nr].pdch[data_ind->ts_nr];
		pcu_l1_meas_set_rssi(&meas, data_ind->rssi);
		/* convert BER to % value */
		pcu_l1_meas_set_ber(&meas, data_ind->ber10k / 100);
		pcu_l1_meas_set_bto(&meas, data_ind->ta_offs_qbits);
		pcu_l1_meas_set_link_qual(&meas, data_ind->lqual_cb / 10);

		LOGPDCH(pdch, DL1IF, LOGL_DEBUG, "FN=%u Rx DATA.ind PDTCH: "
			"BER10k = %d, BTO = %d, Q = %d\n", data_ind->fn,
			data_ind->ber10k, data_ind->ta_offs_qbits, data_ind->lqual_cb);

		rc = pcu_rx_data_ind_pdtch(bts, pdch, data_ind->data, data_ind->len,
					   data_ind->fn, &meas);
		gsmtap_chantype = GSMTAP_CHANNEL_PDTCH;
		break;
	case PCU_IF_SAPI_BCCH:
		rc = pcu_rx_data_ind_bcch(bts, data_ind->data, data_ind->len);
		gsmtap_chantype = GSMTAP_CHANNEL_BCCH;
		break;
	default:
		LOGP(DL1IF, LOGL_ERROR, "(bts=%" PRIu8 ",trx=%" PRIu8 ",ts=%" PRIu8 ") "
		     "FN=%u Rx DATA.ind with unsupported sapi %d\n",
		     bts->nr, data_ind->trx_nr, data_ind->ts_nr, data_ind->fn, data_ind->sapi);
		rc = -EINVAL;
		gsmtap_chantype = GSMTAP_CHANNEL_UNKNOWN;
	}

	if (rc < 0 && (the_pcu->gsmtap_categ_mask & (1 <<PCU_GSMTAP_C_UL_UNKNOWN))) {
		gsmtap_send(the_pcu->gsmtap, data_ind->arfcn | GSMTAP_ARFCN_F_UPLINK, data_ind->ts_nr,
			    gsmtap_chantype, 0, data_ind->fn, meas.rssi, meas.link_qual, data_ind->data, data_ind->len);
	}

	return rc;
}

static int pcu_rx_data_cnf(struct gprs_rlcmac_bts *bts, struct gsm_pcu_if_data *data_cnf)
{
	int rc = 0;
	int current_fn = bts_current_frame_number(bts);

	LOGP(DL1IF, LOGL_DEBUG, "Data confirm received: sapi=%d fn=%d cur_fn=%d\n",
		data_cnf->sapi, data_cnf->fn, current_fn);

	switch (data_cnf->sapi) {
	case PCU_IF_SAPI_PCH:
		if (data_cnf->data[2] == GSM48_MT_RR_IMM_ASS)
			bts_rcv_imm_ass_cnf(bts, data_cnf->data, GSM_RESERVED_TMSI, data_cnf->fn);
		break;
	default:
		LOGP(DL1IF, LOGL_ERROR, "Received PCU data confirm with "
			"unsupported sapi %d\n", data_cnf->sapi);
		rc = -EINVAL;
	}

	return rc;
}

static int pcu_rx_data_cnf_dt(struct gprs_rlcmac_bts *bts, struct gsm_pcu_if_data_cnf_dt *data_cnf_dt)
{
	int rc = 0;
	int current_fn = bts_current_frame_number(bts);

	LOGP(DL1IF, LOGL_DEBUG, "Data confirm received: sapi=%d fn=%d cur_fn=%d\n",
	     data_cnf_dt->sapi, data_cnf_dt->fn, current_fn);

	switch (data_cnf_dt->sapi) {
	case PCU_IF_SAPI_PCH:
		bts_rcv_imm_ass_cnf(bts, NULL, data_cnf_dt->tlli, data_cnf_dt->fn);
		break;
	default:
		LOGP(DL1IF, LOGL_ERROR, "Received PCU data confirm with unsupported sapi %d\n", data_cnf_dt->sapi);
		rc = -EINVAL;
	}

	return rc;
}

// FIXME: remove this, when changed from c++ to c.
int pcu_rx_rts_req_pdtch(struct gprs_rlcmac_bts *bts, uint8_t trx, uint8_t ts,
	uint32_t fn, uint8_t block_nr)
{
	return gprs_rlcmac_rcv_rts_block(bts,
					trx, ts, fn, block_nr);
}
int pcu_rx_rts_req_ptcch(struct gprs_rlcmac_bts *bts, uint8_t trx, uint8_t ts,
	uint32_t fn, uint8_t block_nr)
{
	struct gprs_rlcmac_pdch *pdch;

	/* Prevent buffer overflow */
	if (trx >= ARRAY_SIZE(bts->trx) || ts >= 8)
		return -EINVAL;

	/* Make sure PDCH time-slot is enabled */
	pdch = &bts->trx[trx].pdch[ts];
	if (!pdch_is_enabled(pdch))
		return -EAGAIN;

	/* If there's no TBF attached to this PDCH, we can skip Tx of PTCCH
	 * since there's nothing worthy of being transmitted. This way BTS can
	 * identify idle blocks and send nothing or dumy blocks with reduced
	 * energy for the sake of energy saving.
	 */
	const unsigned num_tbfs = pdch->num_tbfs(GPRS_RLCMAC_DL_TBF)
				+ pdch->num_tbfs(GPRS_RLCMAC_UL_TBF);
	bool skip_idle = (num_tbfs == 0);
#ifdef ENABLE_DIRECT_PHY
		/* In DIRECT_PHY mode we want to always submit something to L1 in
		 * TRX0, since BTS is not preparing dummy bursts on idle TS for us: */
		skip_idle = skip_idle && trx != 0;
#endif
	if (skip_idle) {
		pcu_l1if_tx_ptcch(bts, trx, ts, bts->trx[trx].arfcn, fn, block_nr,
				  NULL, 0);
		return 0;
	}

	pcu_l1if_tx_ptcch(bts, trx, ts, bts->trx[trx].arfcn, fn, block_nr,
			  pdch->ptcch_msg, GSM_MACBLOCK_LEN);
	return 0;
}

static int pcu_rx_rts_req(struct gprs_rlcmac_bts *bts, struct gsm_pcu_if_rts_req *rts_req)
{
	int rc = 0;
	int current_fn = bts_current_frame_number(bts);
	const struct gprs_rlcmac_pdch *pdch;
	pdch = &bts->trx[rts_req->trx_nr].pdch[rts_req->ts_nr];

	LOGPDCH(pdch, DL1IF, LOGL_DEBUG, "FN=%u RX RTS.req: sapi=%d "
		"arfcn=%d cur_fn=%d block=%d\n", rts_req->fn,
		rts_req->sapi, rts_req->arfcn, current_fn, rts_req->block_nr);

	switch (rts_req->sapi) {
	case PCU_IF_SAPI_PDTCH:
		pcu_rx_rts_req_pdtch(bts, rts_req->trx_nr, rts_req->ts_nr,
			rts_req->fn, rts_req->block_nr);
		break;
	case PCU_IF_SAPI_PTCCH:
		pcu_rx_rts_req_ptcch(bts, rts_req->trx_nr, rts_req->ts_nr,
			rts_req->fn, rts_req->block_nr);
		break;
	default:
		LOGP(DL1IF, LOGL_ERROR, "(bts=%u,trx=%u,ts=%u) FN=%u RX RTS.req with "
		     "unsupported sapi %d\n", bts->nr, rts_req->trx_nr, rts_req->ts_nr,
		     rts_req->fn, rts_req->sapi);
		rc = -EINVAL;
	}

	return rc;
}

/* C -> C++ adapter for direct PHY access code (e.g. osmo-bts-sysmo) */
extern "C" int pcu_rx_rach_ind_ptcch(struct gprs_rlcmac_bts *bts, uint8_t trx_nr, uint8_t ts_nr, uint32_t fn, int16_t qta)
{
	struct rach_ind_params rip = {
		/* The content of RA is not of interest on PTCCH/U */
		.burst_type = GSM_L1_BURST_TYPE_ACCESS_0,
		.is_11bit = false,
		.ra = 0x00,
		.trx_nr = trx_nr,
		.ts_nr = ts_nr,
		.rfn = fn,
		.qta = qta,
	};

	return bts_rcv_ptcch_rach(bts, &rip);
}

static int pcu_rx_rach_ind(struct gprs_rlcmac_bts *bts, const struct gsm_pcu_if_rach_ind *rach_ind)
{
	int rc = 0;
	int current_fn = bts_current_frame_number(bts);

	LOGP(DL1IF, LOGL_INFO, "RACH request received: sapi=%d "
		"qta=%d, ra=0x%02x, fn=%u, cur_fn=%d, is_11bit=%d\n", rach_ind->sapi, rach_ind->qta,
		rach_ind->ra, rach_ind->fn, current_fn, rach_ind->is_11bit);

	if (OSMO_UNLIKELY(rach_ind->fn > GSM_TDMA_HYPERFRAME - 1)) {
		LOGP(DL1IF, LOGL_ERROR, "RACH request contains fn=%u that exceeds valid limits (0-%u) -- ignored!\n",
		     rach_ind->fn,  GSM_TDMA_HYPERFRAME - 1);
			return -EINVAL;
	}

	struct rach_ind_params rip = {
		.burst_type = (enum ph_burst_type) rach_ind->burst_type,
		.is_11bit = rach_ind->is_11bit > 0,
		.ra = rach_ind->ra,
		.trx_nr = rach_ind->trx_nr,
		.ts_nr = rach_ind->ts_nr,
		.rfn = rach_ind->fn,
		.qta = rach_ind->qta,
	};

	switch (rach_ind->sapi) {
	case PCU_IF_SAPI_RACH:
		rc = bts_rcv_rach(bts, &rip);
		break;
	case PCU_IF_SAPI_PTCCH:
		rc = bts_rcv_ptcch_rach(bts, &rip);
		break;
	default:
		LOGP(DL1IF, LOGL_ERROR, "Received PCU rach request with "
			"unsupported sapi %d\n", rach_ind->sapi);
		rc = -EINVAL;
	}

	return rc;
}

static int pcu_info_ind_ns(struct gprs_rlcmac_bts *bts,
			   const struct gsm_pcu_if_info_ind *info_ind)
{
	struct osmo_sockaddr remote[PCU_IF_NUM_NSVC] = { };
	struct osmo_sockaddr local[PCU_IF_NUM_NSVC] = { };
	uint16_t nsvci[PCU_IF_NUM_NSVC] = { };
	uint16_t valid = 0;

	for (unsigned int i = 0; i < PCU_IF_NUM_NSVC; i++) {
		struct osmo_sockaddr_str sockstr;

		switch (info_ind->address_type[i]) {
		case PCU_IF_ADDR_TYPE_IPV4:
			local[i].u.sin.sin_family = AF_INET;
			local[i].u.sin.sin_addr.s_addr = INADDR_ANY;
			local[i].u.sin.sin_port = htons(info_ind->local_port[i]);

			remote[i].u.sin.sin_family = AF_INET;
			memcpy(&remote[i].u.sin.sin_addr, &info_ind->remote_ip[i].v4,
			       sizeof(struct in_addr));
			remote[i].u.sin.sin_port = htons(info_ind->remote_port[i]);
			break;
		case PCU_IF_ADDR_TYPE_IPV6:
			local[i].u.sin6.sin6_family = AF_INET6;
			local[i].u.sin6.sin6_addr = in6addr_any;
			local[i].u.sin6.sin6_port = htons(info_ind->local_port[i]);

			remote[i].u.sin6.sin6_family = AF_INET6;
			memcpy(&remote[i].u.sin6.sin6_addr,
			       &info_ind->remote_ip[i].v6,
			       sizeof(struct in6_addr));
			remote[i].u.sin6.sin6_port = htons(info_ind->remote_port[i]);
			break;
		default:
			continue;
		}
		nsvci[i] = info_ind->nsvci[i];

		LOGP(DL1IF, LOGL_DEBUG, " NS%u nsvci=%u\n", i, nsvci[i]);
		if (osmo_sockaddr_str_from_sockaddr(&sockstr, &remote[i].u.sas))
			strcpy(sockstr.ip, "invalid");

		LOGP(DL1IF, LOGL_DEBUG, " NS%u address: r=%s:%u<->l=NULL:%u\n",
		     i, sockstr.ip, sockstr.port, info_ind->local_port[i]);

		valid |= 1 << i;
	}

	if (valid == 0) {
		LOGP(DL1IF, LOGL_ERROR, "No NSVC available to connect to the SGSN!\n");
		return -EINVAL;
	}

	return gprs_ns_update_config(bts, info_ind->nsei, local, remote, nsvci, valid);
}

static int pcu_rx_info_ind(struct gprs_rlcmac_bts *bts, const struct gsm_pcu_if_info_ind *info_ind)
{
	struct gprs_bssgp_pcu *pcu;
	int rc = 0;
	unsigned int trx_nr, ts_nr;
	unsigned int i;

	if (llist_count(&the_pcu->bts_list) > 1)
		LOGP(DL1IF, LOGL_ERROR, "more than one BTS regsitered at this PCU. This PCU has only been tested with one BTS! OS#5930\n");

	LOGP(DL1IF, LOGL_DEBUG, "Info indication received:\n");

	/* NOTE: The classic way to confirm an IMMEDIATE assignment is to send the whole MAC block payload back to the
	 * PCU. So it is the MAC block itsself that serves a reference for the confirmation. This method has certain
	 * disadvantages so it was replaced with a method that uses the TLLI as a reference ("Direct TLLI"). This new
	 * method will replace the old one. The code that handles the old method will be removed in the foreseeable
	 * future. (see also OS#5927) */
	if (info_ind->version == 0x0a) {
		LOGP(DL1IF, LOGL_NOTICE, "PCUIF version 10 is deprecated. OS#5927\n");
	} else if (info_ind->version != PCU_IF_VERSION) {
		fprintf(stderr, "PCU interface version number of BTS/BSC (%u) is different (%u).\nPlease use a BTS/BSC with a compatble interface!\n",
			info_ind->version, PCU_IF_VERSION);
		exit(-1);
	}

	the_pcu->pcu_if_version = info_ind->version;

	if (!(info_ind->flags & PCU_IF_FLAG_ACTIVE)) {
		LOGP(DL1IF, LOGL_NOTICE, "BTS not available\n");
		if (!bts->active)
			return -EAGAIN;
bssgp_failed:
		bts->active = false;
		/* free all TBF */
		for (trx_nr = 0; trx_nr < ARRAY_SIZE(bts->trx); trx_nr++) {
			bts->trx[trx_nr].arfcn = info_ind->trx[trx_nr].arfcn;
			for (ts_nr = 0; ts_nr < ARRAY_SIZE(bts->trx[0].pdch); ts_nr++)
				if (bts->trx[trx_nr].pdch[ts_nr].is_enabled())
					bts->trx[trx_nr].pdch[ts_nr].disable();
		}
		gprs_bssgp_destroy(bts);
		exit(0);
	}
	LOGP(DL1IF, LOGL_INFO, "BTS available\n");
	LOGP(DL1IF, LOGL_DEBUG, " mcc=%03u\n", info_ind->mcc);
	LOGP(DL1IF, LOGL_DEBUG, " mnc=%0*u\n", info_ind->mnc_3_digits, info_ind->mnc);
	LOGP(DL1IF, LOGL_DEBUG, " lac=%d\n", info_ind->lac);
	LOGP(DL1IF, LOGL_DEBUG, " rac=%d\n", info_ind->rac);
	LOGP(DL1IF, LOGL_DEBUG, " cell_id=%d\n", info_ind->cell_id);
	LOGP(DL1IF, LOGL_DEBUG, " bsic=%d\n", info_ind->bsic);
	LOGP(DL1IF, LOGL_DEBUG, " nsei=%d\n", info_ind->nsei);
	LOGP(DL1IF, LOGL_DEBUG, " nse_timer=%d %d %d %d %d %d %d\n",
		info_ind->nse_timer[0], info_ind->nse_timer[1],
		info_ind->nse_timer[2], info_ind->nse_timer[3],
		info_ind->nse_timer[4], info_ind->nse_timer[5],
		info_ind->nse_timer[6]);
	LOGP(DL1IF, LOGL_DEBUG, " cell_timer=%d %d %d %d %d %d %d %d %d %d "
		"%d\n",
		info_ind->cell_timer[0], info_ind->cell_timer[1],
		info_ind->cell_timer[2], info_ind->cell_timer[3],
		info_ind->cell_timer[4], info_ind->cell_timer[5],
		info_ind->cell_timer[6], info_ind->cell_timer[7],
		info_ind->cell_timer[8], info_ind->cell_timer[9],
		info_ind->cell_timer[10]);
	LOGP(DL1IF, LOGL_DEBUG, " repeat_time=%d\n", info_ind->repeat_time);
	LOGP(DL1IF, LOGL_DEBUG, " repeat_count=%d\n", info_ind->repeat_count);
	LOGP(DL1IF, LOGL_DEBUG, " bvci=%d\n", info_ind->bvci);
	LOGP(DL1IF, LOGL_DEBUG, " t3142=%d\n", info_ind->t3142);
	LOGP(DL1IF, LOGL_DEBUG, " t3169=%d\n", info_ind->t3169);
	LOGP(DL1IF, LOGL_DEBUG, " t3191=%d\n", info_ind->t3191);
	LOGP(DL1IF, LOGL_DEBUG, " t3193=%d (ms)\n", info_ind->t3193_10ms * 10);
	LOGP(DL1IF, LOGL_DEBUG, " t3195=%d\n", info_ind->t3195);
	LOGP(DL1IF, LOGL_DEBUG, " n3101=%d\n", info_ind->n3101);
	LOGP(DL1IF, LOGL_DEBUG, " n3103=%d\n", info_ind->n3103);
	LOGP(DL1IF, LOGL_DEBUG, " n3105=%d\n", info_ind->n3105);
	LOGP(DL1IF, LOGL_DEBUG, " cv_countdown=%d\n", info_ind->cv_countdown);
	LOGP(DL1IF, LOGL_DEBUG, " dl_tbf_ext=%d\n", info_ind->dl_tbf_ext);
	LOGP(DL1IF, LOGL_DEBUG, " ul_tbf_ext=%d\n", info_ind->ul_tbf_ext);
	bts->cgi_ps.rai.lac.plmn.mcc = info_ind->mcc;
	bts->cgi_ps.rai.lac.plmn.mnc = info_ind->mnc;
	bts->cgi_ps.rai.lac.plmn.mnc_3_digits = info_ind->mnc_3_digits;
	bts->cgi_ps.rai.lac.lac = info_ind->lac;
	bts->cgi_ps.rai.rac = info_ind->rac;
	bts->cgi_ps.cell_identity = info_ind->cell_id;
	bts->bsic = info_ind->bsic;

	bts->cs_mask = 1 << 0; /* We need at least 1 CS, let's enable CS1 */
	for (i = 0; i < 4; i++) {
		uint8_t allowed = !!(info_ind->flags & (PCU_IF_FLAG_CS1 << i));
		bts->cs_mask |= allowed << i;
		if (allowed)
			LOGP(DL1IF, LOGL_DEBUG, " Use CS%d\n",  i + 1);
	}
	bts_recalc_max_cs(bts);

	bts->mcs_mask = 0;
	for (i = 0; i < 9; i++) {
		uint8_t allowed = !!(info_ind->flags & (PCU_IF_FLAG_MCS1 << i));
		bts->mcs_mask |= allowed << i;
		if (allowed)
			LOGP(DL1IF, LOGL_DEBUG, " Use MCS%d\n", i + 1);

	}
	bts_recalc_max_mcs(bts);

	LOGP(DL1IF, LOGL_DEBUG, " initial_cs=%u%s\n", info_ind->initial_cs,
	     the_pcu->vty.force_initial_cs ? " (VTY forced, ignoring)" : "");
	bts->pcuif_info_ind.initial_cs = info_ind->initial_cs;
	bts_recalc_initial_cs(bts);

	LOGP(DL1IF, LOGL_DEBUG, " initial_mcs=%u%s\n", info_ind->initial_mcs,
	     the_pcu->vty.force_initial_mcs ? " (VTY forced, ignoring)" : "");
	bts->pcuif_info_ind.initial_mcs = info_ind->initial_mcs;
	bts_recalc_initial_mcs(bts);

	pcu = gprs_bssgp_init(
			bts,
			info_ind->nsei, info_ind->bvci,
			info_ind->mcc, info_ind->mnc, info_ind->mnc_3_digits,
			info_ind->lac, info_ind->rac, info_ind->cell_id);
	if (!pcu) {
		LOGP(DL1IF, LOGL_ERROR, "Failed to init BSSGP\n");
		goto bssgp_failed;
	}

	rc = pcu_info_ind_ns(pcu->bts, info_ind);
	if (rc < 0) {
		LOGP(DL1IF, LOGL_ERROR, "No NSVC available to connect to the SGSN!\n");
		goto bssgp_failed;
	}

	if (info_ind->t3142) { /* if timer values are set */
		osmo_tdef_set(bts->T_defs_bts, 3142, info_ind->t3142, OSMO_TDEF_S);
		osmo_tdef_set(bts->T_defs_bts, 3169, info_ind->t3169, OSMO_TDEF_S);
		osmo_tdef_set(bts->T_defs_bts, 3191, info_ind->t3191, OSMO_TDEF_S);
		osmo_tdef_set(bts->T_defs_bts, 3193, info_ind->t3193_10ms * 10, OSMO_TDEF_MS);
		osmo_tdef_set(bts->T_defs_bts, 3195, info_ind->t3195, OSMO_TDEF_S);
		bts->n3101 = info_ind->n3101;
		bts->n3103 = info_ind->n3103;
		bts->n3105 = info_ind->n3105;
	}

	for (trx_nr = 0; trx_nr < ARRAY_SIZE(bts->trx); trx_nr++) {
		bts->trx[trx_nr].arfcn = info_ind->trx[trx_nr].arfcn;
		if ((info_ind->flags & PCU_IF_FLAG_SYSMO)
		 && info_ind->trx[trx_nr].hlayer1) {
#ifdef ENABLE_DIRECT_PHY
			LOGP(DL1IF, LOGL_DEBUG, " TRX %d hlayer1=%x\n", trx_nr,
				info_ind->trx[trx_nr].hlayer1);
				if (!bts->trx[trx_nr].fl1h)
					bts->trx[trx_nr].fl1h = l1if_open_pdch(
						bts->nr, trx_nr,
						info_ind->trx[trx_nr].hlayer1,
						the_pcu->gsmtap);
			if (!bts->trx[trx_nr].fl1h) {
				LOGP(DL1IF, LOGL_FATAL, "Failed to open direct "
					"PHY access for PDCH.\n");
				exit(0);
			}
#else
			LOGP(DL1IF, LOGL_FATAL, "Compiled without direct PHY "
					"access for PDCH, but enabled at "
					"BTS. Please deactivate it!\n");
			exit(0);
#endif
		}

		for (ts_nr = 0; ts_nr < ARRAY_SIZE(bts->trx[0].pdch); ts_nr++) {
			const struct gsm_pcu_if_info_trx_ts *its = &info_ind->trx[trx_nr].ts[ts_nr];
			struct gprs_rlcmac_pdch *pdch = &bts->trx[trx_nr].pdch[ts_nr];
			if ((info_ind->trx[trx_nr].pdch_mask & (1 << ts_nr))) {
				/* FIXME: activate dynamically at RLCMAC */
				if (!pdch->is_enabled()) {
#ifdef ENABLE_DIRECT_PHY
					if ((info_ind->flags &
							PCU_IF_FLAG_SYSMO))
						l1if_connect_pdch(
							bts->trx[trx_nr].fl1h, ts_nr);
#endif
					pcu_tx_act_req(bts, pdch, 1);
					pdch->enable();
				}

				pdch->tsc = its->tsc;

				/* (Optional) frequency hopping parameters */
				if (its->hopping) {
					pdch->fh.enabled = true;
					pdch->fh.maio    = its->maio;
					pdch->fh.hsn     = its->hsn;

					OSMO_ASSERT(its->ma_bit_len <= sizeof(pdch->fh.ma) * 8);
					pdch->fh.ma_oct_len = OSMO_BYTES_FOR_BITS(its->ma_bit_len);
					pdch->fh.ma_bit_len = its->ma_bit_len;

					/* Mobile Allocation + padding (byte/bit order as on the wire):
					 * | 00 00 00 00 00 cc bb aa | -> | cc bb aa 00 00 00 00 00 | */
					unsigned int offset = sizeof(pdch->fh.ma) - pdch->fh.ma_oct_len;
					memcpy(pdch->fh.ma, its->ma + offset, pdch->fh.ma_oct_len);
				}

				LOGP(DL1IF, LOGL_INFO, "PDCH (trx=%u, ts=%u): tsc=%u, hopping=%s\n",
				     trx_nr, ts_nr, pdch->tsc, pdch->fh.enabled ? "yes" : "no");
			} else {
				if (pdch->is_enabled()) {
#ifdef ENABLE_DIRECT_PHY
					if ((info_ind->flags & PCU_IF_FLAG_SYSMO))
						l1if_disconnect_pdch(bts->trx[trx_nr].fl1h, ts_nr);
#endif
					pcu_tx_act_req(bts, pdch, 0);
					pdch->disable();
				}
			}
		}
	}

	bts->active = true;
	return rc;
}

/* Query E1 CCU connection parameters by TS and TRX number */
int pcu_l1if_get_e1_ccu_conn_pars(struct e1_conn_pars **e1_conn_pars, uint8_t bts_nr, uint8_t trx_nr, uint8_t ts_nr)
{
	struct e1_ccu_conn_pars *e1_ccu_conn_pars;

	llist_for_each_entry(e1_ccu_conn_pars, &e1_ccu_table, entry) {
		if (e1_ccu_conn_pars->bts_nr == bts_nr && e1_ccu_conn_pars->trx_nr == trx_nr
		    && e1_ccu_conn_pars->ts_nr == ts_nr) {
			*e1_conn_pars = &e1_ccu_conn_pars->e1_conn_pars;
			return 0;
		}
	}

	return -EINVAL;
}

/* Allocate a new connection parameter struct and store connection parameters */
static void new_e1_ccu_conn_pars(const struct gsm_pcu_if_e1_ccu_ind *e1_ccu_ind, uint8_t bts_nr)
{
	struct e1_ccu_conn_pars *e1_ccu_conn_pars;

	e1_ccu_conn_pars = talloc_zero(tall_pcu_ctx, struct e1_ccu_conn_pars);
	OSMO_ASSERT(e1_ccu_conn_pars);
	e1_ccu_conn_pars->bts_nr = bts_nr;
	e1_ccu_conn_pars->trx_nr = e1_ccu_ind->trx_nr;
	e1_ccu_conn_pars->ts_nr = e1_ccu_ind->ts_nr;
	e1_ccu_conn_pars->e1_conn_pars.e1_nr = e1_ccu_ind->e1_nr;
	e1_ccu_conn_pars->e1_conn_pars.e1_ts = e1_ccu_ind->e1_ts;
	e1_ccu_conn_pars->e1_conn_pars.e1_ts_ss = e1_ccu_ind->e1_ts_ss;
	llist_add(&e1_ccu_conn_pars->entry, &e1_ccu_table);
}

static int pcu_rx_e1_ccu_ind(struct gprs_rlcmac_bts *bts, const struct gsm_pcu_if_e1_ccu_ind *e1_ccu_ind)
{
	struct e1_conn_pars *e1_conn_pars;
	uint8_t rate;
	uint8_t subslot_nr;
	int rc;

	/* only used with log statement below, no technical relevance otherwise. */
	if (e1_ccu_ind->e1_ts_ss > 3) {
		rate = 64;
		subslot_nr = 0;
	} else {
		rate = 16;
		subslot_nr = e1_ccu_ind->e1_ts_ss;
	}

	LOGP(DL1IF, LOGL_NOTICE,
	     "(ts=%u,trx=%u) new E1 CCU communication parameters for CCU (E1-line:%u, E1-TS:%u, E1-SS:%u, rate:%ukbps)\n",
	     e1_ccu_ind->ts_nr, e1_ccu_ind->trx_nr, e1_ccu_ind->e1_nr, e1_ccu_ind->e1_ts,
	     subslot_nr, rate);

	/* Search for an existing entry, when found, update it. */
	rc = pcu_l1if_get_e1_ccu_conn_pars(&e1_conn_pars, bts->nr, e1_ccu_ind->trx_nr, e1_ccu_ind->ts_nr);
	if (rc == 0) {
		e1_conn_pars->e1_nr = e1_ccu_ind->e1_nr;
		e1_conn_pars->e1_ts = e1_ccu_ind->e1_ts;
		e1_conn_pars->e1_ts_ss = e1_ccu_ind->e1_ts_ss;
		return 0;
	}

	/* Create new connection parameter entry */
	new_e1_ccu_conn_pars(e1_ccu_ind, bts->nr);
	return 0;
}

static int pcu_rx_time_ind(struct gprs_rlcmac_bts *bts, struct gsm_pcu_if_time_ind *time_ind)
{
	uint8_t fn13 = time_ind->fn % 13;

	/* omit frame numbers not starting at a MAC block */
	if (fn13 != 0 && fn13 != 4 && fn13 != 8)
		return 0;

	LOGP(DL1IF, LOGL_DEBUG, "Time indication received: %d\n", time_ind->fn % 52);

	/* Ignore TIME.ind completely, we nowadays relay on DATA.ind always
	 * providing all block FNs. */
	return 0;
}

static int pcu_rx_pag_req(struct gprs_rlcmac_bts *bts, struct gsm_pcu_if_pag_req *pag_req)
{
	struct osmo_mobile_identity mi;
	struct GprsMs *ms = NULL;
	struct paging_req_cs req = { .chan_needed = pag_req->chan_needed,
				     .tlli = GSM_RESERVED_TMSI };
	int rc;

	LOGP(DL1IF, LOGL_DEBUG, "Paging request received: chan_needed=%d "
		"length=%d\n", pag_req->chan_needed, pag_req->identity_lv[0]);

	/* check if identity does not fit: length > sizeof(lv) - 1 */
	if (pag_req->identity_lv[0] >= sizeof(pag_req->identity_lv)) {
		LOGP(DL1IF, LOGL_ERROR, "Paging identity too large (%" PRIu8 ")\n",
			pag_req->identity_lv[0]);
		return -EINVAL;
	}

	rc = osmo_mobile_identity_decode(&mi, &pag_req->identity_lv[1], pag_req->identity_lv[0], true);
	if (rc < 0) {
		LOGP(DL1IF, LOGL_ERROR, "Failed to decode Mobile Identity in Paging Request (rc=%d)\n", rc);
		return -EINVAL;
	}

	switch (mi.type) {
	case GSM_MI_TYPE_TMSI:
		req.mi_tmsi = mi;
		req.mi_tmsi_present = true;
		/* TODO: look up MS by TMSI? Derive TLLI? */
		break;
	case GSM_MI_TYPE_IMSI:
		req.mi_imsi = mi;
		req.mi_imsi_present = true;
		ms = bts_ms_by_imsi(bts, req.mi_imsi.imsi);
		break;
	default:
		LOGP(DL1IF, LOGL_ERROR, "Unexpected MI type %u\n", mi.type);
		return -EINVAL;
	}

	return bts_add_paging(bts, &req, ms);
}

static int pcu_rx_susp_req(struct gprs_rlcmac_bts *bts, struct gsm_pcu_if_susp_req *susp_req)
{
	struct bssgp_bvc_ctx *bctx = the_pcu->bssgp.bctx;
	GprsMs *ms;
	struct gprs_rlcmac_dl_tbf *dl_tbf;
	struct gprs_rlcmac_ul_tbf *ul_tbf;
	struct gprs_ra_id ra_id;

	gsm48_parse_ra(&ra_id, susp_req->ra_id);

	LOGP(DL1IF, LOGL_INFO, "GPRS Suspend request received: TLLI=0x%08x RAI=%s\n",
		susp_req->tlli, osmo_rai_name(&ra_id));

	if ((ms = bts_ms_store(bts)->get_ms(susp_req->tlli))) {
		/* We need to catch both pointers here since MS may become freed
		   after first tbf_free(dl_tbf) if only DL TBF was available */
		dl_tbf = ms_dl_tbf(ms);
		ul_tbf = ms_ul_tbf(ms);
		if (dl_tbf)
			tbf_free(dl_tbf);
		if (ul_tbf)
			tbf_free(ul_tbf);
	}

	if (!bctx)
		return -1;

	return bssgp_tx_suspend(bctx->nsei, susp_req->tlli, &ra_id);
}

static int pcu_rx_app_info_req(struct gprs_rlcmac_bts *bts, struct gsm_pcu_if_app_info_req *app_info_req)
{
	struct llist_head *tmp;

	LOGP(DL1IF, LOGL_DEBUG, "Application Information Request received: type=0x%08x len=%i\n",
	     app_info_req->application_type, app_info_req->len);

	bts->app_info_pending = 0;
	llist_for_each(tmp, bts_ms_store(bts)->ms_list()) {
		GprsMs *ms = llist_entry(tmp, typeof(*ms), list);
		if (!ms_dl_tbf(ms))
			continue;
		bts->app_info_pending++;
		ms->app_info_pending = true;
	}

	if (!bts->app_info_pending) {
		LOGP(DL1IF, LOGL_NOTICE, "Packet Application Information will not be sent, no subscribers with active"
		     " TBF\n");
		return -1;
	}

	if (bts->app_info) {
		LOGP(DL1IF, LOGL_NOTICE, "Previous Packet Application Information was not sent to all subscribers,"
		     " overwriting with new one\n");
		msgb_free(bts->app_info);
	}

	LOGP(DL1IF, LOGL_INFO, "Sending Packet Application Information to %i subscribers with active TBF\n",
	     bts->app_info_pending);
	bts->app_info = gprs_rlcmac_app_info_msg(app_info_req);
	return 0;
}

static int pcu_rx_neigh_addr_cnf(struct gprs_rlcmac_bts *bts, struct gsm_pcu_if_neigh_addr_cnf *naddr_cnf)
{
	struct llist_head *tmp;
	struct osmo_cell_global_id_ps cgi_ps;
	struct osmo_cell_global_id_ps *cgi_ps_ptr = &cgi_ps;

	struct neigh_cache_entry_key neigh_key = {
		.local_lac = osmo_load16be(&naddr_cnf->orig_req.local_lac),
		.local_ci = osmo_load16be(&naddr_cnf->orig_req.local_ci),
		.tgt_arfcn = osmo_load16be(&naddr_cnf->orig_req.tgt_arfcn),
		.tgt_bsic = naddr_cnf->orig_req.tgt_bsic,
	};

	if (naddr_cnf->err_code == 0) {
		cgi_ps.rai.lac.plmn.mcc = osmo_load16be(&naddr_cnf->cgi_ps.mcc);
		cgi_ps.rai.lac.plmn.mnc = osmo_load16be(&naddr_cnf->cgi_ps.mnc);
		cgi_ps.rai.lac.plmn.mnc_3_digits = naddr_cnf->cgi_ps.mnc_3_digits;
		cgi_ps.rai.lac.lac = osmo_load16be(&naddr_cnf->cgi_ps.lac);
		cgi_ps.rai.rac = naddr_cnf->cgi_ps.rac;
		cgi_ps.cell_identity = osmo_load16be(&naddr_cnf->cgi_ps.cell_identity);

		LOGP(DL1IF, LOGL_INFO, "Rx Neighbor Address Resolution Confirmation for " NEIGH_CACHE_ENTRY_KEY_FMT ": %s\n",
		     NEIGH_CACHE_ENTRY_KEY_ARGS(&neigh_key), osmo_cgi_ps_name(&cgi_ps));

		/* Cache the cgi_ps so we can avoid requesting again same resolution for a while */
		neigh_cache_add(bts->pcu->neigh_cache, &neigh_key, &cgi_ps);
	} else {
		cgi_ps_ptr = NULL;
		LOGP(DL1IF, LOGL_INFO, "Rx Neighbor Address Resolution Confirmation for " NEIGH_CACHE_ENTRY_KEY_FMT ": failed with err_code=%u\n",
		     NEIGH_CACHE_ENTRY_KEY_ARGS(&neigh_key), naddr_cnf->err_code);
	}

	llist_for_each(tmp, bts_ms_store(bts)->ms_list()) {
		GprsMs *ms = llist_entry(tmp, typeof(*ms), list);
		if (ms->nacc && nacc_fsm_is_waiting_addr_resolution(ms->nacc, &neigh_key))
			osmo_fsm_inst_dispatch(ms->nacc->fi, NACC_EV_RX_RAC_CI, cgi_ps_ptr);
	}
	return 0;
}

static int pcu_rx_container(struct gprs_rlcmac_bts *bts, struct gsm_pcu_if_container *container)
{
	int rc;
	uint16_t data_length = osmo_load16be(&container->length);

	switch (container->msg_type) {
	case PCU_IF_MSG_NEIGH_ADDR_CNF:
		if (data_length < sizeof(struct gsm_pcu_if_neigh_addr_cnf)) {
			LOGP(DL1IF, LOGL_ERROR, "Rx container(NEIGH_ADDR_CNF) message too short: %u vs exp %zu\n",
			     data_length, sizeof(struct gsm_pcu_if_neigh_addr_cnf));
			return -EINVAL;
		}
		rc = pcu_rx_neigh_addr_cnf(bts, (struct gsm_pcu_if_neigh_addr_cnf*)&container->data);
		break;
	default:
		LOGP(DL1IF, LOGL_NOTICE, "(bts=%d) Rx unexpected msg type (%u) inside container!\n",
		     bts->nr, container->msg_type);
		rc = -1;
	}
	return rc;
}

#define CHECK_IF_MSG_SIZE(prim_len, prim_msg) \
	do { \
		size_t _len = PCUIF_HDR_SIZE + sizeof(prim_msg); \
		if (prim_len < _len) { \
			LOGP(DL1IF, LOGL_ERROR, "Received %zu bytes on PCU Socket, but primitive %s " \
			     "size is %zu, discarding\n", prim_len, #prim_msg, _len); \
			return -EINVAL; \
		} \
	} while(0);
int pcu_rx(struct gsm_pcu_if *pcu_prim, size_t pcu_prim_length)
{
	int rc = 0;
	size_t exp_len;
	struct gprs_rlcmac_bts *bts = gprs_pcu_get_bts_by_nr(the_pcu, pcu_prim->bts_nr);
	if (!bts) {
		LOGP(DL1IF, LOGL_NOTICE, "Received message for new BTS%d\n", pcu_prim->bts_nr);
		bts = bts_alloc(the_pcu, pcu_prim->bts_nr);
		if (!bts) {
			LOGP(DL1IF, LOGL_ERROR, "Failed to create object for BTS%d!\n", pcu_prim->bts_nr);
			return -EAGAIN;
		}
	}

	switch (pcu_prim->msg_type) {
	case PCU_IF_MSG_DATA_IND:
		CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.data_ind);
		rc = pcu_rx_data_ind(bts, &pcu_prim->u.data_ind);
		break;
	case PCU_IF_MSG_DATA_CNF:
		CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.data_cnf);
		rc = pcu_rx_data_cnf(bts, &pcu_prim->u.data_cnf);
		break;
	case PCU_IF_MSG_DATA_CNF_DT:
		CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.data_cnf_dt);
		rc = pcu_rx_data_cnf_dt(bts, &pcu_prim->u.data_cnf_dt);
		break;
	case PCU_IF_MSG_RTS_REQ:
		CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.rts_req);
		rc = pcu_rx_rts_req(bts, &pcu_prim->u.rts_req);
		break;
	case PCU_IF_MSG_RACH_IND:
		CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.rach_ind);
		rc = pcu_rx_rach_ind(bts, &pcu_prim->u.rach_ind);
		break;
	case PCU_IF_MSG_INFO_IND:
		CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.info_ind);
		rc = pcu_rx_info_ind(bts, &pcu_prim->u.info_ind);
		break;
	case PCU_IF_MSG_E1_CCU_IND:
		CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.e1_ccu_ind);
		rc = pcu_rx_e1_ccu_ind(bts, &pcu_prim->u.e1_ccu_ind);
		break;
	case PCU_IF_MSG_TIME_IND:
		CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.time_ind);
		rc = pcu_rx_time_ind(bts, &pcu_prim->u.time_ind);
		break;
	case PCU_IF_MSG_PAG_REQ:
		CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.pag_req);
		rc = pcu_rx_pag_req(bts, &pcu_prim->u.pag_req);
		break;
	case PCU_IF_MSG_SUSP_REQ:
		CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.susp_req);
		rc = pcu_rx_susp_req(bts, &pcu_prim->u.susp_req);
		break;
	case PCU_IF_MSG_APP_INFO_REQ:
		CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.app_info_req);
		rc = pcu_rx_app_info_req(bts, &pcu_prim->u.app_info_req);
		break;
	case PCU_IF_MSG_INTERF_IND:
		/* TODO: handle interference reports */
		break;
	case PCU_IF_MSG_CONTAINER:
		CHECK_IF_MSG_SIZE(pcu_prim_length, pcu_prim->u.container);
		/* ^ check if we can access container fields, v check with container data length */
		exp_len = PCUIF_HDR_SIZE + sizeof(pcu_prim->u.container) + osmo_load16be(&pcu_prim->u.container.length);
		if (pcu_prim_length < exp_len) {
			LOGP(DL1IF, LOGL_ERROR, "Received %zu bytes on PCU Socket, but primitive container size" \
			     "is %zu, discarding\n", pcu_prim_length, exp_len);
			rc = -EINVAL;
			break;
		}
		rc = pcu_rx_container(bts, &pcu_prim->u.container);
		break;
	default:
		LOGP(DL1IF, LOGL_ERROR, "Received unknown PCU msg type %d\n",
			pcu_prim->msg_type);
		rc = -EINVAL;
	}

	return rc;
}
