/*! \file gprs_bssgp.c
 * GPRS BSSGP protocol implementation as per 3GPP TS 08.18. */
/*
 * (C) 2009-2017 by Harald Welte <laforge@gnumonks.org>
 *
 * All Rights Reserved
 *
 * SPDX-License-Identifier: GPL-2.0+
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * TODO:
 *  o  properly count incoming BVC-RESET packets in counter group
 *  o  set log context as early as possible for outgoing packets
 */

#include <errno.h>
#include <stdint.h>

#include <osmocom/core/msgb.h>
#include <osmocom/core/byteswap.h>
#include <osmocom/core/bit16gen.h>
#include <osmocom/gsm/tlv.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/stats.h>

#include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/gprs/gprs_bssgp_bss.h>
#include <osmocom/gprs/gprs_ns.h>

#include "osmocom/gsm/gsm48.h"
#include "gprs_bssgp_internal.h"

void *bssgp_tall_ctx = NULL;

static int _gprs_ns_sendmsg(void *ctx, struct msgb *msg);

bssgp_bvc_send bssgp_ns_send = _gprs_ns_sendmsg;
void *bssgp_ns_send_data = NULL;

static const struct rate_ctr_desc bssgp_ctr_description[] = {
	{ "packets:in",	"Packets at BSSGP Level ( In)" },
	{ "packets:out","Packets at BSSGP Level (Out)" },
	{ "bytes:in",	"Bytes at BSSGP Level   ( In)" },
	{ "bytes:out",	"Bytes at BSSGP Level   (Out)" },
	{ "blocked",	"BVC Blocking count" },
	{ "discarded",	"BVC LLC Discarded count" },
	{ "status",	"BVC Status count" },
};

static const struct rate_ctr_group_desc bssgp_ctrg_desc = {
	.group_name_prefix = "bssgp:bss_ctx",
	.group_description = "BSSGP Peer Statistics",
	.num_ctr = ARRAY_SIZE(bssgp_ctr_description),
	.ctr_desc = bssgp_ctr_description,
	.class_id = OSMO_STATS_CLASS_PEER,
};

LLIST_HEAD(bssgp_bvc_ctxts);

static int _bssgp_tx_dl_ud(struct bssgp_flow_control *fc, struct msgb *msg,
			   uint32_t llc_pdu_len, void *priv);


/* callback to be backward compatible with old users which do not set the bssgp_ns_send function */
static int _gprs_ns_sendmsg(void *ctx, struct msgb *msg)
{
	OSMO_ASSERT(bssgp_nsi);
	return gprs_ns_sendmsg(bssgp_nsi, msg);
}

/* Find a BTS Context based on parsed RA ID and Cell ID */
struct bssgp_bvc_ctx *btsctx_by_raid_cid(const struct gprs_ra_id *raid, uint16_t cid)
{
	struct bssgp_bvc_ctx *bctx;

	llist_for_each_entry(bctx, &bssgp_bvc_ctxts, list) {
		if (!memcmp(&bctx->ra_id, raid, sizeof(bctx->ra_id)) &&
		    bctx->cell_id == cid)
			return bctx;
	}
	return NULL;
}

/* Transmit a BVC-RESET or BVC-RESET-ACK with a given nsei and bvci (Chapter 10.4.12)
 *  \param[in] pdu Either BSSGP_PDUT_BVC_RESET or BSSGP_PDUT_BVC_RESET_ACK
 *  \param[in] nsei The NSEI to transmit over
 *  \param[in] bvci BVCI of the BVC to reset
 *  \param[in] cause The cause of the reset only valid for BSSGP_PDUT_BVC_RESET.
 *  \param[in] ra_id Pointer to the ra_id to include. If NULL no cell information will be included
 *  \param[in] cell_id The cell_id to include (if ra_id is not NULL)
 *  returns >= 0 on success, on error < 0.
 */
static int tx_bvc_reset_nsei_bvci(enum bssgp_pdu_type pdu, uint16_t nsei, uint16_t bvci,
				  enum gprs_bssgp_cause cause, const struct gprs_ra_id *ra_id, uint16_t cell_id)
{
	struct msgb *msg = bssgp_msgb_alloc();
	struct bssgp_normal_hdr *bgph =
		(struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
	uint16_t _bvci = osmo_htons(bvci);

	OSMO_ASSERT(pdu == BSSGP_PDUT_BVC_RESET || pdu == BSSGP_PDUT_BVC_RESET_ACK);

	msgb_nsei(msg) = nsei;
	msgb_bvci(msg) = BVCI_SIGNALLING;
	bgph->pdu_type = pdu;

	msgb_tvlv_put(msg, BSSGP_IE_BVCI, 2, (uint8_t *) &_bvci);

	if (pdu == BSSGP_PDUT_BVC_RESET) {
		msgb_tvlv_put(msg, BSSGP_IE_CAUSE, 1, (uint8_t *) &cause);
		LOGP(DLBSSGP, LOGL_NOTICE, "BSSGP (BVCI=%u) Tx BVC-RESET "
			"CAUSE=%s\n", bvci, bssgp_cause_str(cause));
	} else {
		LOGP(DLBSSGP, LOGL_NOTICE, "BSSGP (BVCI=%u) Tx BVC-RESET-ACK\n", bvci);
	}

	if (ra_id) {
		uint8_t bssgp_cid[8];
		bssgp_create_cell_id(bssgp_cid, ra_id, cell_id);
		msgb_tvlv_put(msg, BSSGP_IE_CELL_ID, sizeof(bssgp_cid), bssgp_cid);
	}

	/* Optional: Feature Bitmap */

	return bssgp_ns_send(bssgp_ns_send_data, msg);
}

/*! Transmit a BVC-RESET message with a given nsei and bvci (Chapter 10.4.12)
 *  \param[in] nsei The NSEI to transmit over
 *  \param[in] bvci BVCI of the BVC to reset
 *  \param[in] cause The cause of the reset
 *  \param[in] ra_id Pointer to the ra_id to include. If NULL no cell information will be included
 *  \param[in] cell_id The cell_id to include (if ra_id is not NULL)
 *  returns >= 0 on success, on error < 0.
 */
int bssgp_tx_bvc_reset_nsei_bvci(uint16_t nsei, uint16_t bvci, enum gprs_bssgp_cause cause, const struct gprs_ra_id *ra_id, uint16_t cell_id)
{
	return tx_bvc_reset_nsei_bvci(BSSGP_PDUT_BVC_RESET, nsei, bvci, cause, ra_id, cell_id);
}

/*! Transmit a BVC-RESET-ACK message with a given nsei and bvci (Chapter 10.4.12)
 *  \param[in] nsei The NSEI to transmit over
 *  \param[in] bvci BVCI of the BVC to reset
 *  \param[in] ra_id Pointer to the ra_id to include. If NULL no cell information will be included
 *  \param[in] cell_id The cell_id to include (if ra_id is not NULL)
 *  returns >= 0 on success, on error < 0.
 */
int bssgp_tx_bvc_reset_ack_nsei_bvci(uint16_t nsei, uint16_t bvci, const struct gprs_ra_id *ra_id, uint16_t cell_id)
{
	return tx_bvc_reset_nsei_bvci(BSSGP_PDUT_BVC_RESET_ACK, nsei, bvci, 0, ra_id, cell_id);
}

/*! Initiate reset procedure for all PTP BVC on a given NSEI.
 *
 *  This function initiates reset procedure for all PTP BVC with a given cause.
 *  \param[in] nsei NSEI to which PTP BVC should belong to
 *  \param[in] cause Cause of BVC RESET
 *  \returns 0 on success, negative error code otherwise
 */
int bssgp_tx_bvc_ptp_reset(uint16_t nsei, enum gprs_bssgp_cause cause)
{
	int rc;
	struct bssgp_bvc_ctx *bctx;

	llist_for_each_entry(bctx, &bssgp_bvc_ctxts, list) {
		if (bctx->nsei == nsei && bctx->bvci != BVCI_SIGNALLING) {
			LOGP(DLBSSGP, LOGL_DEBUG, "NSEI=%u/BVCI=%u RESET due to %s\n",
			     nsei, bctx->bvci, bssgp_cause_str(cause));
			rc = bssgp_tx_bvc_reset(bctx, bctx->bvci, cause);
			if (rc < 0)
				return rc;
		}
	}

	return 0;
}

/* Find a BTS context based on BVCI+NSEI tuple */
struct bssgp_bvc_ctx *btsctx_by_bvci_nsei(uint16_t bvci, uint16_t nsei)
{
	struct bssgp_bvc_ctx *bctx;

