/*! \file gprs_ns2_message.c
 * NS-over-FR-over-GRE implementation.
 * GPRS Networks Service (NS) messages on the Gb interface.
 * 3GPP TS 08.16 version 8.0.1 Release 1999 / ETSI TS 101 299 V8.0.1 (2002-05)
 * as well as its successor 3GPP TS 48.016 */

/* (C) 2020 sysmocom - s.f.m.c. GmbH
 * Author: Alexander Couzens <lynxis@fe80.eu>
 *
 * 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 <osmocom/core/byteswap.h>
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/stat_item.h>
#include <osmocom/core/stats.h>
#include <osmocom/gsm/tlv.h>
#include <osmocom/gprs/gprs_msgb.h>
#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/gprs/protocol/gsm_08_16.h>

#include "gprs_ns2_internal.h"

#define ERR_IF_NSVC_USES_SNS(nsvc, reason)						\
	do {										\
		if (!nsvc->nse->bss_sns_fi)						\
			break;								\
		LOGNSVC(nsvc, LOGL_DEBUG, "invalid packet %s with SNS\n", reason);	\
	} while (0)

enum ns_ctr {
	NS_CTR_PKTS_IN,
	NS_CTR_PKTS_OUT,
	NS_CTR_BYTES_IN,
	NS_CTR_BYTES_OUT,
	NS_CTR_BLOCKED,
	NS_CTR_DEAD,
	NS_CTR_REPLACED,
	NS_CTR_NSEI_CHG,
	NS_CTR_INV_VCI,
	NS_CTR_INV_NSEI,
	NS_CTR_LOST_ALIVE,
	NS_CTR_LOST_RESET,
};



static int gprs_ns2_validate_reset(struct gprs_ns2_vc *nsvc, struct msgb *msg, struct tlv_parsed *tp, uint8_t *cause)
{
	if (!TLVP_PRES_LEN(tp, NS_IE_CAUSE, 1) ||
	    !TLVP_PRES_LEN(tp, NS_IE_VCI, 2) || !TLVP_PRES_LEN(tp, NS_IE_NSEI, 2)) {
		*cause = NS_CAUSE_MISSING_ESSENT_IE;
		return -1;
	}

	return 0;
}

static int gprs_ns2_validate_reset_ack(struct gprs_ns2_vc *nsvc, struct msgb *msg, struct tlv_parsed *tp, uint8_t *cause)
{
	if (!TLVP_PRES_LEN(tp, NS_IE_VCI, 2) || !TLVP_PRES_LEN(tp, NS_IE_NSEI, 2)) {
		*cause = NS_CAUSE_MISSING_ESSENT_IE;
		return -1;
	}

	return 0;
}

static int gprs_ns2_validate_block(struct gprs_ns2_vc *nsvc, struct msgb *msg, struct tlv_parsed *tp, uint8_t *cause)
{
	if (!TLVP_PRES_LEN(tp, NS_IE_VCI, 2) || !TLVP_PRES_LEN(tp, NS_IE_CAUSE, 1)) {
		*cause = NS_CAUSE_MISSING_ESSENT_IE;
		return -1;
	}

	return 0;
}

static int gprs_ns2_validate_block_ack(struct gprs_ns2_vc *nsvc, struct msgb *msg, struct tlv_parsed *tp, uint8_t *cause)
{
	if (!TLVP_PRES_LEN(tp, NS_IE_VCI, 2)) {
		*cause = NS_CAUSE_MISSING_ESSENT_IE;
		return -1;
	}

	return 0;
}

static int gprs_ns2_validate_status(struct gprs_ns2_vc *nsvc, struct msgb *msg, struct tlv_parsed *tp, uint8_t *cause)
{

	if (!TLVP_PRES_LEN(tp, NS_IE_CAUSE, 1)) {
		*cause = NS_CAUSE_MISSING_ESSENT_IE;
		return -1;
	}

	uint8_t _cause = tlvp_val8(tp, NS_IE_VCI, 0);

	switch (_cause) {
	case NS_CAUSE_NSVC_BLOCKED:
	case NS_CAUSE_NSVC_UNKNOWN:
		if (!TLVP_PRES_LEN(tp, NS_IE_CAUSE, 1)) {
			*cause = NS_CAUSE_MISSING_ESSENT_IE;
			return -1;
		}
		break;
	case NS_CAUSE_SEM_INCORR_PDU:
	case NS_CAUSE_PDU_INCOMP_PSTATE:
	case NS_CAUSE_PROTO_ERR_UNSPEC:
	case NS_CAUSE_INVAL_ESSENT_IE:
	case NS_CAUSE_MISSING_ESSENT_IE:
		if (!TLVP_PRES_LEN(tp, NS_IE_CAUSE, 1)) {
			*cause = NS_CAUSE_MISSING_ESSENT_IE;
			return -1;
		}
		break;
	case NS_CAUSE_BVCI_UNKNOWN:
		if (!TLVP_PRES_LEN(tp, NS_IE_BVCI, 2)) {
			*cause = NS_CAUSE_MISSING_ESSENT_IE;
			return -1;
		}
		break;
	case NS_CAUSE_UNKN_IP_TEST_FAILED:
		if (!TLVP_PRESENT(tp, NS_IE_IPv4_LIST) && !TLVP_PRESENT(tp, NS_IE_IPv6_LIST)) {
			*cause = NS_CAUSE_MISSING_ESSENT_IE;
			return -1;
		}
		break;
	}

	return 0;
}

int gprs_ns2_validate(struct gprs_ns2_vc *nsvc,
		      uint8_t pdu_type,
		      struct msgb *msg,
		      struct tlv_parsed *tp,
		      uint8_t *cause)
{
	switch (pdu_type) {
	case NS_PDUT_RESET:
		return gprs_ns2_validate_reset(nsvc, msg, tp, cause);
	case NS_PDUT_RESET_ACK:
		return gprs_ns2_validate_reset_ack(nsvc, msg, tp, cause);
	case NS_PDUT_BLOCK:
		return gprs_ns2_validate_block(nsvc, msg, tp, cause);
	case NS_PDUT_BLOCK_ACK:
		return gprs_ns2_validate_block_ack(nsvc, msg, tp, cause);
	case NS_PDUT_STATUS:
		return gprs_ns2_validate_status(nsvc, msg, tp, cause);

	/* following PDUs doesn't have any payloads */
	case NS_PDUT_ALIVE:
	case NS_PDUT_ALIVE_ACK:
	case NS_PDUT_UNBLOCK:
	case NS_PDUT_UNBLOCK_ACK:
		if (msgb_l2len(msg) != sizeof(struct gprs_ns_hdr)) {
			*cause = NS_CAUSE_PROTO_ERR_UNSPEC;
			return -1;
		}
		break;
	}

	return 0;
}


