/*! \file gprs_bssgp_bss.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/>.
 *
 */

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

#include <osmocom/core/msgb.h>
#include <osmocom/core/byteswap.h>
#include <osmocom/core/rate_ctr.h>
#include <osmocom/gsm/tlv.h>
#include <osmocom/core/talloc.h>
#include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/gprs/gprs_bssgp_bss.h>
#include <osmocom/gprs/gprs_ns.h>

#include "gprs_bssgp_internal.h"
#include "common_vty.h"

#define GSM_IMSI_LENGTH 17

uint8_t *bssgp_msgb_tlli_put(struct msgb *msg, uint32_t tlli)
{
	uint32_t _tlli = osmo_htonl(tlli);
	return msgb_tvlv_put(msg, BSSGP_IE_TLLI, 4, (uint8_t *) &_tlli);
}

uint8_t *bssgp_msgb_ra_put(struct msgb *msg, const struct gprs_ra_id *ra_id)
{
	struct gsm48_ra_id ra;

	gsm48_encode_ra(&ra, ra_id);
	return msgb_tvlv_put(msg, BSSGP_IE_ROUTEING_AREA, sizeof(ra), (const uint8_t *)&ra);
}

/*! GMM-SUSPEND.req (Chapter 10.3.6) */
int bssgp_tx_suspend(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));

	LOGP(DBSSGP, LOGL_NOTICE, "BSSGP (BVCI=0) Tx SUSPEND (TLLI=0x%04x)\n",
		tlli);
	msgb_nsei(msg) = nsei;
	msgb_bvci(msg) = 0; /* Signalling */
	bgph->pdu_type = BSSGP_PDUT_SUSPEND;

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

	return bssgp_ns_send(bssgp_ns_send_data, msg);
}

/*! GMM-RESUME.req (Chapter 10.3.9) */
int bssgp_tx_resume(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));

	LOGP(DBSSGP, LOGL_NOTICE, "BSSGP (BVCI=0) Tx RESUME (TLLI=0x%04x)\n",
		tlli);
	msgb_nsei(msg) = nsei;
	msgb_bvci(msg) = 0; /* Signalling */
	bgph->pdu_type = BSSGP_PDUT_RESUME;

	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);
}

/*! Transmit RA-CAPABILITY-UPDATE (10.3.3) */
int bssgp_tx_ra_capa_upd(struct bssgp_bvc_ctx *bctx, uint32_t tlli, uint8_t tag)
{
	struct msgb *msg = bssgp_msgb_alloc();
	struct bssgp_normal_hdr *bgph =
		(struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));

	LOGP(DBSSGP, LOGL_NOTICE, "BSSGP (BVCI=%u) Tx RA-CAPA-UPD (TLLI=0x%04x)\n",
		bctx->bvci, tlli);

	/* set NSEI and BVCI in msgb cb */
	msgb_nsei(msg) = bctx->nsei;
	msgb_bvci(msg) = bctx->bvci;

	bgph->pdu_type = BSSGP_PDUT_RA_CAPA_UDPATE;
	bssgp_msgb_tlli_put(msg, tlli);

	msgb_tvlv_put(msg, BSSGP_IE_TAG, 1, &tag);

	return bssgp_ns_send(bssgp_ns_send_data, msg);
}

/* first common part of RADIO-STATUS */
static struct msgb *common_tx_radio_status(struct bssgp_bvc_ctx *bctx)
{
	struct msgb *msg = bssgp_msgb_alloc();
	struct bssgp_normal_hdr *bgph =
		(struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));

	LOGP(DBSSGP, LOGL_NOTICE, "BSSGP (BVCI=%u) Tx RADIO-STATUS ",
		bctx->bvci);

	/* set NSEI and BVCI in msgb cb */
	msgb_nsei(msg) = bctx->nsei;
	msgb_bvci(msg) = bctx->bvci;

	bgph->pdu_type = BSSGP_PDUT_RADIO_STATUS;

	return msg;
}