	llist_for_each_entry(bctx, &bssgp_bvc_ctxts, list) {
		if (bctx->nsei == nsei && bctx->bvci == bvci)
			return bctx;
	}
	return NULL;
}

void bssgp_set_bssgp_callback(bssgp_bvc_send ns_send, void *data)
{
	bssgp_ns_send = ns_send;
	bssgp_ns_send_data = data;
}

struct bssgp_bvc_ctx *btsctx_alloc(uint16_t bvci, uint16_t nsei)
{
	struct bssgp_bvc_ctx *ctx;

	ctx = talloc_zero(bssgp_tall_ctx, struct bssgp_bvc_ctx);
	if (!ctx)
		return NULL;
	ctx->bvci = bvci;
	ctx->nsei = nsei;
	ctx->is_sgsn = true;
	/* FIXME: BVCI is not unique, only BVCI+NSEI ?!? */
	ctx->ctrg = rate_ctr_group_alloc(ctx, &bssgp_ctrg_desc, bvci);
	if (!ctx->ctrg)
		goto err_ctrg;

	ctx->fc = talloc_zero(ctx, struct bssgp_flow_control);
	if (!ctx->fc)
		goto err_fc;

	/* cofigure for 2Mbit, 30 packets in queue */
	bssgp_fc_init(ctx->fc, 100000, 2*1024*1024/8, 30, &_bssgp_tx_dl_ud);

	llist_add(&ctx->list, &bssgp_bvc_ctxts);

	return ctx;

err_fc:
	rate_ctr_group_free(ctx->ctrg);
err_ctrg:
	talloc_free(ctx);
	return NULL;
}

void bssgp_bvc_ctx_free(struct bssgp_bvc_ctx *ctx)
{
	if (!ctx)
		return;

	osmo_timer_del(&ctx->fc->timer);
	rate_ctr_group_free(ctx->ctrg);
	llist_del(&ctx->list);
	talloc_free(ctx);
}

/* Chapter 10.4.5: Flow Control BVC ACK */
static int bssgp_tx_fc_bvc_ack(uint16_t nsei, uint8_t tag, uint16_t ns_bvci)
{
	struct msgb *msg = bssgp_msgb_alloc();
	struct bssgp_normal_hdr *bgph =
			(struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));

	msgb_nsei(msg) = nsei;
	msgb_bvci(msg) = ns_bvci;

	bgph->pdu_type = BSSGP_PDUT_FLOW_CONTROL_BVC_ACK;
	msgb_tvlv_put(msg, BSSGP_IE_TAG, 1, &tag);

	return bssgp_ns_send(bssgp_ns_send_data, msg);
}

/* 10.3.7 SUSPEND-ACK PDU */
int bssgp_tx_suspend_ack(uint16_t nsei, uint32_t tlli,
			 const struct gprs_ra_id *ra_id, uint8_t suspend_ref)
{
	struct msgb *msg = bssgp_msgb_alloc();
	struct bssgp_normal_hdr *bgph =
		(struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));

	msgb_nsei(msg) = nsei;
	msgb_bvci(msg) = 0; /* Signalling */
	bgph->pdu_type = BSSGP_PDUT_SUSPEND_ACK;

	bssgp_msgb_tlli_put(msg, tlli);
	bssgp_msgb_ra_put(msg, ra_id);
	msgb_tvlv_put(msg, BSSGP_IE_SUSPEND_REF_NR, 1, &suspend_ref);

	return bssgp_ns_send(bssgp_ns_send_data, msg);
}

/* 10.3.8 SUSPEND-NACK PDU */
int bssgp_tx_suspend_nack(uint16_t nsei, uint32_t tlli,
			  const struct gprs_ra_id *ra_id,
			  uint8_t *cause)
{
	struct msgb *msg = bssgp_msgb_alloc();
	struct bssgp_normal_hdr *bgph =
		(struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));

	msgb_nsei(msg) = nsei;
	msgb_bvci(msg) = 0; /* Signalling */
	bgph->pdu_type = BSSGP_PDUT_SUSPEND_NACK;

	bssgp_msgb_tlli_put(msg, tlli);
	bssgp_msgb_ra_put(msg, ra_id);

	if (cause)
		msgb_tvlv_put(msg, BSSGP_IE_CAUSE, 1, cause);

	return bssgp_ns_send(bssgp_ns_send_data, msg);
}

/* 10.3.10 RESUME-ACK PDU */
int bssgp_tx_resume_ack(uint16_t nsei, uint32_t tlli,
			const struct gprs_ra_id *ra_id)
{
	struct msgb *msg = bssgp_msgb_alloc();
	struct bssgp_normal_hdr *bgph =
		(struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));

	msgb_nsei(msg) = nsei;
	msgb_bvci(msg) = 0; /* Signalling */
	bgph->pdu_type = BSSGP_PDUT_RESUME_ACK;

	bssgp_msgb_tlli_put(msg, tlli);
	bssgp_msgb_ra_put(msg, ra_id);

	return bssgp_ns_send(bssgp_ns_send_data, msg);
}

/* 10.3.11 RESUME-NACK PDU */
int bssgp_tx_resume_nack(uint16_t nsei, uint32_t tlli,
			 const struct gprs_ra_id *ra_id, uint8_t *cause)
{
	struct msgb *msg = bssgp_msgb_alloc();
	struct bssgp_normal_hdr *bgph =
		(struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));

	msgb_nsei(msg) = nsei;
	msgb_bvci(msg) = 0; /* Signalling */
	bgph->pdu_type = BSSGP_PDUT_SUSPEND_NACK;

	bssgp_msgb_tlli_put(msg, tlli);
	bssgp_msgb_ra_put(msg, ra_id);

	if (cause)
		msgb_tvlv_put(msg, BSSGP_IE_CAUSE, 1, cause);

	return bssgp_ns_send(bssgp_ns_send_data, msg);
}

uint16_t bssgp_parse_cell_id(struct gprs_ra_id *raid, const uint8_t *buf)
{
	/* 6 octets RAC */
	gsm48_parse_ra(raid, buf);
	/* 2 octets CID */
	return osmo_load16be(buf+6);
}

int bssgp_create_cell_id(uint8_t *buf, const struct gprs_ra_id *raid,
			 uint16_t cid)
{
	/* 6 octets RAC */
	gsm48_encode_ra((struct gsm48_ra_id *)buf, raid);
	/* 2 octets CID */
	osmo_store16be(cid, buf+6);

	return 8;
}

/* Chapter 8.4 BVC-Reset Procedure */
static int bssgp_rx_bvc_reset(struct msgb *msg, struct tlv_parsed *tp,
			      uint16_t ns_bvci)
{
	struct osmo_bssgp_prim nmp;
	struct bssgp_bvc_ctx *bctx;
	uint16_t nsei = msgb_nsei(msg);
	uint16_t bvci;

	bvci = tlvp_val16be(tp, BSSGP_IE_BVCI);
	DEBUGP(DLBSSGP, "BSSGP BVCI=%u Rx RESET cause=%s\n", bvci,
		bssgp_cause_str(*TLVP_VAL(tp, BSSGP_IE_CAUSE)));

	/* look-up or create the BTS context for this BVC */
	bctx = btsctx_by_bvci_nsei(bvci, nsei);
	if (!bctx)
		bctx = btsctx_alloc(bvci, nsei);

	/* As opposed to NS-VCs, BVCs are NOT blocked after RESET */
	bctx->state &= ~BVC_S_BLOCKED;

	/* When we receive a BVC-RESET PDU (at least of a PTP BVCI), the BSS
	 * informs us about its RAC + Cell ID, so we can create a mapping */
	if (bctx->is_sgsn && bvci != BVCI_SIGNALLING && bvci != BVCI_PTM) {
		if (!TLVP_PRES_LEN(tp, BSSGP_IE_CELL_ID, 8)) {
			LOGP(DLBSSGP, LOGL_ERROR, "BSSGP BVCI=%u Rx RESET "
				"missing mandatory IE\n", bvci);
			return -EINVAL;
		}
		/* actually extract RAC / CID */
		bctx->cell_id = bssgp_parse_cell_id(&bctx->ra_id,
						TLVP_VAL(tp, BSSGP_IE_CELL_ID));
		LOGP(DLBSSGP, LOGL_NOTICE, "Cell %s CI %u on BVCI %u\n",
		     osmo_rai_name(&bctx->ra_id), bctx->cell_id, bvci);
	}

	/* Acknowledge the RESET to the BTS */
	if (bvci == BVCI_SIGNALLING || bvci == BVCI_PTM || bctx->is_sgsn)
		bssgp_tx_simple_bvci(BSSGP_PDUT_BVC_RESET_ACK,
				     nsei, bvci, ns_bvci);
	else
		bssgp_tx_bvc_reset_ack_nsei_bvci(nsei, bvci, &bctx->ra_id, bctx->cell_id);

	/* Send NM_BVC_RESET.ind to NM */
	memset(&nmp, 0, sizeof(nmp));
	nmp.nsei = nsei;
	nmp.bvci = bvci;
	nmp.tp = tp;
	nmp.ra_id = &bctx->ra_id;
	osmo_prim_init(&nmp.oph, SAP_BSSGP_NM, PRIM_NM_BVC_RESET,
			PRIM_OP_INDICATION, msg);
	bssgp_prim_cb(&nmp.oph, NULL);
	return 0;
}