/* transmit functions */
static int ns2_tx_simple(struct gprs_ns2_vc *nsvc, uint8_t pdu_type)
{
	struct msgb *msg = gprs_ns2_msgb_alloc();
	struct gprs_ns_hdr *nsh;

	log_set_context(LOG_CTX_GB_NSE, nsvc->nse);
	log_set_context(LOG_CTX_GB_NSVC, nsvc);

	if (!msg)
		return -ENOMEM;

	msg->l2h = msgb_put(msg, sizeof(*nsh));
	nsh = (struct gprs_ns_hdr *) msg->l2h;

	nsh->pdu_type = pdu_type;

	return nsvc->bind->send_vc(nsvc, msg);
}

/*! Transmit a NS-BLOCK on a given NS-VC.
 *  \param[in] vc NS-VC on which the NS-BLOCK is to be transmitted
 *  \param[in] cause Numeric NS Cause value
 *  \returns 0 in case of success */
int ns2_tx_block(struct gprs_ns2_vc *nsvc, uint8_t cause)
{
	struct msgb *msg;
	struct gprs_ns_hdr *nsh;
	uint16_t nsvci = osmo_htons(nsvc->nsvci);

	log_set_context(LOG_CTX_GB_NSE, nsvc->nse);
	log_set_context(LOG_CTX_GB_NSVC, nsvc);

	ERR_IF_NSVC_USES_SNS(nsvc, "transmit NS BLOCK");

	msg = gprs_ns2_msgb_alloc();
	if (!msg)
		return -ENOMEM;

	LOGNSVC(nsvc, LOGL_INFO, "Tx NS BLOCK (cause=%s)\n", gprs_ns2_cause_str(cause));

	rate_ctr_inc(&nsvc->ctrg->ctr[NS_CTR_BLOCKED]);

	msg->l2h = msgb_put(msg, sizeof(*nsh));
	nsh = (struct gprs_ns_hdr *) msg->l2h;
	nsh->pdu_type = NS_PDUT_BLOCK;

	msgb_tvlv_put(msg, NS_IE_CAUSE, 1, &cause);
	msgb_tvlv_put(msg, NS_IE_VCI, 2, (uint8_t *) &nsvci);

	return nsvc->bind->send_vc(nsvc, msg);
}

