/*! \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"

#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(DLBSSGP, 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(DLBSSGP, 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(DLBSSGP, 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(DLBSSGP, 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(DLBSSGP, 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(DLBSSGP, 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(DLBSSGP, 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(DLBSSGP, 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(DLBSSGP, 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(DLBSSGP, 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(DLBSSGP, 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)
{
	if (add_cell_id)
		return bssgp_tx_bvc_reset_nsei_bvci(bctx->nsei, bvci, cause, &bctx->ra_id, bctx->cell_id);
	else
		return bssgp_tx_bvc_reset_nsei_bvci(bctx->nsei, bvci, cause, NULL, 0);
}
int bssgp_tx_bvc_reset(struct bssgp_bvc_ctx *bctx, uint16_t bvci, uint8_t cause)
{
	/* The Cell Identifier IE is mandatory in the BVC-RESET PDU sent from BSS to SGSN in order to reset a
	 * BVC corresponding to a PTP functional entity. The Cell Identifier IE shall not be used in any other
	 * BVC-RESET PDU. */
	switch (bvci) {
	case BVCI_SIGNALLING:
	case BVCI_PTM:
		return bssgp_tx_bvc_reset2(bctx, bvci, cause, false);
	default:
		return bssgp_tx_bvc_reset2(bctx, bvci, cause, true);
	}
}

/*! 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(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);

	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_PRES_LEN(&tp, BSSGP_IE_DRX_PARAMS, 2))
		goto err_mand_ie;
	pinfo->drx_params = tlvp_val16be(&tp, BSSGP_IE_DRX_PARAMS);

	/* Scope */
	if (TLVP_PRES_LEN(&tp, BSSGP_IE_BSS_AREA_ID, 1)) {
		pinfo->scope = BSSGP_PAGING_BSS_AREA;
	} else if (TLVP_PRES_LEN(&tp, BSSGP_IE_LOCATION_AREA, 5)) {
		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_PRES_LEN(&tp, BSSGP_IE_ROUTEING_AREA, 6)) {
		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_PRES_LEN(&tp, BSSGP_IE_BVCI, 2)) {
		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_PRES_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;
}