static int bssgp_rx_bvc_block(struct msgb *msg, struct tlv_parsed *tp)
{
	struct osmo_bssgp_prim nmp;
	uint16_t bvci, nsei = msgb_nsei(msg);
	struct bssgp_bvc_ctx *ptp_ctx;

	bvci = tlvp_val16be(tp, BSSGP_IE_BVCI);
	if (bvci == BVCI_SIGNALLING) {
		/* 8.3.2: Signalling BVC shall never be blocked */
		LOGP(DLBSSGP, LOGL_ERROR, "NSEI=%u/BVCI=%u "
			"received block for signalling BVC!?!\n",
			nsei, msgb_bvci(msg));
		return 0;
	}

	LOGP(DLBSSGP, LOGL_INFO, "BSSGP Rx BVCI=%u BVC-BLOCK\n", bvci);

	ptp_ctx = btsctx_by_bvci_nsei(bvci, nsei);
	if (!ptp_ctx)
		return bssgp_tx_status(BSSGP_CAUSE_UNKNOWN_BVCI, &bvci, msg);

	ptp_ctx->state |= BVC_S_BLOCKED;
	rate_ctr_inc(rate_ctr_group_get_ctr(ptp_ctx->ctrg, BSSGP_CTR_BLOCKED));

	/* Send NM_BVC_BLOCK.ind to NM */
	memset(&nmp, 0, sizeof(nmp));
	nmp.nsei = nsei;
	nmp.bvci = bvci;
	nmp.tp = tp;
	osmo_prim_init(&nmp.oph, SAP_BSSGP_NM, PRIM_NM_BVC_BLOCK,
			PRIM_OP_INDICATION, msg);
	bssgp_prim_cb(&nmp.oph, NULL);

	/* We always acknowledge the BLOCKing */
	return bssgp_tx_simple_bvci(BSSGP_PDUT_BVC_BLOCK_ACK, nsei,
				    bvci, msgb_bvci(msg));
};

static int bssgp_rx_bvc_unblock(struct msgb *msg, struct tlv_parsed *tp)
{
	struct osmo_bssgp_prim nmp;
	uint16_t bvci, nsei = msgb_nsei(msg);
	struct bssgp_bvc_ctx *ptp_ctx;

	bvci = tlvp_val16be(tp, BSSGP_IE_BVCI);
	if (bvci == BVCI_SIGNALLING) {
		/* 8.3.2: Signalling BVC shall never be blocked */
		LOGP(DLBSSGP, LOGL_ERROR, "NSEI=%u/BVCI=%u "
			"received unblock for signalling BVC!?!\n",
			nsei, msgb_bvci(msg));
		return 0;
	}

	DEBUGP(DLBSSGP, "BSSGP BVCI=%u Rx BVC-UNBLOCK\n", bvci);

	ptp_ctx = btsctx_by_bvci_nsei(bvci, nsei);
	if (!ptp_ctx)
		return bssgp_tx_status(BSSGP_CAUSE_UNKNOWN_BVCI, &bvci, msg);

	ptp_ctx->state &= ~BVC_S_BLOCKED;

	/* Send NM_BVC_UNBLOCK.ind to NM */
	memset(&nmp, 0, sizeof(nmp));
	nmp.nsei = nsei;
	nmp.bvci = bvci;
	nmp.tp = tp;
	osmo_prim_init(&nmp.oph, SAP_BSSGP_NM, PRIM_NM_BVC_UNBLOCK,
			PRIM_OP_INDICATION, msg);
	bssgp_prim_cb(&nmp.oph, NULL);

	/* We always acknowledge the unBLOCKing */
	return bssgp_tx_simple_bvci(BSSGP_PDUT_BVC_UNBLOCK_ACK, nsei,
				    bvci, msgb_bvci(msg));
};

/* Uplink unit-data */
static int bssgp_rx_ul_ud(struct msgb *msg, struct tlv_parsed *tp,
			  struct bssgp_bvc_ctx *ctx)
{
	struct osmo_bssgp_prim gbp;
	struct bssgp_ud_hdr *budh = (struct bssgp_ud_hdr *) msgb_bssgph(msg);

	/* extract TLLI and parse TLV IEs */
	msgb_tlli(msg) = osmo_ntohl(budh->tlli);

	DEBUGP(DLBSSGP, "BSSGP TLLI=0x%08x Rx UPLINK-UNITDATA\n", msgb_tlli(msg));

	/* Cell ID and LLC_PDU are the only mandatory IE */
	if (!TLVP_PRES_LEN(tp, BSSGP_IE_CELL_ID, 8) ||
	    !TLVP_PRESENT(tp, BSSGP_IE_LLC_PDU)) {
		LOGP(DLBSSGP, LOGL_ERROR, "BSSGP TLLI=0x%08x Rx UL-UD "
			"missing mandatory IE\n", msgb_tlli(msg));
		return bssgp_tx_status(BSSGP_CAUSE_MISSING_MAND_IE, NULL, msg);
	}

	/* store pointer to LLC header and CELL ID in msgb->cb */
	msgb_llch(msg) = (uint8_t *) TLVP_VAL(tp, BSSGP_IE_LLC_PDU);
	msgb_bcid(msg) = (uint8_t *) TLVP_VAL(tp, BSSGP_IE_CELL_ID);

	/* Send BSSGP_UL_UD.ind to NM */
	memset(&gbp, 0, sizeof(gbp));
	gbp.nsei = ctx->nsei;
	gbp.bvci = ctx->bvci;
	gbp.tlli = msgb_tlli(msg);
	gbp.tp = tp;
	osmo_prim_init(&gbp.oph, SAP_BSSGP_LL, PRIM_BSSGP_UL_UD,
			PRIM_OP_INDICATION, msg);
	return bssgp_prim_cb(&gbp.oph, NULL);
}

static int bssgp_rx_suspend(struct msgb *msg, struct tlv_parsed *tp)
{
	struct osmo_bssgp_prim gbp;
	struct gprs_ra_id raid;
	uint32_t tlli;
	uint16_t ns_bvci = msgb_bvci(msg), nsei = msgb_nsei(msg);
	int rc;

	if (!TLVP_PRES_LEN(tp, BSSGP_IE_TLLI, 4) ||
	    !TLVP_PRES_LEN(tp, BSSGP_IE_ROUTEING_AREA, 6)) {
		LOGP(DLBSSGP, LOGL_ERROR, "BSSGP BVCI=%u Rx SUSPEND "
			"missing mandatory IE\n", ns_bvci);
		return bssgp_tx_status(BSSGP_CAUSE_MISSING_MAND_IE, NULL, msg);
	}

	tlli = tlvp_val32be(tp, BSSGP_IE_TLLI);

	DEBUGP(DLBSSGP, "BSSGP BVCI=%u TLLI=0x%08x Rx SUSPEND\n",
		ns_bvci, tlli);

	gsm48_parse_ra(&raid, TLVP_VAL(tp, BSSGP_IE_ROUTEING_AREA));

	/* Inform GMM about the SUSPEND request */
	memset(&gbp, 0, sizeof(gbp));
	gbp.nsei = nsei;
	gbp.bvci = ns_bvci;
	gbp.tlli = tlli;
	gbp.ra_id = &raid;
	osmo_prim_init(&gbp.oph, SAP_BSSGP_GMM, PRIM_BSSGP_GMM_SUSPEND,
			PRIM_OP_REQUEST, msg);

	rc = bssgp_prim_cb(&gbp.oph, NULL);
	if (rc < 0)
		return bssgp_tx_suspend_nack(nsei, tlli, &raid, NULL);

	bssgp_tx_suspend_ack(nsei, tlli, &raid, 0);

	return 0;
}