/*! Transmit a NS-BLOCK-ACK on a given NS-VC.
 *  \param[in] nsvc NS-VC on which the NS-BLOCK is to be transmitted
 *  \returns 0 in case of success */
int ns2_tx_block_ack(struct gprs_ns2_vc *nsvc)
{
	struct msgb *msg;
	struct gprs_ns_hdr *nsh;
	uint16_t nsvci = osmo_htons(nsvc->nsvci);

	log_set_context(LOG_CTX_GB_NSE, nsvc->nse);
	log_set_context(LOG_CTX_GB_NSVC, nsvc);

	ERR_IF_NSVC_USES_SNS(nsvc, "transmit NS BLOCK ACK");

	msg = gprs_ns2_msgb_alloc();
	if (!msg)
		return -ENOMEM;

	LOGNSVC(nsvc, LOGL_INFO, "Tx NS BLOCK ACK\n");

	msg->l2h = msgb_put(msg, sizeof(*nsh));
	nsh = (struct gprs_ns_hdr *) msg->l2h;
	nsh->pdu_type = NS_PDUT_BLOCK_ACK;

	msgb_tvlv_put(msg, NS_IE_VCI, 2, (uint8_t *) &nsvci);

	return nsvc->bind->send_vc(nsvc, msg);
}

/*! Transmit a NS-RESET on a given NS-VC.
 *  \param[in] nsvc NS-VC used for transmission
 *  \paam[in] cause Numeric NS cause value
 *  \returns 0 in case of success */
int ns2_tx_reset(struct gprs_ns2_vc *nsvc, uint8_t cause)
{
	struct msgb *msg;
	struct gprs_ns_hdr *nsh;
	uint16_t nsvci = osmo_htons(nsvc->nsvci);
	uint16_t nsei = osmo_htons(nsvc->nse->nsei);

	log_set_context(LOG_CTX_GB_NSE, nsvc->nse);
	log_set_context(LOG_CTX_GB_NSVC, nsvc);

	ERR_IF_NSVC_USES_SNS(nsvc, "transmit NS RESET");

	msg = gprs_ns2_msgb_alloc();
	if (!msg)
		return -ENOMEM;

	LOGNSVC(nsvc, LOGL_INFO, "Tx NS RESET (cause=%s)\n", gprs_ns2_cause_str(cause));

	msg->l2h = msgb_put(msg, sizeof(*nsh));
	nsh = (struct gprs_ns_hdr *) msg->l2h;
	nsh->pdu_type = NS_PDUT_RESET;

	msgb_tvlv_put(msg, NS_IE_CAUSE, 1, &cause);
	msgb_tvlv_put(msg, NS_IE_VCI, 2, (uint8_t *) &nsvci);
	msgb_tvlv_put(msg, NS_IE_NSEI, 2, (uint8_t *) &nsei);

	return nsvc->bind->send_vc(nsvc, msg);
}