/* second common part of RADIO-STATUS */
static int common_tx_radio_status2(struct msgb *msg, uint8_t cause)
{
	msgb_tvlv_put(msg, BSSGP_IE_CAUSE, 1, &cause);
	LOGPC(DBSSGP, LOGL_NOTICE, "CAUSE=%s\n", bssgp_cause_str(cause));

	return bssgp_ns_send(bssgp_ns_send_data, msg);
}

/*! Transmit RADIO-STATUS for TLLI (10.3.5) */
int bssgp_tx_radio_status_tlli(struct bssgp_bvc_ctx *bctx, uint8_t cause,
				uint32_t tlli)
{
	struct msgb *msg = common_tx_radio_status(bctx);

	if (!msg)
		return -ENOMEM;
	bssgp_msgb_tlli_put(msg, tlli);
	LOGPC(DBSSGP, LOGL_NOTICE, "TLLI=0x%08x ", tlli);

	return common_tx_radio_status2(msg, cause);
}

/*! Transmit RADIO-STATUS for TMSI (10.3.5) */
int bssgp_tx_radio_status_tmsi(struct bssgp_bvc_ctx *bctx, uint8_t cause,
				uint32_t tmsi)
{
	struct msgb *msg = common_tx_radio_status(bctx);
	uint32_t _tmsi = osmo_htonl(tmsi);

	if (!msg)
		return -ENOMEM;
	msgb_tvlv_put(msg, BSSGP_IE_TMSI, 4, (uint8_t *)&_tmsi);
	LOGPC(DBSSGP, LOGL_NOTICE, "TMSI=0x%08x ", tmsi);

	return common_tx_radio_status2(msg, cause);
}

/*! Transmit RADIO-STATUS for IMSI (10.3.5) */
int bssgp_tx_radio_status_imsi(struct bssgp_bvc_ctx *bctx, uint8_t cause,
				const char *imsi)
{
	struct msgb *msg = common_tx_radio_status(bctx);
	uint8_t mi[GSM48_MID_MAX_SIZE];
	int imsi_len = gsm48_generate_mid_from_imsi(mi, imsi);

	if (!msg)
		return -ENOMEM;
/* 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);
	/* strip the MI type and length values (2 bytes) */
	if (imsi_len > 2)
		msgb_tvlv_put(msg, BSSGP_IE_IMSI, imsi_len-2, mi+2);
#pragma GCC diagnostic pop
	LOGPC(DBSSGP, LOGL_NOTICE, "IMSI=%s ", imsi);

	return common_tx_radio_status2(msg, cause);
}