static int bssgp_rx_resume(struct msgb *msg, struct tlv_parsed *tp)
{
	struct osmo_bssgp_prim gbp;
	struct gprs_ra_id raid;
	uint32_t tlli;
	uint8_t suspend_ref;
	uint16_t ns_bvci = msgb_bvci(msg), nsei = msgb_nsei(msg);
	int rc;

	if (!TLVP_PRES_LEN(tp, BSSGP_IE_TLLI, 4 ) ||
	    !TLVP_PRES_LEN(tp, BSSGP_IE_ROUTEING_AREA, 6) ||
	    !TLVP_PRES_LEN(tp, BSSGP_IE_SUSPEND_REF_NR, 1)) {
		LOGP(DLBSSGP, LOGL_ERROR, "BSSGP BVCI=%u Rx RESUME "
			"missing mandatory IE\n", ns_bvci);
		return bssgp_tx_status(BSSGP_CAUSE_MISSING_MAND_IE, NULL, msg);
	}

	tlli = tlvp_val32be(tp, BSSGP_IE_TLLI);
	suspend_ref = *TLVP_VAL(tp, BSSGP_IE_SUSPEND_REF_NR);

	DEBUGP(DLBSSGP, "BSSGP BVCI=%u TLLI=0x%08x Rx RESUME\n", ns_bvci, tlli);

	gsm48_parse_ra(&raid, TLVP_VAL(tp, BSSGP_IE_ROUTEING_AREA));

	/* Inform GMM about the RESUME request */
	memset(&gbp, 0, sizeof(gbp));
	gbp.nsei = nsei;
	gbp.bvci = ns_bvci;
	gbp.tlli = tlli;
	gbp.ra_id = &raid;
	gbp.u.resume.suspend_ref = suspend_ref;
	osmo_prim_init(&gbp.oph, SAP_BSSGP_GMM, PRIM_BSSGP_GMM_RESUME,
			PRIM_OP_REQUEST, msg);

	rc = bssgp_prim_cb(&gbp.oph, NULL);
	if (rc < 0)
		return bssgp_tx_resume_nack(nsei, tlli, &raid,
					    NULL);

	bssgp_tx_resume_ack(nsei, tlli, &raid);
	return 0;
}


static int bssgp_rx_llc_disc(struct msgb *msg, struct tlv_parsed *tp,
			     struct bssgp_bvc_ctx *ctx)
{
	struct osmo_bssgp_prim nmp;
	uint32_t tlli = 0;
	uint16_t nsei = msgb_nsei(msg);

	if (!TLVP_PRES_LEN(tp, BSSGP_IE_TLLI, 4) ||
	    !TLVP_PRES_LEN(tp, BSSGP_IE_LLC_FRAMES_DISCARDED, 1) ||
	    !TLVP_PRES_LEN(tp, BSSGP_IE_BVCI, 2) ||
	    !TLVP_PRES_LEN(tp, BSSGP_IE_NUM_OCT_AFF, 3)) {
		LOGP(DLBSSGP, LOGL_ERROR, "BSSGP BVCI=%u Rx LLC DISCARDED "
			"missing mandatory IE\n", ctx->bvci);
		return bssgp_tx_status(BSSGP_CAUSE_MISSING_MAND_IE, NULL, msg);
	}

	tlli = tlvp_val32be(tp, BSSGP_IE_TLLI);

	DEBUGP(DLBSSGP, "BSSGP BVCI=%u TLLI=%08x Rx LLC DISCARDED\n",
		ctx->bvci, tlli);

	rate_ctr_inc(rate_ctr_group_get_ctr(ctx->ctrg, BSSGP_CTR_DISCARDED));

	/* send NM_LLC_DISCARDED to NM */
	memset(&nmp, 0, sizeof(nmp));
	nmp.nsei = nsei;
	nmp.bvci = ctx->bvci;
	nmp.tlli = tlli;
	nmp.tp = tp;
	osmo_prim_init(&nmp.oph, SAP_BSSGP_NM, PRIM_NM_LLC_DISCARDED,
			PRIM_OP_INDICATION, msg);

	return bssgp_prim_cb(&nmp.oph, NULL);
}

int bssgp_rx_status(struct msgb *msg, struct tlv_parsed *tp,
	uint16_t bvci, struct bssgp_bvc_ctx *bctx)
{
	uint16_t nsei = msgb_nsei(msg);
	struct osmo_bssgp_prim nmp;
	enum gprs_bssgp_cause cause;

	if (!TLVP_PRES_LEN(tp, BSSGP_IE_CAUSE, 1)) {
		LOGP(DLBSSGP, LOGL_ERROR, "BSSGP BVCI=%u Rx STATUS "
			"missing mandatory IE\n", bvci);
		cause = BSSGP_CAUSE_PROTO_ERR_UNSPEC;
	} else {
		cause = *TLVP_VAL(tp, BSSGP_IE_CAUSE);
	}

	LOGP(DLBSSGP, LOGL_NOTICE, "BSSGP BVCI=%u Rx BVC STATUS, cause=%s\n",
		bvci, bssgp_cause_str(cause));

	if (cause == BSSGP_CAUSE_BVCI_BLOCKED || cause == BSSGP_CAUSE_UNKNOWN_BVCI) {
		if (!TLVP_PRES_LEN(tp, BSSGP_IE_BVCI, 2))
			LOGP(DLBSSGP, LOGL_ERROR,
				"BSSGP BVCI=%u Rx STATUS cause=%s "
				"missing conditional BVCI IE\n",
				bvci, bssgp_cause_str(cause));
	}

	if (bctx)
		rate_ctr_inc(rate_ctr_group_get_ctr(bctx->ctrg, BSSGP_CTR_STATUS));

	/* send NM_STATUS to NM */
	memset(&nmp, 0, sizeof(nmp));
	nmp.nsei = nsei;
	nmp.bvci = bvci;
	nmp.tp = tp;
	osmo_prim_init(&nmp.oph, SAP_BSSGP_NM, PRIM_NM_STATUS,
			PRIM_OP_INDICATION, msg);

	return bssgp_prim_cb(&nmp.oph, NULL);
}

/* One element (msgb) in a BSSGP Flow Control queue */
struct bssgp_fc_queue_element {
	/* linked list of queue elements */
	struct llist_head list;
	/* The message that we have enqueued */
	struct msgb *msg;
	/* Length of the LLC PDU part of the contained message */
	uint32_t llc_pdu_len;
	/* private pointer passed to the flow control out_cb function */
	void *priv;
};

static int fc_queue_timer_cfg(struct bssgp_flow_control *fc);
static int bssgp_fc_needs_queueing(struct bssgp_flow_control *fc, uint32_t pdu_len);

static void fc_timer_cb(void *data)
{
	struct bssgp_flow_control *fc = data;
	struct bssgp_fc_queue_element *fcqe;
	struct timeval time_now;

	/* if the queue is empty, we return without sending something
	 * and without re-starting the timer */
	if (llist_empty(&fc->queue))
		return;

	/* get the first entry from the queue */
	fcqe = llist_entry(fc->queue.next, struct bssgp_fc_queue_element,
			   list);

	if (bssgp_fc_needs_queueing(fc, fcqe->llc_pdu_len)) {
		LOGP(DLBSSGP, LOGL_NOTICE, "BSSGP-FC: fc_timer_cb() but still "
			"not able to send PDU of %u bytes\n", fcqe->llc_pdu_len);
		/* make sure we re-start the timer */
		fc_queue_timer_cfg(fc);
		return;
	}

	/* remove from the queue */
	llist_del(&fcqe->list);

	fc->queue_depth--;

	/* record the time we transmitted this PDU */
	osmo_gettimeofday(&time_now, NULL);
	fc->time_last_pdu = time_now;

	/* call the output callback for this FC instance */
	fc->out_cb(fcqe->priv, fcqe->msg, fcqe->llc_pdu_len, NULL);

	/* we expect that out_cb will in the end free the msgb once
	 * it is no longer needed */

	/* but we have to free the queue element ourselves */
	talloc_free(fcqe);

	/* re-configure the timer for the next PDU */
	fc_queue_timer_cfg(fc);
}