/*! Transmit a NS-RESET-ACK on a given NS-VC.
 *  \param[in] nsvc NS-VC used for transmission
 *  \returns 0 in case of success */
int ns2_tx_reset_ack(struct gprs_ns2_vc *nsvc)
{
	struct msgb *msg;
	struct gprs_ns_hdr *nsh;
	uint16_t nsvci, nsei;

	/* Section 9.2.6 */
	log_set_context(LOG_CTX_GB_NSE, nsvc->nse);
	log_set_context(LOG_CTX_GB_NSVC, nsvc);

	ERR_IF_NSVC_USES_SNS(nsvc, "transmit NS RESET ACK");

	msg = gprs_ns2_msgb_alloc();
	if (!msg)
		return -ENOMEM;

	nsvci = osmo_htons(nsvc->nsvci);
	nsei = osmo_htons(nsvc->nse->nsei);

	msg->l2h = msgb_put(msg, sizeof(*nsh));
	nsh = (struct gprs_ns_hdr *) msg->l2h;

	nsh->pdu_type = NS_PDUT_RESET_ACK;

	LOGNSVC(nsvc, LOGL_INFO, "Tx NS RESET ACK\n");

	msgb_tvlv_put(msg, NS_IE_VCI, 2, (uint8_t *)&nsvci);
	msgb_tvlv_put(msg, NS_IE_NSEI, 2, (uint8_t *)&nsei);

	return nsvc->bind->send_vc(nsvc, msg);
}

/*! Transmit a NS-UNBLOCK on a given NS-VC.
 *  \param[in] nsvc NS-VC on which the NS-UNBLOCK is to be transmitted
 *  \returns 0 in case of success */
int ns2_tx_unblock(struct gprs_ns2_vc *nsvc)
{
	log_set_context(LOG_CTX_GB_NSE, nsvc->nse);
	log_set_context(LOG_CTX_GB_NSVC, nsvc);

	ERR_IF_NSVC_USES_SNS(nsvc, "transmit NS UNBLOCK");

	LOGNSVC(nsvc, LOGL_INFO, "Tx NS UNBLOCK\n");

	return ns2_tx_simple(nsvc, NS_PDUT_UNBLOCK);
}


/*! Transmit a NS-UNBLOCK-ACK on a given NS-VC.
 *  \param[in] nsvc NS-VC on which the NS-UNBLOCK-ACK is to be transmitted
 *  \returns 0 in case of success */
int ns2_tx_unblock_ack(struct gprs_ns2_vc *nsvc)
{
	log_set_context(LOG_CTX_GB_NSE, nsvc->nse);
	log_set_context(LOG_CTX_GB_NSVC, nsvc);

	ERR_IF_NSVC_USES_SNS(nsvc, "transmit NS UNBLOCK ACK");

	LOGNSVC(nsvc, LOGL_INFO, "Tx NS UNBLOCK_ACK\n");

	return ns2_tx_simple(nsvc, NS_PDUT_UNBLOCK_ACK);
}

/*! Transmit a NS-ALIVE on a given NS-VC.
 *  \param[in] nsvc NS-VC on which the NS-ALIVE is to be transmitted
 *  \returns 0 in case of success */
int ns2_tx_alive(struct gprs_ns2_vc *nsvc)
{
	log_set_context(LOG_CTX_GB_NSE, nsvc->nse);
	log_set_context(LOG_CTX_GB_NSVC, nsvc);
	LOGNSVC(nsvc, LOGL_DEBUG, "Tx NS ALIVE\n");

	return ns2_tx_simple(nsvc, NS_PDUT_ALIVE);
}