/*! Transmit FLUSH-LL-ACK (Chapter 10.4.2) */
int bssgp_tx_flush_ll_ack(struct bssgp_bvc_ctx *bctx, uint32_t tlli,
			   uint8_t action, uint16_t bvci_new,
			   uint32_t num_octets)
{
	struct msgb *msg = bssgp_msgb_alloc();
	struct bssgp_normal_hdr *bgph =
			(struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
	uint16_t _bvci_new = osmo_htons(bvci_new);
	uint32_t _oct_aff = osmo_htonl(num_octets & 0xFFFFFF);

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

	bssgp_msgb_tlli_put(msg, tlli);
	msgb_tvlv_put(msg, BSSGP_IE_FLUSH_ACTION, 1, &action);
	if (action == 1) /* transferred */
		msgb_tvlv_put(msg, BSSGP_IE_BVCI, 2, (uint8_t *) &_bvci_new);
	msgb_tvlv_put(msg, BSSGP_IE_NUM_OCT_AFF, 3, (uint8_t *) &_oct_aff);

	return bssgp_ns_send(bssgp_ns_send_data, msg);
}

/*! Transmit LLC-DISCARDED (Chapter 10.4.3) */
int bssgp_tx_llc_discarded(struct bssgp_bvc_ctx *bctx, uint32_t tlli,
			   uint8_t num_frames, uint32_t num_octets)
{
	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(bctx->bvci);
	uint32_t _oct_aff = osmo_htonl(num_octets & 0xFFFFFF);

	LOGP(DBSSGP, LOGL_NOTICE, "BSSGP (BVCI=%u) Tx LLC-DISCARDED "
	     "TLLI=0x%04x, FRAMES=%u, OCTETS=%u\n", bctx->bvci, tlli,
	     num_frames, num_octets);
	msgb_nsei(msg) = bctx->nsei;
	msgb_bvci(msg) = 0; /* Signalling */
	bgph->pdu_type = BSSGP_PDUT_LLC_DISCARD;

	bssgp_msgb_tlli_put(msg, tlli);

	msgb_tvlv_put(msg, BSSGP_IE_LLC_FRAMES_DISCARDED, 1, &num_frames);
	msgb_tvlv_put(msg, BSSGP_IE_BVCI, 2, (uint8_t *) &_bvci);
	msgb_tvlv_put(msg, BSSGP_IE_NUM_OCT_AFF, 3, ((uint8_t *) &_oct_aff) + 1);

	return bssgp_ns_send(bssgp_ns_send_data, msg);
}

/*! Transmit a BVC-BLOCK message (Chapter 10.4.8) */
int bssgp_tx_bvc_block(struct bssgp_bvc_ctx *bctx, uint8_t cause)
{
	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(bctx->bvci);

	LOGP(DBSSGP, LOGL_NOTICE, "BSSGP (BVCI=%u) Tx BVC-BLOCK "
		"CAUSE=%s\n", bctx->bvci, bssgp_cause_str(cause));

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

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

	return bssgp_ns_send(bssgp_ns_send_data, msg);
}

/*! Transmit a BVC-UNBLOCK message (Chapter 10.4.10) */
int bssgp_tx_bvc_unblock(struct bssgp_bvc_ctx *bctx)
{
	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(bctx->bvci);

	LOGP(DBSSGP, LOGL_NOTICE, "BSSGP (BVCI=%u) Tx BVC-UNBLOCK\n", bctx->bvci);

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

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

	return bssgp_ns_send(bssgp_ns_send_data, msg);
}

/*! Transmit a BVC-RESET message (Chapter 10.4.12) */
int bssgp_tx_bvc_reset2(struct bssgp_bvc_ctx *bctx, uint16_t bvci, uint8_t cause, bool add_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);

	LOGP(DBSSGP, LOGL_NOTICE, "BSSGP (BVCI=%u) Tx BVC-RESET "
		"CAUSE=%s\n", bvci, bssgp_cause_str(cause));

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

	msgb_tvlv_put(msg, BSSGP_IE_BVCI, 2, (uint8_t *) &_bvci);
	msgb_tvlv_put(msg, BSSGP_IE_CAUSE, 1, &cause);
	if (add_cell_id) {
		uint8_t bssgp_cid[8];
		bssgp_create_cell_id(bssgp_cid, &bctx->ra_id, bctx->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);
}
int bssgp_tx_bvc_reset(struct bssgp_bvc_ctx *bctx, uint16_t bvci, uint8_t cause)
{
	return bssgp_tx_bvc_reset2(bctx, bvci, cause, bvci != BVCI_PTM);
}

/*! Transmit a FLOW_CONTROL-BVC (Chapter 10.4.4)
 *  \param[in] bctx BVC Context
 *  \param[in] tag Additional tag to identify acknowledge
 *  \param[in] bucket_size Maximum bucket size in octets
 *  \param[in] bucket_leak_rate Bucket leak rate in octets/sec
 *  \param[in] bmax_default_ms Maximum bucket size default for MS
 *  \param[in] r_default_ms Bucket leak rate default for MS in octets/sec
 *  \param[in] bucket_full_ratio Ratio (in percent) of queue filling
 *  \param[in] queue_delay_ms Average queuing delay in milliseconds
 */
int bssgp_tx_fc_bvc(struct bssgp_bvc_ctx *bctx, uint8_t tag,
		    uint32_t bucket_size, uint32_t bucket_leak_rate,
		    uint32_t bmax_default_ms, uint32_t r_default_ms,
		    uint8_t *bucket_full_ratio, uint32_t *queue_delay_ms)
{
	struct msgb *msg;
	struct bssgp_normal_hdr *bgph;
	uint16_t e_bucket_size, e_leak_rate, e_bmax_default_ms, e_r_default_ms;
	uint16_t e_queue_delay = 0; /* to make gcc happy */

	if ((bucket_size / 100) > 0xffff)
		return -EINVAL;
	e_bucket_size = osmo_htons(bucket_size / 100);

	if ((bucket_leak_rate * 8 / 100) > 0xffff)
		return -EINVAL;
	e_leak_rate = osmo_htons((bucket_leak_rate * 8) / 100);

	if ((bmax_default_ms / 100) > 0xffff)
		return -EINVAL;
	e_bmax_default_ms = osmo_htons(bmax_default_ms / 100);

	if ((r_default_ms * 8 / 100) > 0xffff)
		return -EINVAL;
	e_r_default_ms = osmo_htons((r_default_ms * 8) / 100);

	if (queue_delay_ms) {
		if ((*queue_delay_ms / 10) > 60000)
			return -EINVAL;
		else if (*queue_delay_ms == 0xFFFFFFFF)
			e_queue_delay = 0xFFFF;
		else
			e_queue_delay = osmo_htons(*queue_delay_ms / 10);
	}

	msg = bssgp_msgb_alloc();
	bgph = (struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
	msgb_nsei(msg) = bctx->nsei;
	msgb_bvci(msg) = bctx->bvci;
	bgph->pdu_type = BSSGP_PDUT_FLOW_CONTROL_BVC;

	msgb_tvlv_put(msg, BSSGP_IE_TAG, sizeof(tag), (uint8_t *)&tag);
	msgb_tvlv_put(msg, BSSGP_IE_BVC_BUCKET_SIZE,
		     sizeof(e_bucket_size), (uint8_t *) &e_bucket_size);
	msgb_tvlv_put(msg, BSSGP_IE_BUCKET_LEAK_RATE,
		      sizeof(e_leak_rate), (uint8_t *) &e_leak_rate);
	msgb_tvlv_put(msg, BSSGP_IE_BMAX_DEFAULT_MS,
		      sizeof(e_bmax_default_ms),
					(uint8_t *) &e_bmax_default_ms);
	msgb_tvlv_put(msg, BSSGP_IE_R_DEFAULT_MS,
		      sizeof(e_r_default_ms), (uint8_t *) &e_r_default_ms);
	if (bucket_full_ratio)
		msgb_tvlv_put(msg, BSSGP_IE_BUCKET_FULL_RATIO,
			      1, bucket_full_ratio);
	if (queue_delay_ms)
		msgb_tvlv_put(msg, BSSGP_IE_BVC_MEASUREMENT,
			      sizeof(e_queue_delay),
			      (uint8_t *) &e_queue_delay);

	return bssgp_ns_send(bssgp_ns_send_data, msg);
}

/*! Transmit a FLOW_CONTROL-MS (Chapter 10.4.6)
 *  \param[in] bctx BVC Context
 *  \param[in] tlli TLLI to identify MS
 *  \param[in] tag Additional tag to identify acknowledge
 *  \param[in] ms_bucket_size Maximum bucket size in octets
 *  \param[in] bucket_leak_rate Bucket leak rate in octets/sec
 *  \param[in] bucket_full_ratio Ratio (in percent) of queue filling
 */
int bssgp_tx_fc_ms(struct bssgp_bvc_ctx *bctx, uint32_t tlli, uint8_t tag,
		   uint32_t ms_bucket_size, uint32_t bucket_leak_rate,
		   uint8_t *bucket_full_ratio)
{
	struct msgb *msg;
	struct bssgp_normal_hdr *bgph;
	uint16_t e_bucket_size, e_leak_rate;

	if ((ms_bucket_size / 100) > 0xffff)
		return -EINVAL;
	e_bucket_size = ms_bucket_size / 100;

	if ((bucket_leak_rate * 8 / 100) > 0xffff)
		return -EINVAL;
	e_leak_rate = (bucket_leak_rate * 8) / 100;

	msg = bssgp_msgb_alloc();
	bgph = (struct bssgp_normal_hdr *) msgb_put(msg, sizeof(*bgph));
	msgb_nsei(msg) = bctx->nsei;
	msgb_bvci(msg) = bctx->bvci;
	bgph->pdu_type = BSSGP_PDUT_FLOW_CONTROL_MS;

	bssgp_msgb_tlli_put(msg, tlli);
	msgb_tvlv_put(msg, BSSGP_IE_TAG, sizeof(tag), (uint8_t *)&tag);
	msgb_tvlv_put(msg, BSSGP_IE_MS_BUCKET_SIZE,
		      sizeof(e_bucket_size), (uint8_t *) &e_bucket_size);
	msgb_tvlv_put(msg, BSSGP_IE_BUCKET_LEAK_RATE,
		      sizeof(e_leak_rate), (uint8_t *) &e_leak_rate);
	if (bucket_full_ratio)
		msgb_tvlv_put(msg, BSSGP_IE_BUCKET_FULL_RATIO,
			      1, bucket_full_ratio);

	return bssgp_ns_send(bssgp_ns_send_data, msg);
}

/*! RL-UL-UNITDATA.req (Chapter 10.2.2)
 *  \param[in] bctx BVC Context
 *  \param[in] tlli TLLI to identify MS
 *  \param[in] qos_profile Pointer to three octests of QoS profile
 *  \param[in] llc_pdu msgb pointer containing UL Unitdata IE payload
 */
int bssgp_tx_ul_ud(struct bssgp_bvc_ctx *bctx, uint32_t tlli,
		   const uint8_t *qos_profile, struct msgb *llc_pdu)
{
	struct msgb *msg = llc_pdu;
	uint8_t bssgp_cid[8];
	uint8_t bssgp_align[3] = {0, 0, 0};
	struct bssgp_ud_hdr *budh;
	int align = sizeof(*budh);

	/* FIXME: Optional LSA Identifier List, PFI */

	/* Cell Identifier */
	bssgp_create_cell_id(bssgp_cid, &bctx->ra_id, bctx->cell_id);
	align += 2; /* add T+L */
	align += sizeof(bssgp_cid);

	/* First push alignment IE */
	align += 2; /* add T+L */
	align = (4 - align) & 3; /* how many octest are required to align? */
	msgb_tvlv_push(msg, BSSGP_IE_ALIGNMENT, align, bssgp_align);

	/* Push other IEs */
	msgb_tvlv_push(msg, BSSGP_IE_CELL_ID, sizeof(bssgp_cid), bssgp_cid);

	/* User Data Header */
	budh = (struct bssgp_ud_hdr *) msgb_push(msg, sizeof(*budh));
	budh->tlli = osmo_htonl(tlli);
	memcpy(budh->qos_profile, qos_profile, 3);
	budh->pdu_type = BSSGP_PDUT_UL_UNITDATA;

	/* set NSEI and BVCI in msgb cb */
	msgb_nsei(msg) = bctx->nsei;
	msgb_bvci(msg) = bctx->bvci;

	rate_ctr_inc(&bctx->ctrg->ctr[BSSGP_CTR_PKTS_OUT]);
	rate_ctr_add(&bctx->ctrg->ctr[BSSGP_CTR_BYTES_OUT], msg->len);

	return bssgp_ns_send(bssgp_ns_send_data, msg);
}

/* Parse a single GMM-PAGING.req to a given NSEI/NS-BVCI */
int bssgp_rx_paging(struct bssgp_paging_info *pinfo,
		    struct msgb *msg)
{
	struct bssgp_normal_hdr *bgph =
			(struct bssgp_normal_hdr *) msgb_bssgph(msg);
	struct tlv_parsed tp;
	uint8_t ra[6];
	int rc, data_len;

	memset(ra, 0, sizeof(ra));

	data_len = msgb_bssgp_len(msg) - sizeof(*bgph);
	rc = bssgp_tlv_parse(&tp, bgph->data, data_len);
	if (rc < 0)
		goto err_mand_ie;

	switch (bgph->pdu_type) {
	case BSSGP_PDUT_PAGING_PS:
		pinfo->mode = BSSGP_PAGING_PS;
		break;
	case BSSGP_PDUT_PAGING_CS:
		pinfo->mode = BSSGP_PAGING_CS;
		break;
	default:
		return -EINVAL;
	}

	/* IMSI */
	if (!TLVP_PRESENT(&tp, BSSGP_IE_IMSI))
		goto err_mand_ie;
	if (!pinfo->imsi)
		pinfo->imsi = talloc_zero_size(pinfo, GSM_IMSI_LENGTH);
	gsm48_mi_to_string(pinfo->imsi, GSM_IMSI_LENGTH,
			   TLVP_VAL(&tp, BSSGP_IE_IMSI),
			   TLVP_LEN(&tp, BSSGP_IE_IMSI));

	/* DRX Parameters */
	if (!TLVP_PRESENT(&tp, BSSGP_IE_DRX_PARAMS))
		goto err_mand_ie;
	pinfo->drx_params = tlvp_val16be(&tp, BSSGP_IE_DRX_PARAMS);

	/* Scope */
	if (TLVP_PRESENT(&tp, BSSGP_IE_BSS_AREA_ID)) {
		pinfo->scope = BSSGP_PAGING_BSS_AREA;
	} else if (TLVP_PRESENT(&tp, BSSGP_IE_LOCATION_AREA)) {
		pinfo->scope = BSSGP_PAGING_LOCATION_AREA;
		memcpy(ra, TLVP_VAL(&tp, BSSGP_IE_LOCATION_AREA),
			TLVP_LEN(&tp, BSSGP_IE_LOCATION_AREA));
		gsm48_parse_ra(&pinfo->raid, ra);
	} else if (TLVP_PRESENT(&tp, BSSGP_IE_ROUTEING_AREA)) {
		pinfo->scope = BSSGP_PAGING_ROUTEING_AREA;
		memcpy(ra, TLVP_VAL(&tp, BSSGP_IE_ROUTEING_AREA),
			TLVP_LEN(&tp, BSSGP_IE_ROUTEING_AREA));
		gsm48_parse_ra(&pinfo->raid, ra);
	} else if (TLVP_PRESENT(&tp, BSSGP_IE_BVCI)) {
		pinfo->scope = BSSGP_PAGING_BVCI;
		pinfo->bvci = tlvp_val16be(&tp, BSSGP_IE_BVCI);
	} else
		return -EINVAL;

	/* QoS profile mandatory for PS */
	if (pinfo->mode == BSSGP_PAGING_PS) {
		if (!TLVP_PRESENT(&tp, BSSGP_IE_QOS_PROFILE))
			goto err_cond_ie;
		if (TLVP_LEN(&tp, BSSGP_IE_QOS_PROFILE) < 3)
			goto err;

		memcpy(&pinfo->qos, TLVP_VAL(&tp, BSSGP_IE_QOS_PROFILE),
			3);
	}

	/* Optional (P-)TMSI */
	if (TLVP_PRESENT(&tp, BSSGP_IE_TMSI) &&
	    TLVP_LEN(&tp, BSSGP_IE_TMSI) >= 4) {
		if (!pinfo->ptmsi)
			pinfo->ptmsi = talloc_zero_size(pinfo, sizeof(uint32_t));
		*(pinfo->ptmsi) = osmo_load32be(TLVP_VAL(&tp, BSSGP_IE_TMSI));
	}

	return 0;

err_mand_ie:
err_cond_ie:
err:
	/* FIXME */
	return 0;
}