/* configure/schedule the flow control timer to expire once the bucket
 * will have leaked a sufficient number of bytes to transmit the next
 * PDU in the queue */
static int fc_queue_timer_cfg(struct bssgp_flow_control *fc)
{
	struct bssgp_fc_queue_element *fcqe;
	uint32_t msecs;

	if (llist_empty(&fc->queue))
		return 0;

	fcqe = llist_entry(fc->queue.next, struct bssgp_fc_queue_element,
			   list);

	if (fc->bucket_leak_rate != 0) {
		/* Calculate the point in time at which we will have leaked
		 * a sufficient number of bytes from the bucket to transmit
		 * the first PDU in the queue */
		msecs = (fcqe->llc_pdu_len * 1000) / fc->bucket_leak_rate;
		/* FIXME: add that time to fc->time_last_pdu and subtract it from
		 * current time */
		osmo_timer_setup(&fc->timer, fc_timer_cb, fc);
		osmo_timer_schedule(&fc->timer, msecs / 1000, (msecs % 1000) * 1000);
	} else {
		/* If the PCU is telling us to not send any more data at all,
		* there's no point starting a timer. */
	}

	return 0;
}

/* Enqueue a PDU in the flow control queue for delayed transmission */
static int fc_enqueue(struct bssgp_flow_control *fc, struct msgb *msg,
		      uint32_t llc_pdu_len, void *priv)
{
	struct bssgp_fc_queue_element *fcqe;

	if (fc->queue_depth >= fc->max_queue_depth)
		return -ENOSPC;

	fcqe = talloc_zero(fc, struct bssgp_fc_queue_element);
	if (!fcqe)
		return -ENOMEM;
	fcqe->msg = msg;
	fcqe->llc_pdu_len = llc_pdu_len;
	fcqe->priv = priv;

	llist_add_tail(&fcqe->list, &fc->queue);

	fc->queue_depth++;

	/* re-configure the timer for dequeueing the pdu */
	fc_queue_timer_cfg(fc);

	return 0;
}

/* According to Section 8.2 */
static int bssgp_fc_needs_queueing(struct bssgp_flow_control *fc, uint32_t pdu_len)
{
	struct timeval time_now, time_diff;
	int64_t bucket_predicted;
	uint32_t csecs_elapsed, leaked;

	/* B' = B + L(p) - (Tc - Tp)*R */

	/* compute number of centi-seconds that have elapsed since transmitting
	 * the last PDU (Tc - Tp) */
	osmo_gettimeofday(&time_now, NULL);
	timersub(&time_now, &fc->time_last_pdu, &time_diff);
	csecs_elapsed = time_diff.tv_sec*100 + time_diff.tv_usec/10000;

	/* compute number of bytes that have leaked in the elapsed number
	 * of centi-seconds */
	leaked = csecs_elapsed * (fc->bucket_leak_rate / 100);
	/* add the current PDU length to the last bucket level */
	bucket_predicted = fc->bucket_counter + pdu_len;
	/* ... and subtract the number of leaked bytes */
	bucket_predicted -= leaked;

	if (bucket_predicted < pdu_len)
		return 0;

	if (bucket_predicted <= fc->bucket_size_max) {
		/* the bucket is not full yet, we can pass the packet */
		fc->bucket_counter = bucket_predicted;
		return 0;
	}

	/* bucket is full, PDU needs to be delayed */
	return 1;
}

/* output callback for BVC flow control */
static int _bssgp_tx_dl_ud(struct bssgp_flow_control *fc, struct msgb *msg,
			   uint32_t llc_pdu_len, void *priv)
{
	return bssgp_ns_send(bssgp_ns_send_data, msg);
}

/* input function of the flow control implementation, called first
 * for the MM flow control, and then as the MM flow control output
 * callback in order to perform BVC flow control */
int bssgp_fc_in(struct bssgp_flow_control *fc, struct msgb *msg,
		uint32_t llc_pdu_len, void *priv)
{
	struct timeval time_now;

	if (llc_pdu_len > fc->bucket_size_max) {
		LOGP(DLBSSGP, LOGL_NOTICE, "Single PDU (size=%u) is larger "
		     "than maximum bucket size (%u)!\n", llc_pdu_len,
		     fc->bucket_size_max);
		msgb_free(msg);
		return -EIO;
	}

	if (bssgp_fc_needs_queueing(fc, llc_pdu_len)) {
		int rc;
		rc = fc_enqueue(fc, msg, llc_pdu_len, priv);
		if (rc)
			msgb_free(msg);
		return rc;
	} else {
		/* record the time we transmitted this PDU */
		osmo_gettimeofday(&time_now, NULL);
		fc->time_last_pdu = time_now;
		return fc->out_cb(priv, msg, llc_pdu_len, NULL);
	}
}


/* Initialize the Flow Control structure */
void bssgp_fc_init(struct bssgp_flow_control *fc,
		   uint32_t bucket_size_max, uint32_t bucket_leak_rate,
		   uint32_t max_queue_depth,
		   int (*out_cb)(struct bssgp_flow_control *fc, struct msgb *msg,
				 uint32_t llc_pdu_len, void *priv))
{
	fc->out_cb = out_cb;
	fc->bucket_size_max = bucket_size_max;
	fc->bucket_leak_rate = bucket_leak_rate;
	fc->max_queue_depth = max_queue_depth;
	INIT_LLIST_HEAD(&fc->queue);
	osmo_gettimeofday(&fc->time_last_pdu, NULL);
}

/* Initialize the Flow Control parameters for a new MS according to
 * default values for the BVC specified by BVCI and NSEI */
int bssgp_fc_ms_init(struct bssgp_flow_control *fc_ms, uint16_t bvci,
		     uint16_t nsei, uint32_t max_queue_depth)
{
	struct bssgp_bvc_ctx *ctx;

	ctx = btsctx_by_bvci_nsei(bvci, nsei);
	if (!ctx)
		return -ENODEV;

	/* output call-back of per-MS FC is per-CTX FC */
	bssgp_fc_init(fc_ms, ctx->bmax_default_ms, ctx->r_default_ms,
			max_queue_depth, bssgp_fc_in);

	return 0;
}

static int bssgp_rx_fc_bvc(struct msgb *msg, struct tlv_parsed *tp,
			   struct bssgp_bvc_ctx *bctx)
{
	uint32_t old_leak_rate = bctx->fc->bucket_leak_rate;
	uint32_t old_r_def_ms = bctx->r_default_ms;

	DEBUGP(DLBSSGP, "BSSGP BVCI=%u Rx Flow Control BVC\n",
		bctx->bvci);

	if (!TLVP_PRES_LEN(tp, BSSGP_IE_TAG, 1) ||
	    !TLVP_PRES_LEN(tp, BSSGP_IE_BVC_BUCKET_SIZE, 2) ||
	    !TLVP_PRES_LEN(tp, BSSGP_IE_BUCKET_LEAK_RATE, 2) ||
	    !TLVP_PRES_LEN(tp, BSSGP_IE_BMAX_DEFAULT_MS, 2) ||
	    !TLVP_PRES_LEN(tp, BSSGP_IE_R_DEFAULT_MS,2)) {
		LOGP(DLBSSGP, LOGL_ERROR, "BSSGP BVCI=%u Rx FC BVC "
			"missing mandatory IE\n", bctx->bvci);
		return bssgp_tx_status(BSSGP_CAUSE_MISSING_MAND_IE, NULL, msg);
	}