/*! Transmit a NS-ALIVE-ACK on a given NS-VC.
 *  \param[in] nsvc NS-VC on which the NS-ALIVE-ACK is to be transmitted
 *  \returns 0 in case of success */
int ns2_tx_alive_ack(struct gprs_ns2_vc *nsvc)
{
	log_set_context(LOG_CTX_GB_NSE, nsvc->nse);
	log_set_context(LOG_CTX_GB_NSVC, nsvc);
	LOGNSVC(nsvc, LOGL_DEBUG, "Tx NS ALIVE_ACK\n");

	return ns2_tx_simple(nsvc, NS_PDUT_ALIVE_ACK);
}

/*! Transmit NS-UNITDATA on a given NS-VC.
 *  \param[in] nsvc NS-VC on which the NS-UNITDATA is to be transmitted
 *  \param[in] bvci BVCI to encode in NS-UNITDATA header
 *  \param[in] sducontrol SDU control octet of NS header
 *  \param[in] msg message buffer containing payload
 *  \returns 0 in case of success */
int ns2_tx_unit_data(struct gprs_ns2_vc *nsvc,
		     uint16_t bvci, uint8_t sducontrol,
		     struct msgb *msg)
{
	struct gprs_ns_hdr *nsh;

	log_set_context(LOG_CTX_GB_NSE, nsvc->nse);
	log_set_context(LOG_CTX_GB_NSVC, nsvc);

	msg->l2h = msgb_push(msg, sizeof(*nsh) + 3);
	nsh = (struct gprs_ns_hdr *) msg->l2h;
	if (!nsh) {
		LOGNSVC(nsvc, LOGL_ERROR, "Not enough headroom for NS header\n");
		msgb_free(msg);
		return -EIO;
	}

	nsh->pdu_type = NS_PDUT_UNITDATA;
	nsh->data[0] = sducontrol;
	nsh->data[1] = bvci >> 8;
	nsh->data[2] = bvci & 0xff;

	return nsvc->bind->send_vc(nsvc, msg);
}

/*! Transmit a NS-STATUS on a given NS-VC.
 *  \param[in] nsvc NS-VC to be used for transmission
 *  \param[in] cause Numeric NS cause value
 *  \param[in] bvci BVCI to be reset within NSVC
 *  \param[in] orig_msg message causing the STATUS
 *  \returns 0 in case of success */
int ns2_tx_status(struct gprs_ns2_vc *nsvc, uint8_t cause,
		       uint16_t bvci, struct msgb *orig_msg)
{
	struct msgb *msg = gprs_ns2_msgb_alloc();
	struct gprs_ns_hdr *nsh;
	uint16_t nsvci = osmo_htons(nsvc->nsvci);

	log_set_context(LOG_CTX_GB_NSE, nsvc->nse);
	log_set_context(LOG_CTX_GB_NSVC, nsvc);

	bvci = osmo_htons(bvci);

	if (!msg)
		return -ENOMEM;

	LOGNSVC(nsvc, LOGL_NOTICE, "Tx NS STATUS (cause=%s)\n", gprs_ns2_cause_str(cause));

	msg->l2h = msgb_put(msg, sizeof(*nsh));
	nsh = (struct gprs_ns_hdr *) msg->l2h;
	nsh->pdu_type = NS_PDUT_STATUS;

	msgb_tvlv_put(msg, NS_IE_CAUSE, 1, &cause);

	/* Section 9.2.7.1: Static conditions for NS-VCI */
	if (cause == NS_CAUSE_NSVC_BLOCKED ||
	    cause == NS_CAUSE_NSVC_UNKNOWN)
		msgb_tvlv_put(msg, NS_IE_VCI, 2, (uint8_t *)&nsvci);

	/* Section 9.2.7.2: Static conditions for NS PDU */
	switch (cause) {
	case NS_CAUSE_SEM_INCORR_PDU:
	case NS_CAUSE_PDU_INCOMP_PSTATE:
	case NS_CAUSE_PROTO_ERR_UNSPEC:
	case NS_CAUSE_INVAL_ESSENT_IE:
	case NS_CAUSE_MISSING_ESSENT_IE:
		msgb_tvlv_put(msg, NS_IE_PDU, msgb_l2len(orig_msg),
			      orig_msg->l2h);
		break;
	default:
		break;
	}

	/* Section 9.2.7.3: Static conditions for BVCI */
	if (cause == NS_CAUSE_BVCI_UNKNOWN)
		msgb_tvlv_put(msg, NS_IE_VCI, 2, (uint8_t *)&bvci);

	return nsvc->bind->send_vc(nsvc, msg);
}