	/* 11.3.5 Bucket Size in 100 octets unit */
	bctx->fc->bucket_size_max = 100 * tlvp_val16be(tp, BSSGP_IE_BVC_BUCKET_SIZE);
	/* 11.3.4 Bucket Leak Rate in 100 bits/sec unit */
	bctx->fc->bucket_leak_rate = 100 * tlvp_val16be(tp, BSSGP_IE_BUCKET_LEAK_RATE) / 8;
	/* 11.3.2 in octets */
	bctx->bmax_default_ms = tlvp_val16be(tp, BSSGP_IE_BMAX_DEFAULT_MS);
	/* 11.3.32 Bucket Leak rate in 100bits/sec unit */
	bctx->r_default_ms = 100 * tlvp_val16be(tp, BSSGP_IE_R_DEFAULT_MS) / 8;

	if (old_leak_rate != 0 && bctx->fc->bucket_leak_rate == 0)
		LOGP(DLBSSGP, LOGL_NOTICE, "BSS instructs us to bucket leak "
			"rate of 0, stopping all DL GPRS!\n");
	else if (old_leak_rate == 0 && bctx->fc->bucket_leak_rate != 0)
		LOGP(DLBSSGP, LOGL_NOTICE, "BSS instructs us to bucket leak "
			"rate of != 0, restarting all DL GPRS!\n");

	if (old_r_def_ms != 0 && bctx->r_default_ms == 0)
		LOGP(DLBSSGP, LOGL_NOTICE, "BSS instructs us to MS default "
			"bucket leak rate of 0, stopping DL GPRS!\n");
	else if (old_r_def_ms == 0 && bctx->r_default_ms != 0)
		LOGP(DLBSSGP, LOGL_NOTICE, "BSS instructs us to MS default "
			"bucket leak rate != 0, restarting DL GPRS!\n");

	/* reconfigure the timer for flow control based on new values */
	fc_queue_timer_cfg(bctx->fc);

	/* Send FLOW_CONTROL_BVC_ACK */
	return bssgp_tx_fc_bvc_ack(msgb_nsei(msg), *TLVP_VAL(tp, BSSGP_IE_TAG),
				   msgb_bvci(msg));
}

/* Receive a BSSGP PDU from a BSS on a PTP BVCI */
static int bssgp_rx_ptp(struct msgb *msg, struct tlv_parsed *tp,
			struct bssgp_bvc_ctx *bctx)
{
	struct bssgp_normal_hdr *bgph =
			(struct bssgp_normal_hdr *) msgb_bssgph(msg);
	uint8_t pdu_type = bgph->pdu_type;
	int rc = 0;

	OSMO_ASSERT(pdu_type != BSSGP_PDUT_STATUS);

	/* If traffic is received on a BVC that is marked as blocked, the
	 * received PDU shall not be accepted and a STATUS PDU (Cause value:
	 * BVC Blocked) shall be sent to the peer entity on the signalling BVC */
	if (bctx->state & BVC_S_BLOCKED) {
		uint16_t bvci = msgb_bvci(msg);
		return bssgp_tx_status(BSSGP_CAUSE_BVCI_BLOCKED, &bvci, msg);
	}

	switch (pdu_type) {
	case BSSGP_PDUT_UL_UNITDATA:
		/* some LLC data from the MS */
		rc = bssgp_rx_ul_ud(msg, tp, bctx);
		break;
	case BSSGP_PDUT_RA_CAPABILITY:
		/* BSS requests RA capability or IMSI */
		DEBUGP(DLBSSGP, "BSSGP BVCI=%u Rx RA CAPABILITY UPDATE\n",
			bctx->bvci);
		/* FIXME: send GMM_RA_CAPABILITY_UPDATE.ind to GMM */
		/* FIXME: send RA_CAPA_UPDATE_ACK */
		break;
	case BSSGP_PDUT_RADIO_STATUS:
		DEBUGP(DLBSSGP, "BSSGP BVCI=%u Rx RADIO STATUS\n", bctx->bvci);
		/* BSS informs us of some exception */
		/* FIXME: send GMM_RADIO_STATUS.ind to GMM */
		break;
	case BSSGP_PDUT_FLOW_CONTROL_BVC:
		/* BSS informs us of available bandwidth in Gb interface */
		rc = bssgp_rx_fc_bvc(msg, tp, bctx);
		break;
	case BSSGP_PDUT_FLOW_CONTROL_MS:
		/* BSS informs us of available bandwidth to one MS */
		DEBUGP(DLBSSGP, "BSSGP BVCI=%u Rx Flow Control MS\n",
			bctx->bvci);
		/* FIXME: actually implement flow control */
		/* FIXME: Send FLOW_CONTROL_MS_ACK */
		break;
	case BSSGP_PDUT_STATUS:
		/* This is already handled in bssgp_rcvmsg() */
		break;
	case BSSGP_PDUT_BVC_RESET:
		rc = bssgp_rx_bvc_reset(msg, tp, bctx->bvci);
		break;
	case BSSGP_PDUT_DOWNLOAD_BSS_PFC:
	case BSSGP_PDUT_CREATE_BSS_PFC_ACK:
	case BSSGP_PDUT_CREATE_BSS_PFC_NACK:
	case BSSGP_PDUT_MODIFY_BSS_PFC:
	case BSSGP_PDUT_DELETE_BSS_PFC_ACK:
		DEBUGP(DLBSSGP, "BSSGP BVCI=%u Rx PDU type %s not [yet] "
		       "implemented\n", bctx->bvci, bssgp_pdu_str(pdu_type));
		rc = bssgp_tx_status(BSSGP_CAUSE_PDU_INCOMP_FEAT, NULL, msg);
		break;
	/* those only exist in the SGSN -> BSS direction */
	case BSSGP_PDUT_DL_UNITDATA:
	case BSSGP_PDUT_PAGING_PS:
	case BSSGP_PDUT_PAGING_CS:
	case BSSGP_PDUT_RA_CAPA_UPDATE_ACK:
	case BSSGP_PDUT_FLOW_CONTROL_BVC_ACK:
	case BSSGP_PDUT_FLOW_CONTROL_MS_ACK:
		DEBUGP(DLBSSGP, "BSSGP BVCI=%u PDU type %s only exists in DL\n",
		       bctx->bvci, bssgp_pdu_str(pdu_type));
		bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg);
		rc = -EINVAL;
		break;
	default:
		DEBUGP(DLBSSGP, "BSSGP BVCI=%u PDU type %s unknown\n",
		       bctx->bvci, bssgp_pdu_str(pdu_type));
		rc = bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg);
		break;
	}

	return rc;
}

/* Receive a BSSGP PDU from a BSS on a SIGNALLING BVCI */
static int bssgp_rx_sign(struct msgb *msg, struct tlv_parsed *tp,
			 struct bssgp_bvc_ctx *bctx)
{
	struct bssgp_normal_hdr *bgph =
			(struct bssgp_normal_hdr *) msgb_bssgph(msg);
	uint8_t pdu_type = bgph->pdu_type;
	int rc = 0;
	uint16_t ns_bvci = msgb_bvci(msg);
	uint16_t bvci = bctx ? bctx->bvci : ns_bvci;

	switch (bgph->pdu_type) {
	case BSSGP_PDUT_SUSPEND:
		/* MS wants to suspend */
		rc = bssgp_rx_suspend(msg, tp);
		break;
	case BSSGP_PDUT_RESUME:
		/* MS wants to resume */
		rc = bssgp_rx_resume(msg, tp);
		break;
	case BSSGP_PDUT_FLUSH_LL_ACK:
		/* BSS informs us it has performed LL FLUSH */
		DEBUGP(DLBSSGP, "BSSGP Rx BVCI=%u FLUSH LL ACK\n", bvci);
		/* FIXME: send NM_FLUSH_LL.res to NM */
		break;
	case BSSGP_PDUT_LLC_DISCARD:
		/* BSS informs that some LLC PDU's have been discarded */
		if (!bctx) {
			LOGP(DLBSSGP, LOGL_ERROR,
			     "BSSGP Rx LLC-DISCARD missing mandatory BVCI\n");
			goto err_mand_ie;
		}
		rc = bssgp_rx_llc_disc(msg, tp, bctx);
		break;
	case BSSGP_PDUT_BVC_BLOCK:
		/* BSS tells us that BVC shall be blocked */
		if (!TLVP_PRES_LEN(tp, BSSGP_IE_BVCI, 2) ||
		    !TLVP_PRES_LEN(tp, BSSGP_IE_CAUSE, 1)) {
			LOGP(DLBSSGP, LOGL_ERROR, "BSSGP Rx BVC-BLOCK "
				"missing mandatory IE\n");
			goto err_mand_ie;
		}
		rc = bssgp_rx_bvc_block(msg, tp);
		break;
	case BSSGP_PDUT_BVC_UNBLOCK:
		/* BSS tells us that BVC shall be unblocked */
		if (!TLVP_PRES_LEN(tp, BSSGP_IE_BVCI, 2)) {
			LOGP(DLBSSGP, LOGL_ERROR, "BSSGP Rx BVC-UNBLOCK "
				"missing mandatory IE\n");
			goto err_mand_ie;
		}
		rc = bssgp_rx_bvc_unblock(msg, tp);
		break;
	case BSSGP_PDUT_BVC_RESET_ACK:
		LOGP(DLBSSGP, LOGL_ERROR, "BSSGP BVCI=%u Rx BVC-RESET-ACK\n", bvci);
		break;
	case BSSGP_PDUT_BVC_RESET:
		/* SGSN or BSS tells us that BVC init is required */
		if (!TLVP_PRES_LEN(tp, BSSGP_IE_BVCI, 2) ||
		    !TLVP_PRES_LEN(tp, BSSGP_IE_CAUSE, 1)) {
			LOGP(DLBSSGP, LOGL_ERROR, "BSSGP Rx BVC-RESET "
				"missing mandatory IE\n");
			goto err_mand_ie;
		}
		rc = bssgp_rx_bvc_reset(msg, tp, ns_bvci);
		break;
	case BSSGP_PDUT_STATUS:
		/* This is already handled in bssgp_rcvmsg() */
		break;

	case BSSGP_PDUT_RAN_INFO:
	case BSSGP_PDUT_RAN_INFO_REQ:
	case BSSGP_PDUT_RAN_INFO_ACK:
	case BSSGP_PDUT_RAN_INFO_ERROR:
	case BSSGP_PDUT_RAN_INFO_APP_ERROR:
		rc = bssgp_rx_rim(msg, tp, bvci);
		break;

	/* those only exist in the SGSN -> BSS direction */
	case BSSGP_PDUT_PAGING_PS:
	case BSSGP_PDUT_PAGING_CS:
	case BSSGP_PDUT_SUSPEND_ACK:
	case BSSGP_PDUT_SUSPEND_NACK:
	case BSSGP_PDUT_RESUME_ACK:
	case BSSGP_PDUT_RESUME_NACK:
	case BSSGP_PDUT_FLUSH_LL:
	case BSSGP_PDUT_BVC_BLOCK_ACK:
	case BSSGP_PDUT_BVC_UNBLOCK_ACK:
	case BSSGP_PDUT_SGSN_INVOKE_TRACE:
		DEBUGP(DLBSSGP, "BSSGP BVCI=%u Rx PDU type %s only exists in DL\n",
		       bvci, bssgp_pdu_str(pdu_type));
		bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg);
		rc = -EINVAL;
		break;
	default:
		DEBUGP(DLBSSGP, "BSSGP BVCI=%u Rx PDU type %s unknown\n",
			bvci, bssgp_pdu_str(pdu_type));
		rc = bssgp_tx_status(BSSGP_CAUSE_PROTO_ERR_UNSPEC, NULL, msg);
		break;
	}

	return rc;
err_mand_ie:
	return bssgp_tx_status(BSSGP_CAUSE_MISSING_MAND_IE, NULL, msg);
}

/* We expect msgb_bssgph() to point to the BSSGP header */
int bssgp_rcvmsg(struct msgb *msg)
{
	struct bssgp_normal_hdr *bgph =
			(struct bssgp_normal_hdr *) msgb_bssgph(msg);
	struct bssgp_ud_hdr *budh = (struct bssgp_ud_hdr *) msgb_bssgph(msg);
	struct tlv_parsed tp;
	struct bssgp_bvc_ctx *bctx;
	uint8_t pdu_type = bgph->pdu_type;
	uint16_t ns_bvci = msgb_bvci(msg);
	uint16_t nsei = msgb_nsei(msg);
	uint16_t bvci = ns_bvci;
	int data_len;
	int rc = 0;

	/* Identifiers from DOWN: NSEI, BVCI (both in msg->cb) */

	/* UNITDATA BSSGP headers have TLLI in front */
	if (pdu_type != BSSGP_PDUT_UL_UNITDATA &&
	    pdu_type != BSSGP_PDUT_DL_UNITDATA) {
		data_len = msgb_bssgp_len(msg) - sizeof(*bgph);
		rc = bssgp_tlv_parse(&tp, bgph->data, data_len);
	} else {
		data_len = msgb_bssgp_len(msg) - sizeof(*budh);
		rc = bssgp_tlv_parse(&tp, budh->data, data_len);
	}
	if (rc < 0) {
		LOGP(DLBSSGP, LOGL_ERROR, "Failed to parse BSSGP %s message. Invalid message was: %s\n",
		     bssgp_pdu_str(pdu_type), msgb_hexdump(msg));
		if (pdu_type != BSSGP_PDUT_STATUS)
			return bssgp_tx_status(BSSGP_CAUSE_INV_MAND_INF, NULL, msg);
		return rc;
	}

	if (bvci == BVCI_SIGNALLING && TLVP_PRES_LEN(&tp, BSSGP_IE_BVCI, 2))
		bvci = tlvp_val16be(&tp, BSSGP_IE_BVCI);

	/* look-up or create the BTS context for this BVC */
	bctx = btsctx_by_bvci_nsei(bvci, nsei);

	if (bctx) {
		log_set_context(LOG_CTX_GB_BVC, bctx);
		rate_ctr_inc(rate_ctr_group_get_ctr(bctx->ctrg, BSSGP_CTR_PKTS_IN));
		rate_ctr_add(rate_ctr_group_get_ctr(bctx->ctrg, BSSGP_CTR_BYTES_IN),
			     msgb_bssgp_len(msg));
	}

	/* Always handle STATUS PDUs, even if they contain an invalid BVCI or
	 * are otherwise unexpected */
	if (pdu_type == BSSGP_PDUT_STATUS)
		/* Some exception has occurred */
		return bssgp_rx_status(msg, &tp, bvci, bctx);

	/* Only a RESET PDU can create a new BVC context, otherwise it must be
	 * registered if a BVCI is given. */
	if (!bctx && bvci != BVCI_SIGNALLING &&
	    pdu_type != BSSGP_PDUT_BVC_RESET) {
		LOGP(DLBSSGP, LOGL_NOTICE, "NSEI=%u/BVCI=%u Rejecting PDU type %s for unknown BVCI\n", nsei, bvci,
			bssgp_pdu_str(pdu_type));
		return bssgp_tx_status(BSSGP_CAUSE_UNKNOWN_BVCI, &bvci, msg);
	}

	if (ns_bvci == BVCI_SIGNALLING)
		rc = bssgp_rx_sign(msg, &tp, bctx);
	else if (ns_bvci == BVCI_PTM)
		rc = bssgp_tx_status(BSSGP_CAUSE_PDU_INCOMP_FEAT, NULL, msg);
	else if (bctx)
		rc = bssgp_rx_ptp(msg, &tp, bctx);
	else
		LOGP(DLBSSGP, LOGL_NOTICE,
		     "NSEI=%u/BVCI=%u Cannot handle PDU type %s for unknown BVCI, NS BVCI %u\n", nsei, bvci,
		     bssgp_pdu_str(pdu_type), ns_bvci);

	return rc;
}

int bssgp_tx_dl_ud(struct msgb *msg, uint16_t pdu_lifetime,
		   struct bssgp_dl_ud_par *dup)
{
	struct bssgp_bvc_ctx *bctx;
	struct bssgp_ud_hdr *budh;
	uint8_t llc_pdu_tlv_hdr_len = 2;
	uint8_t *llc_pdu_tlv;
	uint16_t msg_len = msg->len;
	uint16_t bvci = msgb_bvci(msg);
	uint16_t nsei = msgb_nsei(msg);
	uint16_t _pdu_lifetime = osmo_htons(pdu_lifetime); /* centi-seconds */
	uint16_t drx_params;

	OSMO_ASSERT(dup != NULL);