/*! Encode + Transmit a SNS-ACK as per Section 9.3.1.
 *  \param[in] nsvc NS-VC through which to transmit the ACK
 *  \param[in] trans_id Transaction ID which to acknowledge
 *  \param[in] cause Pointer to cause value (NULL if no cause to be sent)
 *  \param[in] ip4_elems Array of IPv4 Elements
 *  \param[in] num_ip4_elems number of ip4_elems
 *  \returns 0 on success; negative in case of error */
int ns2_tx_sns_ack(struct gprs_ns2_vc *nsvc, uint8_t trans_id, uint8_t *cause,
			const struct gprs_ns_ie_ip4_elem *ip4_elems,
			unsigned int num_ip4_elems,
			const struct gprs_ns_ie_ip6_elem *ip6_elems,
			unsigned int num_ip6_elems)
{
	struct msgb *msg;
	struct gprs_ns_hdr *nsh;
	uint16_t nsei;

	if (!nsvc)
		return -1;

	msg = gprs_ns2_msgb_alloc();

	log_set_context(LOG_CTX_GB_NSE, nsvc->nse);
	log_set_context(LOG_CTX_GB_NSVC, nsvc);
	if (!msg)
		return -ENOMEM;

	if (!nsvc->nse->bss_sns_fi) {
		LOGNSVC(nsvc, LOGL_ERROR, "Cannot transmit SNS on NSVC without SNS active\n");
		msgb_free(msg);
		return -EIO;
	}

	nsei = osmo_htons(nsvc->nse->nsei);

	msg->l2h = msgb_put(msg, sizeof(*nsh));
	nsh = (struct gprs_ns_hdr *) msg->l2h;

	nsh->pdu_type = SNS_PDUT_ACK;
	msgb_tvlv_put(msg, NS_IE_NSEI, 2, (uint8_t *)&nsei);
	msgb_v_put(msg, trans_id);
	if (cause)
		msgb_tvlv_put(msg, NS_IE_CAUSE, 1, cause);
	if (ip4_elems) {
		/* List of IP4 Elements 10.3.2c */
		msgb_tvlv_put(msg, NS_IE_IPv4_LIST,
			      num_ip4_elems*sizeof(struct gprs_ns_ie_ip4_elem),
			      (const uint8_t *)ip4_elems);
	}
	if (ip6_elems) {
		/* List of IP6 elements 10.3.2d */
		msgb_tvlv_put(msg, NS_IE_IPv6_LIST,
			      num_ip6_elems*sizeof(struct gprs_ns_ie_ip6_elem),
			      (const uint8_t *)ip6_elems);
	}

	return nsvc->bind->send_vc(nsvc, msg);
}

/*! Encode + Transmit a SNS-CONFIG as per Section 9.3.4.
 *  \param[in] nsvc NS-VC through which to transmit the SNS-CONFIG
 *  \param[in] end_flag Whether or not this is the last SNS-CONFIG
 *  \param[in] ip4_elems Array of IPv4 Elements
 *  \param[in] num_ip4_elems number of ip4_elems
 *  \returns 0 on success; negative in case of error */