	/* Identifiers from UP: TLLI, BVCI, NSEI (all in msgb->cb) */
	if (bvci <= BVCI_PTM ) {
		LOGP(DLBSSGP, LOGL_ERROR, "Cannot send DL-UD to BVCI %u\n",
			bvci);
		msgb_free(msg);
		return -EINVAL;
	}

	bctx = btsctx_by_bvci_nsei(bvci, nsei);
	if (!bctx) {
		LOGP(DLBSSGP, LOGL_ERROR, "Cannot send DL-UD to unknown BVCI %u\n",
			bvci);
		msgb_free(msg);
		return -ENODEV;
	}

	if (msg->len > TVLV_MAX_ONEBYTE)
		llc_pdu_tlv_hdr_len += 1;

	/* prepend the tag and length of the LLC-PDU TLV */
	llc_pdu_tlv = msgb_push(msg, llc_pdu_tlv_hdr_len);
	llc_pdu_tlv[0] = BSSGP_IE_LLC_PDU;
	if (llc_pdu_tlv_hdr_len > 2) {
		llc_pdu_tlv[1] = msg_len >> 8;
		llc_pdu_tlv[2] = msg_len & 0xff;
	} else {
		llc_pdu_tlv[1] = msg_len & 0x7f;
		llc_pdu_tlv[1] |= 0x80;
	}

	/* FIXME: optional elements: Alignment, UTRAN CCO, LSA, PFI */

	/* Old TLLI to help BSS map from old->new */
	if (dup->tlli) {
		uint32_t tlli = osmo_htonl(*dup->tlli);
		msgb_tvlv_push(msg, BSSGP_IE_TLLI, 4, (uint8_t *) &tlli);
	}

	/* IMSI */
	if (dup->imsi && strlen(dup->imsi)) {
		uint8_t mi[GSM48_MID_MAX_SIZE];
/* gsm48_generate_mid_from_imsi() is guaranteed to never return more than 11,
 * but somehow gcc (8.2) is not smart enough to figure this out and claims that
 * the memcpy in msgb_tvlv_put() below will cause and out-of-bounds access up to
 * mi[131], which is wrong */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Warray-bounds"
		int imsi_len = gsm48_generate_mid_from_imsi(mi, dup->imsi);
		OSMO_ASSERT(imsi_len <= GSM48_MID_MAX_SIZE);
		if (imsi_len > 2)
			msgb_tvlv_push(msg, BSSGP_IE_IMSI,
				imsi_len-2, mi+2);
#pragma GCC diagnostic pop
	}

	/* DRX parameters */
	drx_params = osmo_htons(dup->drx_parms);
	msgb_tvlv_push(msg, BSSGP_IE_DRX_PARAMS, 2,
		(uint8_t *) &drx_params);

	/* FIXME: Priority */

	/* MS Radio Access Capability */
	if (dup->ms_ra_cap.len)
		msgb_tvlv_push(msg, BSSGP_IE_MS_RADIO_ACCESS_CAP,
			dup->ms_ra_cap.len, dup->ms_ra_cap.v);

	/* prepend the pdu lifetime */
	msgb_tvlv_push(msg, BSSGP_IE_PDU_LIFETIME, 2, (uint8_t *)&_pdu_lifetime);

	/* prepend the QoS profile, TLLI and pdu type */
	budh = (struct bssgp_ud_hdr *) msgb_push(msg, sizeof(*budh));
	memcpy(budh->qos_profile, dup->qos_profile, sizeof(budh->qos_profile));
	budh->tlli = osmo_htonl(msgb_tlli(msg));
	budh->pdu_type = BSSGP_PDUT_DL_UNITDATA;

	rate_ctr_inc(rate_ctr_group_get_ctr(bctx->ctrg, BSSGP_CTR_PKTS_OUT));
	rate_ctr_add(rate_ctr_group_get_ctr(bctx->ctrg, BSSGP_CTR_BYTES_OUT), msg->len);

	/* Identifiers down: BVCI, NSEI (in msgb->cb) */

	/* check if we have to go through per-ms flow control or can go
	 * directly to the per-BSS flow control */
	if (dup->fc)
		return bssgp_fc_in(dup->fc, msg, msg_len, bctx->fc);
	else
		return bssgp_fc_in(bctx->fc, msg, msg_len, NULL);
}

/* Send a single GMM-PAGING.req to a given NSEI/NS-BVCI */
int bssgp_tx_paging(uint16_t nsei, uint16_t ns_bvci,
		     struct bssgp_paging_info *pinfo)
{
	struct msgb *msg = bssgp_msgb_alloc();
	struct bssgp_normal_hdr *bgph =
			(struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
	uint16_t drx_params = osmo_htons(pinfo->drx_params);
	uint8_t mi[GSM48_MID_MAX_SIZE];
	int imsi_len = gsm48_generate_mid_from_imsi(mi, pinfo->imsi);
	struct gsm48_ra_id ra;

	if (imsi_len < 2)
		return -EINVAL;

	msgb_nsei(msg) = nsei;
	msgb_bvci(msg) = ns_bvci;

	if (pinfo->mode == BSSGP_PAGING_PS)
		bgph->pdu_type = BSSGP_PDUT_PAGING_PS;
	else
		bgph->pdu_type = BSSGP_PDUT_PAGING_CS;
	/* IMSI */
/* gsm48_generate_mid_from_imsi() is guaranteed to never return more than 11,
 * but somehow gcc (8.2) is not smart enough to figure this out and claims that
 * the memcpy in msgb_tvlv_put() below will cause and out-of-bounds access up to
 * mi[131], which is wrong */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Warray-bounds"
	OSMO_ASSERT(imsi_len <= GSM48_MID_MAX_SIZE);
	msgb_tvlv_put(msg, BSSGP_IE_IMSI, imsi_len-2, mi+2);
#pragma GCC diagnostic pop
	/* DRX Parameters */
	msgb_tvlv_put(msg, BSSGP_IE_DRX_PARAMS, 2,
			(uint8_t *) &drx_params);
	/* Scope */
	switch (pinfo->scope) {
	case BSSGP_PAGING_BSS_AREA:
		{
			uint8_t null = 0;
			msgb_tvlv_put(msg, BSSGP_IE_BSS_AREA_ID, 1, &null);
		}
		break;
	case BSSGP_PAGING_LOCATION_AREA:
		gsm48_encode_ra(&ra, &pinfo->raid);
		msgb_tvlv_put(msg, BSSGP_IE_LOCATION_AREA, 4, (const uint8_t *)&ra);
		break;
	case BSSGP_PAGING_ROUTEING_AREA:
		bssgp_msgb_ra_put(msg, &pinfo->raid);
		break;
	case BSSGP_PAGING_BVCI:
		{
			uint16_t bvci = osmo_htons(pinfo->bvci);
			msgb_tvlv_put(msg, BSSGP_IE_BVCI, 2, (uint8_t *)&bvci);
		}
		break;
	}
	/* QoS profile mandatory for PS */
	if (pinfo->mode == BSSGP_PAGING_PS)
		msgb_tvlv_put(msg, BSSGP_IE_QOS_PROFILE, 3, pinfo->qos);

	/* Optional (P-)TMSI */
	if (pinfo->ptmsi) {
		uint32_t ptmsi = osmo_htonl(*pinfo->ptmsi);
		msgb_tvlv_put(msg, BSSGP_IE_TMSI, 4, (uint8_t *) &ptmsi);
	}

	return bssgp_ns_send(bssgp_ns_send_data, msg);
}

void bssgp_set_log_ss(int ss)
{
	/* BSSGP has moved from DGPRS to DLGPRS, please update your code if it's
	 * still calling this function
	 */
}

/*!
 * \brief Flush the queue of the bssgp_flow_control
 * \param[in] The flow control object which holds the queue.
 */
void bssgp_fc_flush_queue(struct bssgp_flow_control *fc)
{
	struct bssgp_fc_queue_element *element, *tmp;

	llist_for_each_entry_safe(element, tmp, &fc->queue, list) {
		msgb_free(element->msg);
		llist_del(&element->list);
		talloc_free(element);
	}
}

/*!
 * \brief Flush the queues of all BSSGP contexts.
 */
void bssgp_flush_all_queues(void)
{
	struct bssgp_bvc_ctx *bctx;

	llist_for_each_entry(bctx, &bssgp_bvc_ctxts, list) {
		if (bctx->fc)
			bssgp_fc_flush_queue(bctx->fc);
	}
}