int ns2_tx_sns_config(struct gprs_ns2_vc *nsvc, bool end_flag,
			   const struct gprs_ns_ie_ip4_elem *ip4_elems,
			   unsigned int num_ip4_elems,
			   const struct gprs_ns_ie_ip6_elem *ip6_elems,
			   unsigned int num_ip6_elems)
{
	struct msgb *msg;
	struct gprs_ns_hdr *nsh;
	uint16_t nsei;

	if (!nsvc)
		return -1;

	msg = gprs_ns2_msgb_alloc();

	log_set_context(LOG_CTX_GB_NSE, nsvc->nse);
	log_set_context(LOG_CTX_GB_NSVC, nsvc);
	if (!msg)
		return -ENOMEM;

	if (!nsvc->nse->bss_sns_fi) {
		LOGNSVC(nsvc, LOGL_ERROR, "Cannot transmit SNS on NSVC without SNS active\n");
		msgb_free(msg);
		return -EIO;
	}

	nsei = osmo_htons(nsvc->nse->nsei);

	msg->l2h = msgb_put(msg, sizeof(*nsh));
	nsh = (struct gprs_ns_hdr *) msg->l2h;

	nsh->pdu_type = SNS_PDUT_CONFIG;

	msgb_v_put(msg, end_flag ? 0x01 : 0x00);
	msgb_tvlv_put(msg, NS_IE_NSEI, 2, (uint8_t *)&nsei);

	/* List of IP4 Elements 10.3.2c */
	if (ip4_elems) {
		msgb_tvlv_put(msg, NS_IE_IPv4_LIST, num_ip4_elems*sizeof(struct gprs_ns_ie_ip4_elem),
			      (const uint8_t *)ip4_elems);
	} else if (ip6_elems) {
		/* List of IP6 elements 10.3.2d */
		msgb_tvlv_put(msg, NS_IE_IPv6_LIST, num_ip6_elems*sizeof(struct gprs_ns_ie_ip6_elem),
			      (const uint8_t *)ip6_elems);
	}

	return nsvc->bind->send_vc(nsvc, msg);
}

/*! Encode + Transmit a SNS-CONFIG-ACK as per Section 9.3.5.
 *  \param[in] nsvc NS-VC through which to transmit the SNS-CONFIG-ACK
 *  \param[in] cause Pointer to cause value (NULL if no cause to be sent)
 *  \returns 0 on success; negative in case of error */
int ns2_tx_sns_config_ack(struct gprs_ns2_vc *nsvc, uint8_t *cause)
{
	struct msgb *msg;
	struct gprs_ns_hdr *nsh;
	uint16_t nsei;

	if (!nsvc)
		return -1;

	msg = gprs_ns2_msgb_alloc();
	log_set_context(LOG_CTX_GB_NSE, nsvc->nse);
	log_set_context(LOG_CTX_GB_NSVC, nsvc);
	if (!msg)
		return -ENOMEM;

	if (!nsvc->nse->bss_sns_fi) {
		LOGNSVC(nsvc, LOGL_ERROR, "Cannot transmit SNS on NSVC without SNS active\n");
		msgb_free(msg);
		return -EIO;
	}

	nsei = osmo_htons(nsvc->nse->nsei);

	msg->l2h = msgb_put(msg, sizeof(*nsh));
	nsh = (struct gprs_ns_hdr *) msg->l2h;

	nsh->pdu_type = SNS_PDUT_CONFIG_ACK;

	msgb_tvlv_put(msg, NS_IE_NSEI, 2, (uint8_t *)&nsei);
	if (cause)
		msgb_tvlv_put(msg, NS_IE_CAUSE, 1, cause);

	return nsvc->bind->send_vc(nsvc, msg);
}


/*! Encode + transmit a SNS-SIZE as per Section 9.3.7.
 *  \param[in] nsvc NS-VC through which to transmit the SNS-SIZE
 *  \param[in] reset_flag Whether or not to add a RESET flag
 *  \param[in] max_nr_nsvc Maximum number of NS-VCs
 *  \param[in] ip4_ep_nr Number of IPv4 endpoints (< 0 will omit the TLV)
 *  \param[in] ip6_ep_nr Number of IPv6 endpoints (< 0 will omit the TLV)
 *  \returns 0 on success; negative in case of error */
int ns2_tx_sns_size(struct gprs_ns2_vc *nsvc, bool reset_flag, uint16_t max_nr_nsvc,
			 int ip4_ep_nr, int ip6_ep_nr)
{
	struct msgb *msg;
	struct gprs_ns_hdr *nsh;
	uint16_t nsei;

	if (!nsvc)
		return -1;

	msg = gprs_ns2_msgb_alloc();

	log_set_context(LOG_CTX_GB_NSE, nsvc->nse);
	log_set_context(LOG_CTX_GB_NSVC, nsvc);
	if (!msg)
		return -ENOMEM;

	if (!nsvc->nse->bss_sns_fi) {
		LOGNSVC(nsvc, LOGL_ERROR, "Cannot transmit SNS on NSVC without SNS active\n");
		msgb_free(msg);
		return -EIO;
	}

	nsei = osmo_htons(nsvc->nse->nsei);

	msg->l2h = msgb_put(msg, sizeof(*nsh));
	nsh = (struct gprs_ns_hdr *) msg->l2h;

	nsh->pdu_type = SNS_PDUT_SIZE;

	msgb_tvlv_put(msg, NS_IE_NSEI, 2, (uint8_t *)&nsei);
	msgb_tv_put(msg, NS_IE_RESET_FLAG, reset_flag ? 0x01 : 0x00);
	msgb_tv16_put(msg, NS_IE_MAX_NR_NSVC, max_nr_nsvc);
	if (ip4_ep_nr >= 0)
		msgb_tv16_put(msg, NS_IE_IPv4_EP_NR, ip4_ep_nr);
	if (ip6_ep_nr >= 0)
		msgb_tv16_put(msg, NS_IE_IPv6_EP_NR, ip6_ep_nr);

	return nsvc->bind->send_vc(nsvc, msg);
}

/*! Encode + Transmit a SNS-SIZE-ACK as per Section 9.3.8.
 *  \param[in] nsvc NS-VC through which to transmit the SNS-SIZE-ACK
 *  \param[in] cause Pointer to cause value (NULL if no cause to be sent)
 *  \returns 0 on success; negative in case of error */
int ns2_tx_sns_size_ack(struct gprs_ns2_vc *nsvc, uint8_t *cause)
{
	struct msgb *msg = gprs_ns2_msgb_alloc();
	struct gprs_ns_hdr *nsh;
	uint16_t nsei;

	log_set_context(LOG_CTX_GB_NSE, nsvc->nse);
	log_set_context(LOG_CTX_GB_NSVC, nsvc);
	if (!msg)
		return -ENOMEM;

	if (!nsvc->nse->bss_sns_fi) {
		LOGNSVC(nsvc, LOGL_ERROR, "Cannot transmit SNS on NSVC without SNS active\n");
		msgb_free(msg);
		return -EIO;
	}

	nsei = osmo_htons(nsvc->nse->nsei);

	msg->l2h = msgb_put(msg, sizeof(*nsh));
	nsh = (struct gprs_ns_hdr *) msg->l2h;

	nsh->pdu_type = SNS_PDUT_SIZE_ACK;

	msgb_tvlv_put(msg, NS_IE_NSEI, 2, (uint8_t *)&nsei);
	if (cause)
		msgb_tvlv_put(msg, NS_IE_CAUSE, 1, cause);

	return nsvc->bind->send_vc(nsvc, msg);
}


