/*! \file gprs_ns.c
 * 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) 2009-2018 by Harald Welte <laforge@gnumonks.org>
 * (C) 2016-2017 sysmocom - s.f.m.c. GmbH
 *
 * 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/>.
 *
 */

/*! \addtogroup libgb
 *  @{
 *
 * 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) 
 *
 * Some introduction into NS:  NS is used typically on top of frame relay,
 * but in the ip.access world it is encapsulated in UDP packets.  It serves
 * as an intermediate shim betwen BSSGP and the underlying medium.  It doesn't
 * do much, apart from providing congestion notification and status indication.
 *
 * Terms:
 *
 * 	NS		Network Service
 * 	NSVC		NS Virtual Connection
 * 	NSEI		NS Entity Identifier
 * 	NSVL		NS Virtual Link
 * 	NSVLI		NS Virtual Link Identifier
 * 	BVC		BSSGP Virtual Connection
 * 	BVCI		BSSGP Virtual Connection Identifier
 * 	NSVCG		NS Virtual Connection Goup
 * 	Blocked		NS-VC cannot be used for user traffic
 * 	Alive		Ability of a NS-VC to provide communication
 *
 * There can be multiple BSSGP virtual connections over one (group of) NSVC's.  BSSGP will
 * therefore identify the BSSGP virtual connection by a BVCI passed down to NS.
 * NS then has to figure out which NSVC's are responsible for this BVCI.
 * Those mappings are administratively configured.
 *
 * This implementation has the following limitations:
 * - Only one NS-VC for each NSE: No load-sharing function
 * - NSVCI 65535 and 65534 are reserved for internal use
 * - Only UDP is supported as of now, no frame relay support
 * - There are no BLOCK and UNBLOCK timers (yet?)
 *
 * \file gprs_ns.c */

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

#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#include <osmocom/core/fsm.h>
#include <osmocom/core/msgb.h>
#include <osmocom/core/byteswap.h>
#include <osmocom/gsm/tlv.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/select.h>
#include <osmocom/core/rate_ctr.h>
#include <osmocom/core/stat_item.h>
#include <osmocom/core/stats.h>
#include <osmocom/core/socket.h>
#include <osmocom/core/signal.h>
#include <osmocom/gprs/gprs_ns.h>
#include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/gprs/gprs_ns_frgre.h>

#include "common_vty.h"
#include "gb_internal.h"

#define ns_set_state(ns_, st_) ns_set_state_with_log(ns_, st_, false, __FILE__, __LINE__)
#define ns_set_remote_state(ns_, st_) ns_set_state_with_log(ns_, st_, true, __FILE__, __LINE__)
#define ns_mark_blocked(ns_) ns_set_state(ns_, (ns_)->state | NSE_S_BLOCKED)
#define ns_mark_unblocked(ns_) ns_set_state(ns_, (ns_)->state & (~NSE_S_BLOCKED));
#define ns_mark_alive(ns_) ns_set_state(ns_, (ns_)->state | NSE_S_ALIVE)
#define ns_mark_dead(ns_) ns_set_state(ns_, (ns_)->state & (~NSE_S_ALIVE));

#define ERR_IF_NSVC_USES_SNS(nsvc, reason) 							\
	do {											\
		if ((nsvc)->nsi->bss_sns_fi) {							\
			LOGP(DNS, LOGL_ERROR, "NSEI=%u Asked to %s. Rejected on IP-SNS\n",	\
				nsvc->nsei, reason);						\
			osmo_log_backtrace(DNS, LOGL_ERROR);					\
			return -EIO;								\
		}										\
	} while (0)

static const struct tlv_definition ns_att_tlvdef = {
	.def = {
		[NS_IE_CAUSE]	= { TLV_TYPE_TvLV, 0 },
		[NS_IE_VCI]	= { TLV_TYPE_TvLV, 0 },
		[NS_IE_PDU]	= { TLV_TYPE_TvLV, 0 },
		[NS_IE_BVCI]	= { TLV_TYPE_TvLV, 0 },
		[NS_IE_NSEI]	= { TLV_TYPE_TvLV, 0 },
		[NS_IE_IPv4_LIST] = { TLV_TYPE_TvLV, 0 },
		[NS_IE_IPv6_LIST] = { TLV_TYPE_TvLV, 0 },
		[NS_IE_MAX_NR_NSVC] = { TLV_TYPE_FIXED, 2 },
		[NS_IE_IPv4_EP_NR] = { TLV_TYPE_FIXED, 2 },
		[NS_IE_IPv6_EP_NR] = { TLV_TYPE_FIXED, 2 },
		[NS_IE_RESET_FLAG] = { TLV_TYPE_TV, 0 },
		/* TODO: IP_ADDR can be 5 or 17 bytes long, depending on first byte. This
		 * cannot be expressed in our TLV parser.  However, we don't do IPv6 anyway */
		[NS_IE_IP_ADDR] = { TLV_TYPE_FIXED, 5 },
	},
};

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 const struct rate_ctr_desc nsvc_ctr_description[] = {
	{ "packets:in", "Packets at NS Level  ( In)" },
	{ "packets:out","Packets at NS Level  (Out)" },
	{ "bytes:in",	"Bytes at NS Level    ( In)" },
	{ "bytes:out",	"Bytes at NS Level    (Out)" },
	{ "blocked",	"NS-VC Block count         " },
	{ "dead",	"NS-VC gone dead count     " },
	{ "replaced",	"NS-VC replaced other count" },
	{ "nsei-chg",	"NS-VC changed NSEI count  " },
	{ "inv-nsvci",	"NS-VCI was invalid count  " },
	{ "inv-nsei",	"NSEI was invalid count    " },
	{ "lost:alive",	"ALIVE ACK missing count   " },
	{ "lost:reset",	"RESET ACK missing count   " },
};

static const struct rate_ctr_group_desc nsvc_ctrg_desc = {
	.group_name_prefix = "ns:nsvc",
	.group_description = "NSVC Peer Statistics",
	.num_ctr = ARRAY_SIZE(nsvc_ctr_description),
	.ctr_desc = nsvc_ctr_description,
	.class_id = OSMO_STATS_CLASS_PEER,
};

enum ns_stat {
	NS_STAT_ALIVE_DELAY,
};

static const struct osmo_stat_item_desc nsvc_stat_description[] = {
	{ "alive.delay", "ALIVE response time        ", "ms", 16, 0 },
};

static const struct osmo_stat_item_group_desc nsvc_statg_desc = {
	.group_name_prefix = "ns.nsvc",
	.group_description = "NSVC Peer Statistics",
	.num_items = ARRAY_SIZE(nsvc_stat_description),
	.item_desc = nsvc_stat_description,
	.class_id = OSMO_STATS_CLASS_PEER,
};

const struct value_string gprs_ns_signal_ns_names[] = {
	{ S_NS_RESET,		"NS-RESET" },
	{ S_NS_BLOCK,		"NS-BLOCK" },
	{ S_NS_UNBLOCK,		"NS-UNBLOCK" },
	{ S_NS_ALIVE_EXP,	"NS-ALIVE expired" },
	{ S_NS_REPLACED,	"NSVC replaced" },
	{ S_NS_MISMATCH,	"Unexpected IE" },
	{ S_SNS_CONFIGURED,	"SNS Configured" },
	{ 0, NULL }
};

#define CHECK_TX_RC(rc, nsvc) \
		if (rc < 0)							\
			LOGP(DNS, LOGL_ERROR, "TX failed (%d) to peer %s\n",	\
				rc, gprs_ns_ll_str(nsvc));

static bool nsvc_is_not_used(const struct gprs_nsvc *nsvc)
{
	if (nsvc->data_weight == 0 && nsvc->sig_weight == 0)
		return true;
	else
		return false;
}

struct msgb *gprs_ns_msgb_alloc(void)
{
	struct msgb *msg = msgb_alloc_headroom(NS_ALLOC_SIZE, NS_ALLOC_HEADROOM,
		"GPRS/NS");
	if (!msg) {
		LOGP(DNS, LOGL_ERROR, "Failed to allocate NS message of size %d\n",
			NS_ALLOC_SIZE);
	}
	return msg;
}

/* FIXME: convert to osmo_fsm */
static inline void ns_set_state_with_log(struct gprs_nsvc *nsvc, uint32_t state, bool is_remote,
					 const char *file, unsigned line)
{
	uint32_t old_state = is_remote ? nsvc->remote_state : nsvc->state;

	LOGPSRC(DNS, LOGL_DEBUG, file, line, "NSEI %d (NS-VCI=%u) setting %sstate [%s,%s,%s] -> [%s,%s,%s]\n",
		nsvc->nsei, nsvc->nsvci, is_remote ? "remote " : "",
		NS_DESC_A(old_state), NS_DESC_B(old_state), NS_DESC_R(old_state),
		NS_DESC_A(state), NS_DESC_B(state), NS_DESC_R(state));

	if (is_remote)
		nsvc->remote_state = state;
	else
		nsvc->state = state;
}

/*! Lookup struct gprs_nsvc based on NSVCI
 *  \param[in] nsi NS instance in which to search
 *  \param[in] nsvci NSVCI to be searched
 *  \returns gprs_nsvc of respective NSVCI
 */
struct gprs_nsvc *gprs_nsvc_by_nsvci(struct gprs_ns_inst *nsi, uint16_t nsvci)
{
	struct gprs_nsvc *nsvc;
	llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
		if (nsvc->nsvci == nsvci)
			return nsvc;
	}
	return NULL;
}

/*! Lookup struct gprs_nsvc based on NSEI
 *  \param[in] nsi NS instance in which to search
 *  \param[in] nsei NSEI to be searched
 *  \returns first gprs_nsvc of respective NSEI
 */
struct gprs_nsvc *gprs_nsvc_by_nsei(struct gprs_ns_inst *nsi, uint16_t nsei)
{
	struct gprs_nsvc *nsvc;
	llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
		if (nsvc->nsei == nsei)
			return nsvc;
	}
	return NULL;
}

/*! Determine active NS-VC for given NSEI + BVCI.
 *  Use this function to determine which of the NS-VCs inside the NS Instance
 *  shall be used to transmit data for given NSEI + BVCI */
static struct gprs_nsvc *gprs_active_nsvc_by_nsei(struct gprs_ns_inst *nsi,
						  uint16_t nsei, uint16_t bvci)
{
	struct gprs_nsvc *nsvc;
	llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
		/* if signalling BVCI, skip any NSVC with signalling weight == 0 */
		if (bvci == 0 && nsvc->sig_weight == 0)
			continue;
		/* if point-to-point BVCI, skip any NSVC with data weight == 0 */
		if (bvci != 0 && nsvc->data_weight == 0)
			continue;
		if (nsvc->nsei == nsei) {
			if (!(nsvc->state & NSE_S_BLOCKED) &&
			    nsvc->state & NSE_S_ALIVE)
				return nsvc;
		}
	}
	return NULL;
}

/*! Lookup NS-VC based on specified remote peer socket addr.
 *  \param[in] nsi NS Instance within which we shall look up the NS-VC
 *  \param[in] sin Remote peer Socket Address (IP + UDP Port)
 *  \returns NS-VC matching the given peer; NULL in case of none */
struct gprs_nsvc *gprs_nsvc_by_rem_addr(struct gprs_ns_inst *nsi, const struct sockaddr_in *sin)
{
	struct gprs_nsvc *nsvc;
	llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
		if (nsvc->ip.bts_addr.sin_addr.s_addr ==
					sin->sin_addr.s_addr &&
		    nsvc->ip.bts_addr.sin_port == sin->sin_port)
			return nsvc;
	}
	return NULL;
}

static void gprs_ns_timer_cb(void *data);

/*! Create a new NS-VC (Virtual Circuit) within given instance
 *  \param[in] nsi NS Instance in which to create the NSVC
 *  \param[in] nsvci] NS Virtual Connection Identifier for this NSVC
 *  \param[in] sig_weight Signalling Weight of this NS-VC. Use "0" for no signalling
 *  \param[in] data_weight Data WEight of this NS-VC. Use "0" for no data
 *  \returns newly-created gprs_nsvc within nsi. NULL on error. */
struct gprs_nsvc *gprs_nsvc_create2(struct gprs_ns_inst *nsi, uint16_t nsvci,
				    uint8_t sig_weight, uint8_t data_weight)
{
	struct gprs_nsvc *nsvc;

	if (gprs_nsvc_by_nsvci(nsi, nsvci)) {
		LOGP(DNS, LOGL_ERROR, "Cannot create NS-VC for already-existing NSVCI=%u\n", nsvci);
		return NULL;
	}

	LOGP(DNS, LOGL_INFO, "NSVCI=%u Creating NS-VC with Signal weight %u, Data weight %u\n",
	     nsvci, sig_weight, data_weight);

	nsvc = talloc_zero(nsi, struct gprs_nsvc);
	if (!nsvc)
		return NULL;
	nsvc->nsvci = nsvci;
	nsvc->nsvci_is_valid = 1;
	/* before RESET procedure: BLOCKED and DEAD */
	if (nsi->bss_sns_fi)
		ns_set_state(nsvc, 0);
	else
		ns_set_state(nsvc, NSE_S_BLOCKED);
	nsvc->nsi = nsi;
	osmo_timer_setup(&nsvc->timer, gprs_ns_timer_cb, nsvc);
	nsvc->ctrg = rate_ctr_group_alloc(nsvc, &nsvc_ctrg_desc, nsvci);
	if (!nsvc->ctrg) {
		talloc_free(nsvc);
		return NULL;
	}
	nsvc->statg = osmo_stat_item_group_alloc(nsvc, &nsvc_statg_desc, nsvci);
	nsvc->sig_weight = sig_weight;
	nsvc->data_weight = data_weight;

	llist_add(&nsvc->list, &nsi->gprs_nsvcs);

	return nsvc;
}

/*! Old API for creating a NS-VC. Uses gprs_nsvc_create2 with fixed weights. */
struct gprs_nsvc *gprs_nsvc_create(struct gprs_ns_inst *nsi, uint16_t nsvci)
{
	return gprs_nsvc_create2(nsi, nsvci, 1, 1);
}

/*! Delete given NS-VC
 *  \param[in] nsvc gprs_nsvc to be deleted
 */
void gprs_nsvc_delete(struct gprs_nsvc *nsvc)
{
	if (osmo_timer_pending(&nsvc->timer))
		osmo_timer_del(&nsvc->timer);
	llist_del(&nsvc->list);
	rate_ctr_group_free(nsvc->ctrg);
	osmo_stat_item_group_free(nsvc->statg);
	talloc_free(nsvc);
}

static void ns_osmo_signal_dispatch(struct gprs_nsvc *nsvc, unsigned int signal,
			       uint8_t cause)
{
	struct ns_signal_data nssd = {0};

	nssd.nsvc = nsvc;
	nssd.cause = cause;

	osmo_signal_dispatch(SS_L_NS, signal, &nssd);
}

static void ns_osmo_signal_dispatch_mismatch(struct gprs_nsvc *nsvc,
					     struct msgb *msg,
					     uint8_t pdu_type, uint8_t ie_type)
{
	struct ns_signal_data nssd = {0};

	nssd.nsvc     = nsvc;
	nssd.pdu_type = pdu_type;
	nssd.ie_type  = ie_type;
	nssd.msg      = msg;

	osmo_signal_dispatch(SS_L_NS, S_NS_MISMATCH, &nssd);
}

static void ns_osmo_signal_dispatch_replaced(struct gprs_nsvc *nsvc, struct gprs_nsvc *old_nsvc)
{
	struct ns_signal_data nssd = {0};

	nssd.nsvc = nsvc;
	nssd.old_nsvc = old_nsvc;

	osmo_signal_dispatch(SS_L_NS, S_NS_REPLACED, &nssd);
}

const struct value_string gprs_ns_pdu_strings[] = {
	/* 3GPP TS 48.016 §9.2 Network Service Control PDUs */
	{ NS_PDUT_UNITDATA,	"NS-UNITDATA" },	/* §9.2.1 */
	{ NS_PDUT_RESET,	"NS-RESET" },		/* §9.2.5 */
	{ NS_PDUT_RESET_ACK,	"NS-RESET-ACK" },	/* §9.2.6 */
	{ NS_PDUT_BLOCK,	"NS-BLOCK" },		/* §9.2.3 */
	{ NS_PDUT_BLOCK_ACK,	"NS-BLOCK-ACK" },	/* §9.2.4 */
	{ NS_PDUT_UNBLOCK,	"NS-UNBLOCK" },		/* §9.2.8 */
	{ NS_PDUT_UNBLOCK_ACK,	"NS-UNBLOCK-ACK" },	/* §9.2.9 */
	{ NS_PDUT_STATUS,	"NS-STATUS" },		/* §9.2.7 */
	{ NS_PDUT_ALIVE,	"NS-ALIVE" },		/* §9.2.1 */
	{ NS_PDUT_ALIVE_ACK,	"NS-ALIVE-ACK" },	/* §9.2.2 */
	/* 3GPP TS 48.016 §9.3 Sub-Network Service Control PDUs */
	{ SNS_PDUT_ACK,			"SNS-ACK" },		/* §9.3.1 */
	{ SNS_PDUT_ADD,			"SNS-ADD" },		/* §9.3.2 */
	{ SNS_PDUT_CHANGE_WEIGHT,	"SNS-CHANGEWEIGHT" },	/* §9.3.3 */
	{ SNS_PDUT_CONFIG,		"SNS-CONFIG" },		/* §9.3.4 */
	{ SNS_PDUT_CONFIG_ACK,		"SNS-CONFIG-ACK" },	/* §9.3.5 */
	{ SNS_PDUT_DELETE,		"SNS-DELETE" },		/* §9.3.6 */
	{ SNS_PDUT_SIZE,		"SNS-SIZE" },		/* §9.3.7 */
	{ SNS_PDUT_SIZE_ACK,		"SNS-SIZE-ACK" },	/* §9.3.8 */
	{ 0, NULL }
};

/* Section 10.3.2, Table 13 */
static const struct value_string ns_cause_str[] = {
	{ NS_CAUSE_TRANSIT_FAIL,	"Transit network failure" },
	{ NS_CAUSE_OM_INTERVENTION, 	"O&M intervention" },
	{ NS_CAUSE_EQUIP_FAIL,		"Equipment failure" },
	{ NS_CAUSE_NSVC_BLOCKED,	"NS-VC blocked" },
	{ NS_CAUSE_NSVC_UNKNOWN,	"NS-VC unknown" },
	{ NS_CAUSE_BVCI_UNKNOWN,	"BVCI unknown" },
	{ NS_CAUSE_SEM_INCORR_PDU,	"Semantically incorrect PDU" },
	{ NS_CAUSE_PDU_INCOMP_PSTATE,	"PDU not compatible with protocol state" },
	{ NS_CAUSE_PROTO_ERR_UNSPEC,	"Protocol error, unspecified" },
	{ NS_CAUSE_INVAL_ESSENT_IE,	"Invalid essential IE" },
	{ NS_CAUSE_MISSING_ESSENT_IE,	"Missing essential IE" },
	{ NS_CAUSE_INVAL_NR_IPv4_EP,	"Invalid Number of IPv4 Endpoints" },
	{ NS_CAUSE_INVAL_NR_IPv6_EP,	"Invalid Number of IPv6 Endpoints" },
	{ NS_CAUSE_INVAL_NR_NS_VC,	"Invalid Number of NS-VCs" },
	{ NS_CAUSE_INVAL_WEIGH,		"Invalid Weights" },
	{ NS_CAUSE_UNKN_IP_EP,		"Unknown IP Endpoint" },
	{ NS_CAUSE_UNKN_IP_ADDR,	"Unknown IP Address" },
	{ NS_CAUSE_UNKN_IP_TEST_FAILED,	"IP Test Failed" },
	{ 0, NULL }
};

/*! Obtain a human-readable string for NS cause value */
const char *gprs_ns_cause_str(enum ns_cause cause)
{
	return get_value_string(ns_cause_str, cause);
}

static int nsip_sendmsg(struct gprs_nsvc *nsvc, struct msgb *msg);
extern int grps_ns_frgre_sendmsg(struct gprs_nsvc *nsvc, struct msgb *msg);

static bool ns_is_sns(uint8_t pdu_type)
{
	switch (pdu_type) {
	case SNS_PDUT_CONFIG:
	case SNS_PDUT_ACK:
	case SNS_PDUT_ADD:
	case SNS_PDUT_CHANGE_WEIGHT:
	case SNS_PDUT_DELETE:
	case SNS_PDUT_CONFIG_ACK:
	case SNS_PDUT_SIZE:
	case SNS_PDUT_SIZE_ACK:
		return true;
	default:
		return false;
	}
}

static int gprs_ns_tx(struct gprs_nsvc *nsvc, struct msgb *msg)
{
	struct gprs_ns_hdr *nsh = (struct gprs_ns_hdr *) msg->l2h;
	int ret;

	log_set_context(LOG_CTX_GB_NSVC, nsvc);

	/* A pre-configured endpoint shall not be used for NSE data or signalling
	 * traffic (with the exception of Size and Configuration procedures) unless it
	 * is configured by the SGSN using the auto-configuration procedures. */
	if (nsvc_is_not_used(nsvc) && !ns_is_sns(nsh->pdu_type) && nsh->pdu_type != NS_PDUT_STATUS) {
		LOGP(DNS, LOGL_NOTICE, "Not transmitting %s on unused/pre-configured endpoint\n",
			get_value_string(gprs_ns_pdu_strings, nsh->pdu_type));
		msgb_free(msg);
		return -EINVAL;
	}

	/* Increment number of Uplink bytes */
	rate_ctr_inc(&nsvc->ctrg->ctr[NS_CTR_PKTS_OUT]);
	rate_ctr_add(&nsvc->ctrg->ctr[NS_CTR_BYTES_OUT], msgb_l2len(msg));

	switch (nsvc->ll) {
	case GPRS_NS_LL_UDP:
		ret = nsip_sendmsg(nsvc, msg);
		if (ret < 0)
			LOGP(DNS, LOGL_INFO,
				"failed to send NS message via UDP: %s\n",
				strerror(-ret));
		break;
	case GPRS_NS_LL_FR_GRE:
		ret = gprs_ns_frgre_sendmsg(nsvc, msg);
		if (ret < 0)
			LOGP(DNS, LOGL_INFO,
				"failed to send NS message via FR/GRE: %s\n",
				strerror(-ret));
		break;
	default:
		LOGP(DNS, LOGL_ERROR, "unsupported NS linklayer %u\n", nsvc->ll);
		msgb_free(msg);
		ret = -EIO;
		break;
	}
	return ret;
}

static int gprs_ns_tx_simple(struct gprs_nsvc *nsvc, uint8_t pdu_type)
{
	struct msgb *msg = gprs_ns_msgb_alloc();
	struct gprs_ns_hdr *nsh;

	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 gprs_ns_tx(nsvc, msg);
}

/*! Transmit a NS-RESET on a given NSVC
 *  \param[in] nsvc NS-VC used for transmission
 *  \paam[in] cause Numeric NS cause value
 */
int gprs_ns_tx_reset(struct gprs_nsvc *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->nsei);

	log_set_context(LOG_CTX_GB_NSVC, nsvc);

	ERR_IF_NSVC_USES_SNS(nsvc, "transmit NS RESET");

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

	LOGP(DNS, LOGL_INFO, "NSEI=%u Tx NS RESET (NSVCI=%u, cause=%s)\n",
		nsvc->nsei, nsvc->nsvci, gprs_ns_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 gprs_ns_tx(nsvc, msg);

}

/*! Transmit a NS-STATUS on a given NSVC
 *  \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 */
int gprs_ns_tx_status(struct gprs_nsvc *nsvc, uint8_t cause,
		      uint16_t bvci, struct msgb *orig_msg)
{
	struct msgb *msg = gprs_ns_msgb_alloc();
	struct gprs_ns_hdr *nsh;
	uint16_t nsvci = osmo_htons(nsvc->nsvci);

	log_set_context(LOG_CTX_GB_NSVC, nsvc);

	bvci = osmo_htons(bvci);

	if (!msg)
		return -ENOMEM;

	LOGP(DNS, LOGL_NOTICE, "NSEI=%u Tx NS STATUS (NSVCI=%u, cause=%s)\n",
		nsvc->nsei, nsvc->nsvci, gprs_ns_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 gprs_ns_tx(nsvc, msg);
}

/*! Transmit a NS-BLOCK on a tiven NS-VC
 *  \param[in] nsvc 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 gprs_ns_tx_block(struct gprs_nsvc *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_NSVC, nsvc);

	ERR_IF_NSVC_USES_SNS(nsvc, "transmit NS BLOCK");

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

	LOGP(DNS, LOGL_INFO, "NSEI=%u Tx NS BLOCK (NSVCI=%u, cause=%s)\n",
		nsvc->nsei, nsvc->nsvci, gprs_ns_cause_str(cause));

	/* be conservative and mark it as blocked even now! */
	ns_mark_blocked(nsvc);
	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 gprs_ns_tx(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
 */
static int gprs_ns_tx_block_ack(struct gprs_nsvc *nsvc)
{
	struct msgb *msg;
	struct gprs_ns_hdr *nsh;
	uint16_t nsvci = osmo_htons(nsvc->nsvci);

	log_set_context(LOG_CTX_GB_NSVC, nsvc);

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

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

	LOGP(DNS, LOGL_INFO, "NSEI=%u Tx NS BLOCK ACK (NSVCI=%u)\n", nsvc->nsei, nsvc->nsvci);

	/* be conservative and mark it as blocked even now! */
	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 gprs_ns_tx(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 gprs_ns_tx_unblock(struct gprs_nsvc *nsvc)
{
	log_set_context(LOG_CTX_GB_NSVC, nsvc);

	ERR_IF_NSVC_USES_SNS(nsvc, "transmit NS UNBLOCK");

	LOGP(DNS, LOGL_INFO, "NSEI=%u Tx NS UNBLOCK (NSVCI=%u)\n",
		nsvc->nsei, nsvc->nsvci);

	return gprs_ns_tx_simple(nsvc, NS_PDUT_UNBLOCK);
}

/*! 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 gprs_ns_tx_alive(struct gprs_nsvc *nsvc)
{
	log_set_context(LOG_CTX_GB_NSVC, nsvc);
	LOGP(DNS, LOGL_DEBUG, "NSEI=%u Tx NS ALIVE (NSVCI=%u)\n",
		nsvc->nsei, nsvc->nsvci);

	return gprs_ns_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 gprs_ns_tx_alive_ack(struct gprs_nsvc *nsvc)
{
	log_set_context(LOG_CTX_GB_NSVC, nsvc);
	LOGP(DNS, LOGL_DEBUG, "NSEI=%u Tx NS ALIVE_ACK (NSVCI=%u)\n",
		nsvc->nsei, nsvc->nsvci);

	return gprs_ns_tx_simple(nsvc, NS_PDUT_ALIVE_ACK);
}

static const enum ns_timeout timer_mode_tout[_NSVC_TIMER_NR] = {
	[NSVC_TIMER_TNS_RESET]	= NS_TOUT_TNS_RESET,
	[NSVC_TIMER_TNS_ALIVE]	= NS_TOUT_TNS_ALIVE,
	[NSVC_TIMER_TNS_TEST]	= NS_TOUT_TNS_TEST,
};

static const struct value_string timer_mode_strs[] = {
	{ NSVC_TIMER_TNS_RESET, "tns-reset" },
	{ NSVC_TIMER_TNS_ALIVE, "tns-alive" },
	{ NSVC_TIMER_TNS_TEST, "tns-test" },
	{ 0, NULL }
};

static void nsvc_start_timer(struct gprs_nsvc *nsvc, enum nsvc_timer_mode mode)
{
	enum ns_timeout tout = timer_mode_tout[mode];
	unsigned int seconds = nsvc->nsi->timeout[tout];

	log_set_context(LOG_CTX_GB_NSVC, nsvc);
	DEBUGP(DNS, "NSEI=%u Starting timer in mode %s (%u seconds)\n",
		nsvc->nsei, get_value_string(timer_mode_strs, mode),
		seconds);

	if (osmo_timer_pending(&nsvc->timer))
		osmo_timer_del(&nsvc->timer);

	osmo_gettimeofday(&nsvc->timer_started, NULL);
	nsvc->timer_mode = mode;
	osmo_timer_schedule(&nsvc->timer, seconds, 0);
}

static int nsvc_timer_elapsed_ms(struct gprs_nsvc *nsvc)
{
	struct timeval now, elapsed;
	osmo_gettimeofday(&now, NULL);
	timersub(&now, &nsvc->timer_started, &elapsed);

	return 1000 * elapsed.tv_sec + elapsed.tv_usec / 1000;
}

static void gprs_ns_timer_cb(void *data)
{
	struct gprs_nsvc *nsvc = data;
	enum ns_timeout tout = timer_mode_tout[nsvc->timer_mode];
	unsigned int seconds = nsvc->nsi->timeout[tout];

	log_set_context(LOG_CTX_GB_NSVC, nsvc);
	DEBUGP(DNS, "NSEI=%u Timer expired in mode %s (%u seconds)\n",
		nsvc->nsei, get_value_string(timer_mode_strs, nsvc->timer_mode),
		seconds);

	switch (nsvc->timer_mode) {
	case NSVC_TIMER_TNS_ALIVE:
		/* Tns-alive case: we expired without response ! */
		rate_ctr_inc(&nsvc->ctrg->ctr[NS_CTR_LOST_ALIVE]);
		nsvc->alive_retries++;
		if (nsvc->alive_retries >
			nsvc->nsi->timeout[NS_TOUT_TNS_ALIVE_RETRIES]) {
			/* mark as dead (and blocked unless IP-SNS) */
			rate_ctr_inc(&nsvc->ctrg->ctr[NS_CTR_DEAD]);
			if (!nsvc->nsi->bss_sns_fi) {
				ns_set_state(nsvc, NSE_S_BLOCKED);
				rate_ctr_inc(&nsvc->ctrg->ctr[NS_CTR_BLOCKED]);
			} else
				ns_set_state(nsvc, 0);
			LOGP(DNS, LOGL_NOTICE,
				"NSEI=%u Tns-alive expired more then "
				"%u times, blocking NS-VC\n", nsvc->nsei,
				nsvc->nsi->timeout[NS_TOUT_TNS_ALIVE_RETRIES]);
			ns_osmo_signal_dispatch(nsvc, S_NS_ALIVE_EXP, 0);
			/* FIXME: should we send this signal in case of SNS? */
			if (!nsvc->nsi->bss_sns_fi)
				ns_osmo_signal_dispatch(nsvc, S_NS_BLOCK, NS_CAUSE_NSVC_BLOCKED);
			return;
		}
		/* Tns-test case: send NS-ALIVE PDU */
		gprs_ns_tx_alive(nsvc);
		/* start Tns-alive timer */
		nsvc_start_timer(nsvc, NSVC_TIMER_TNS_ALIVE);
		break;
	case NSVC_TIMER_TNS_TEST:
		/* Tns-test case: send NS-ALIVE PDU */
		gprs_ns_tx_alive(nsvc);
		/* start Tns-alive timer (transition into faster
		 * alive retransmissions) */
		nsvc->alive_retries = 0;
		nsvc_start_timer(nsvc, NSVC_TIMER_TNS_ALIVE);
		break;
	case NSVC_TIMER_TNS_RESET:
		rate_ctr_inc(&nsvc->ctrg->ctr[NS_CTR_LOST_RESET]);
		if (!(nsvc->state & NSE_S_RESET))
			LOGP(DNS, LOGL_NOTICE,
				"NSEI=%u Reset timed out but RESET flag is not set\n",
				nsvc->nsei);
		/* Mark NS-VC locally as blocked and dead */
		ns_set_state(nsvc, NSE_S_BLOCKED | NSE_S_RESET);
		/* Chapter 7.3: Re-send the RESET */
		gprs_ns_tx_reset(nsvc, NS_CAUSE_OM_INTERVENTION);
		/* Re-start Tns-reset timer */
		nsvc_start_timer(nsvc, NSVC_TIMER_TNS_RESET);
		break;
	case _NSVC_TIMER_NR:
		break;
	}
}

/* Section 9.2.6 */
static int gprs_ns_tx_reset_ack(struct gprs_nsvc *nsvc)
{
	struct msgb *msg;
	struct gprs_ns_hdr *nsh;
	uint16_t nsvci, nsei;

	log_set_context(LOG_CTX_GB_NSVC, nsvc);

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

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

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

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

	nsh->pdu_type = NS_PDUT_RESET_ACK;

	LOGP(DNS, LOGL_INFO, "NSEI=%u Tx NS RESET ACK (NSVCI=%u)\n",
		nsvc->nsei, nsvc->nsvci);

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

	return gprs_ns_tx(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 gprs_ns_tx_sns_ack(struct gprs_nsvc *nsvc, uint8_t trans_id, uint8_t *cause,
			const struct gprs_ns_ie_ip4_elem *ip4_elems,
			unsigned int num_ip4_elems)
{
	struct msgb *msg = gprs_ns_msgb_alloc();
	struct gprs_ns_hdr *nsh;
	uint16_t nsei;

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

	if (!nsvc->nsi->bss_sns_fi) {
		LOGP(DNS, LOGL_ERROR, "NSEI=%u Cannot transmit SNS on NSVC without SNS active\n",
		     nsvc->nsei);
		msgb_free(msg);
		return -EIO;
	}

	nsei = osmo_htons(nsvc->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);
	}
	/* FIXME: List of IP6 elements 10.3.2d */
	return gprs_ns_tx(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 gprs_ns_tx_sns_config(struct gprs_nsvc *nsvc, bool end_flag,
			  const struct gprs_ns_ie_ip4_elem *ip4_elems,
			  unsigned int num_ip4_elems)
{
	struct msgb *msg = gprs_ns_msgb_alloc();
	struct gprs_ns_hdr *nsh;
	uint16_t nsei;

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

	if (!nsvc->nsi->bss_sns_fi) {
		LOGP(DNS, LOGL_ERROR, "NSEI=%u Cannot transmit SNS on NSVC without SNS active\n",
		     nsvc->nsei);
		msgb_free(msg);
		return -EIO;
	}

	nsei = osmo_htons(nsvc->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 */
	msgb_tvlv_put(msg, NS_IE_IPv4_LIST, num_ip4_elems*sizeof(struct gprs_ns_ie_ip4_elem),
			(const uint8_t *)ip4_elems);
	/* FIXME: List of IP6 elements 10.3.2d */

	return gprs_ns_tx(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 gprs_ns_tx_sns_config_ack(struct gprs_nsvc *nsvc, uint8_t *cause)
{
	struct msgb *msg = gprs_ns_msgb_alloc();
	struct gprs_ns_hdr *nsh;
	uint16_t nsei;

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

	if (!nsvc->nsi->bss_sns_fi) {
		LOGP(DNS, LOGL_ERROR, "NSEI=%u Cannot transmit SNS on NSVC without SNS active\n",
		     nsvc->nsei);
		msgb_free(msg);
		return -EIO;
	}

	nsei = osmo_htons(nsvc->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 gprs_ns_tx(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 (NULL if none)
 *  \param[in] ip6_ep_nr Number of IPv6 endpoints (NULL if none)
 *  \returns 0 on success; negative in case of error */
int gprs_ns_tx_sns_size(struct gprs_nsvc *nsvc, bool reset_flag, uint16_t max_nr_nsvc,
			uint16_t *ip4_ep_nr, uint16_t *ip6_ep_nr)
{
	struct msgb *msg = gprs_ns_msgb_alloc();
	struct gprs_ns_hdr *nsh;
	uint16_t nsei;

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

	if (!nsvc->nsi->bss_sns_fi) {
		LOGP(DNS, LOGL_ERROR, "NSEI=%u Cannot transmit SNS on NSVC without SNS active\n",
		     nsvc->nsei);
		msgb_free(msg);
		return -EIO;
	}

	nsei = osmo_htons(nsvc->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)
		msgb_tv16_put(msg, NS_IE_IPv4_EP_NR, *ip4_ep_nr);
	if (ip6_ep_nr)
		msgb_tv16_put(msg, NS_IE_IPv6_EP_NR, *ip6_ep_nr);

	return gprs_ns_tx(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 gprs_ns_tx_sns_size_ack(struct gprs_nsvc *nsvc, uint8_t *cause)
{
	struct msgb *msg = gprs_ns_msgb_alloc();
	struct gprs_ns_hdr *nsh;
	uint16_t nsei;

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

	if (!nsvc->nsi->bss_sns_fi) {
		LOGP(DNS, LOGL_ERROR, "NSEI=%u Cannot transmit SNS on NSVC without SNS active\n",
		     nsvc->nsei);
		msgb_free(msg);
		return -EIO;
	}

	nsei = osmo_htons(nsvc->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 gprs_ns_tx(nsvc, msg);
}

/*! High-level function for transmitting a NS-UNITDATA messsage
 *  \param[in] nsi NS-instance on which we shall transmit
 *  \param[in] msg struct msgb to be trasnmitted
 *
 * This function obtains the NS-VC by the msgb_nsei(msg) and then checks
 * if the NS-VC is ALIVE and not BLOCKED.  After that, it adds a NS
 * header for the NS-UNITDATA message type and sends it off.
 *
 * Section 9.2.10: transmit side / NS-UNITDATA-REQUEST primitive 
 */
int gprs_ns_sendmsg(struct gprs_ns_inst *nsi, struct msgb *msg)
{
	struct gprs_nsvc *nsvc;
	struct gprs_ns_hdr *nsh;
	uint16_t bvci = msgb_bvci(msg);

	nsvc = gprs_active_nsvc_by_nsei(nsi, msgb_nsei(msg), msgb_bvci(msg));
	if (!nsvc) {
		int rc;
		if (gprs_nsvc_by_nsei(nsi, msgb_nsei(msg))) {
		    LOGP(DNS, LOGL_ERROR,
			 "All NS-VCs for NSEI %u are either dead or blocked!\n",
			 msgb_nsei(msg));
		    rc = -EBUSY;
		} else {
		    LOGP(DNS, LOGL_ERROR, "Unable to resolve NSEI %u "
			 "to NS-VC!\n", msgb_nsei(msg));
		    rc = -EINVAL;
		}

		msgb_free(msg);
		return rc;
	}
	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) {
		LOGP(DNS, LOGL_ERROR, "Not enough headroom for NS header\n");
		msgb_free(msg);
		return -EIO;
	}

	nsh->pdu_type = NS_PDUT_UNITDATA;
	/* spare octet in data[0] */
	nsh->data[1] = bvci >> 8;
	nsh->data[2] = bvci & 0xff;

	return gprs_ns_tx(nsvc, msg);
}

/* Section 9.2.10: receive side */
static int gprs_ns_rx_unitdata(struct gprs_nsvc *nsvc, struct msgb *msg)
{
	struct gprs_ns_hdr *nsh = (struct gprs_ns_hdr *)msg->l2h;
	uint16_t bvci;

	if (nsvc->state & NSE_S_BLOCKED)
		return gprs_ns_tx_status(nsvc, NS_CAUSE_NSVC_BLOCKED,
					 0, msg);

	/* spare octet in data[0] */
	bvci = nsh->data[1] << 8 | nsh->data[2];
	msgb_bssgph(msg) = &nsh->data[3];
	msgb_bvci(msg) = bvci;

	/* call upper layer (BSSGP) */
	return nsvc->nsi->cb(GPRS_NS_EVT_UNIT_DATA, nsvc, msg, bvci);
}

/* Section 9.2.7 */
static int gprs_ns_rx_status(struct gprs_nsvc *nsvc, struct msgb *msg)
{
	struct gprs_ns_hdr *nsh = (struct gprs_ns_hdr *) msg->l2h;
	struct tlv_parsed tp;
	uint8_t cause;
	int rc;

	LOGP(DNS, LOGL_NOTICE, "NSEI=%u Rx NS STATUS ", nsvc->nsei);

	rc = tlv_parse(&tp, &ns_att_tlvdef, nsh->data,
			msgb_l2len(msg) - sizeof(*nsh), 0, 0);
	if (rc < 0) {
		LOGPC(DNS, LOGL_NOTICE, "Error during TLV Parse\n");
		LOGP(DNS, LOGL_ERROR, "NSEI=%u Rx NS STATUS: "
			"Error during TLV Parse\n", nsvc->nsei);
		return rc;
	}

	if (!TLVP_PRESENT(&tp, NS_IE_CAUSE)) {
		LOGPC(DNS, LOGL_INFO, "missing cause IE\n");
		return -EINVAL;
	}

	cause = *TLVP_VAL(&tp, NS_IE_CAUSE);
	LOGPC(DNS, LOGL_NOTICE, "cause=%s\n", gprs_ns_cause_str(cause));

	return 0;
}

/* Replace a nsvc object with another based on NSVCI.
 * This function replaces looks for a NSVC with the given NSVCI and replaces it
 * if possible and necessary. If replaced, the former value of *nsvc is
 * returned in *old_nsvc.
 * \return != 0 if *nsvc points to a matching NSVC.
 */
static int gprs_nsvc_replace_if_found(uint16_t nsvci,
				      struct gprs_nsvc **nsvc,
				      struct gprs_nsvc **old_nsvc)
{
	struct gprs_nsvc *matching_nsvc;

	if ((*nsvc)->nsvci == nsvci) {
		*old_nsvc = NULL;
		return 1;
	}

	matching_nsvc = gprs_nsvc_by_nsvci((*nsvc)->nsi, nsvci);

	if (!matching_nsvc)
		return 0;

	/* The NS-VCI is already used by this NS-VC */

	char *old_peer;

	/* Exchange the NS-VC objects */
	*old_nsvc = *nsvc;
	*nsvc     = matching_nsvc;

	/* Do logging */
	old_peer = talloc_strdup(*old_nsvc, gprs_ns_ll_str(*old_nsvc));
	LOGP(DNS, LOGL_INFO, "NS-VC changed link (NSVCI=%u) from %s to %s\n",
	     nsvci, old_peer, gprs_ns_ll_str(*nsvc));

	talloc_free(old_peer);

	return 1;
}

/* Section 7.3 */
static int gprs_ns_rx_reset(struct gprs_nsvc **nsvc, struct msgb *msg)
{
	struct gprs_ns_hdr *nsh = (struct gprs_ns_hdr *) msg->l2h;
	struct tlv_parsed tp;
	uint8_t cause;
	uint16_t nsvci, nsei;
	struct gprs_nsvc *orig_nsvc = NULL;
	int rc;

	rc = tlv_parse(&tp, &ns_att_tlvdef, nsh->data,
			msgb_l2len(msg) - sizeof(*nsh), 0, 0);
	if (rc < 0) {
		LOGP(DNS, LOGL_ERROR, "NSEI=%u Rx NS RESET "
			"Error during TLV Parse\n", (*nsvc)->nsei);
		return rc;
	}

	if (!TLVP_PRESENT(&tp, NS_IE_CAUSE) ||
	    !TLVP_PRESENT(&tp, NS_IE_VCI) ||
	    !TLVP_PRESENT(&tp, NS_IE_NSEI)) {
		LOGP(DNS, LOGL_ERROR, "NS RESET Missing mandatory IE\n");
		gprs_ns_tx_status(*nsvc, NS_CAUSE_MISSING_ESSENT_IE, 0, msg);
		return -EINVAL;
	}

	cause = *(uint8_t  *) TLVP_VAL(&tp, NS_IE_CAUSE);
	nsvci = tlvp_val16be(&tp, NS_IE_VCI);
	nsei  = tlvp_val16be(&tp, NS_IE_NSEI);

	LOGP(DNS, LOGL_INFO, "NSVCI=%u%s Rx NS RESET (NSEI=%u, NSVCI=%u, cause=%s)\n",
	     (*nsvc)->nsvci, (*nsvc)->nsvci_is_valid ? "" : "(invalid)",
	     nsei, nsvci, gprs_ns_cause_str(cause));

	if ((*nsvc)->nsvci_is_valid && (*nsvc)->nsvci != nsvci) {
		if ((*nsvc)->persistent || (*nsvc)->remote_end_is_sgsn) {
			/* The incoming RESET doesn't match the NSVCI. Send an
			 * appropriate RESET_ACK and ignore the RESET.
			 * See 3GPP TS 08.16, 7.3.1, 2nd paragraph.
			 */
			ns_osmo_signal_dispatch_mismatch(*nsvc, msg,
							 NS_PDUT_RESET,
							 NS_IE_VCI);
			rate_ctr_inc(&(*nsvc)->ctrg->ctr[NS_CTR_INV_VCI]);
			gprs_ns_tx_reset_ack(*nsvc);
			return 0;
		}

		/* NS-VCI has changed */
		if (!gprs_nsvc_replace_if_found(nsvci, nsvc, &orig_nsvc)) {
			LOGP(DNS, LOGL_INFO, "Creating NS-VC %d replacing %d "
			     "at %s\n",
			     nsvci, (*nsvc)->nsvci,
			     gprs_ns_ll_str(*nsvc));
			orig_nsvc = *nsvc;
			*nsvc = gprs_nsvc_create((*nsvc)->nsi, nsvci);
			(*nsvc)->nsei  = nsei;
		}
	}

	if ((*nsvc)->nsvci_is_valid && (*nsvc)->nsei != nsei) {
		if ((*nsvc)->persistent || (*nsvc)->remote_end_is_sgsn) {
			/* The incoming RESET doesn't match the NSEI. Send an
			 * appropriate RESET_ACK and ignore the RESET.
			 * See 3GPP TS 08.16, 7.3.1, 3rd paragraph.
			 */
			ns_osmo_signal_dispatch_mismatch(*nsvc, msg,
							 NS_PDUT_RESET,
							 NS_IE_NSEI);
			rate_ctr_inc(&(*nsvc)->ctrg->ctr[NS_CTR_INV_NSEI]);
			rc = gprs_ns_tx_reset_ack(*nsvc);
			CHECK_TX_RC(rc, *nsvc);
			return 0;
		}

		/* NSEI has changed */
		rate_ctr_inc(&(*nsvc)->ctrg->ctr[NS_CTR_NSEI_CHG]);
		(*nsvc)->nsei = nsei;
	}

	/* Mark NS-VC as blocked and alive */
	ns_set_state(*nsvc, NSE_S_BLOCKED | NSE_S_ALIVE);

	if (orig_nsvc) {
		rate_ctr_inc(&(*nsvc)->ctrg->ctr[NS_CTR_REPLACED]);
		ns_osmo_signal_dispatch_replaced(*nsvc, orig_nsvc);

		/* Update the ll info fields */
		gprs_ns_ll_copy(*nsvc, orig_nsvc);
		gprs_ns_ll_clear(orig_nsvc);
	} else {
		(*nsvc)->nsei  = nsei;
		(*nsvc)->nsvci = nsvci;
		(*nsvc)->nsvci_is_valid = 1;
		rate_ctr_group_upd_idx((*nsvc)->ctrg, nsvci);
		osmo_stat_item_group_udp_idx((*nsvc)->statg, nsvci);
	}

	/* inform interested parties about the fact that this NSVC
	 * has received RESET */
	ns_osmo_signal_dispatch(*nsvc, S_NS_RESET, cause);

	rc = gprs_ns_tx_reset_ack(*nsvc);

	/* start the test procedure */
	gprs_nsvc_start_test(*nsvc);

	return rc;
}

static int gprs_ns_rx_reset_ack(struct gprs_nsvc **nsvc, struct msgb *msg)
{
	struct gprs_ns_hdr *nsh = (struct gprs_ns_hdr *) msg->l2h;
	struct tlv_parsed tp;
	uint16_t nsvci, nsei;
	struct gprs_nsvc *orig_nsvc = NULL;
	int rc;

	rc = tlv_parse(&tp, &ns_att_tlvdef, nsh->data,
			msgb_l2len(msg) - sizeof(*nsh), 0, 0);
	if (rc < 0) {
		LOGP(DNS, LOGL_ERROR, "NSEI=%u Rx NS RESET ACK "
			"Error during TLV Parse\n", (*nsvc)->nsei);
		return rc;
	}

	if (!TLVP_PRESENT(&tp, NS_IE_VCI) ||
	    !TLVP_PRESENT(&tp, NS_IE_NSEI)) {
		LOGP(DNS, LOGL_ERROR, "NS RESET ACK Missing mandatory IE\n");
		rc = gprs_ns_tx_status(*nsvc, NS_CAUSE_MISSING_ESSENT_IE, 0, msg);
		CHECK_TX_RC(rc, *nsvc);
		return -EINVAL;
	}

	nsvci = tlvp_val16be(&tp, NS_IE_VCI);
	nsei  = tlvp_val16be(&tp, NS_IE_NSEI);

	LOGP(DNS, LOGL_INFO, "NSVCI=%u%s Rx NS RESET ACK (NSEI=%u, NSVCI=%u)\n",
	     (*nsvc)->nsvci, (*nsvc)->nsvci_is_valid ? "" : "(invalid)",
	     nsei, nsvci);

	if (!((*nsvc)->state & NSE_S_RESET)) {
		/* Not waiting for a RESET_ACK on this NS-VC, ignore it.
		 * See 3GPP TS 08.16, 7.3.1, 5th paragraph.
		 */
		LOGP(DNS, LOGL_ERROR,
		     "NS RESET ACK Discarding unexpected message for "
		     "NS-VCI %d from SGSN NSEI=%d\n",
		     nsvci, nsei);
		return 0;
	}

	if (!(*nsvc)->nsvci_is_valid) {
		LOGP(DNS, LOGL_NOTICE,
		     "NS RESET ACK Uninitialised NS-VC (%u) for "
		     "NS-VCI %d, NSEI=%d from %s\n",
		     (*nsvc)->nsvci, nsvci, nsei, gprs_ns_ll_str(*nsvc));
		return -EINVAL;
	}

	if ((*nsvc)->nsvci != nsvci) {
		/* NS-VCI has changed */

		/* if !0, use another NSVC object that matches the NSVCI */
		int use_other_nsvc;

		/* Only do this with BSS peers */
		use_other_nsvc = !(*nsvc)->remote_end_is_sgsn &&
			!(*nsvc)->persistent;

		if (use_other_nsvc)
			/* Update *nsvc to point to the right NSVC object */
			use_other_nsvc = gprs_nsvc_replace_if_found(nsvci, nsvc,
								    &orig_nsvc);

		if (!use_other_nsvc) {
			/* The incoming RESET_ACK doesn't match the NSVCI.
			 * See 3GPP TS 08.16, 7.3.1, 4th paragraph.
			 */
			ns_osmo_signal_dispatch_mismatch(*nsvc, msg,
							 NS_PDUT_RESET_ACK,
							 NS_IE_VCI);
			rate_ctr_inc(&(*nsvc)->ctrg->ctr[NS_CTR_INV_VCI]);
			LOGP(DNS, LOGL_ERROR,
			     "NS RESET ACK Unknown NS-VCI %d (%s NSEI=%d) "
			     "from %s\n",
			     nsvci,
			     (*nsvc)->remote_end_is_sgsn ? "SGSN" : "BSS",
			     nsei, gprs_ns_ll_str(*nsvc));
			return -EINVAL;
		}

		/* Notify others */
		rate_ctr_inc(&(*nsvc)->ctrg->ctr[NS_CTR_REPLACED]);
		ns_osmo_signal_dispatch_replaced(*nsvc, orig_nsvc);

		/* Update the ll info fields */
		gprs_ns_ll_copy(*nsvc, orig_nsvc);
		gprs_ns_ll_clear(orig_nsvc);
	} else if ((*nsvc)->nsei != nsei) {
		if ((*nsvc)->persistent || (*nsvc)->remote_end_is_sgsn) {
			/* The incoming RESET_ACK doesn't match the NSEI.
			 * See 3GPP TS 08.16, 7.3.1, 4th paragraph.
			 */
			ns_osmo_signal_dispatch_mismatch(*nsvc, msg,
							 NS_PDUT_RESET_ACK,
							 NS_IE_NSEI);
			rate_ctr_inc(&(*nsvc)->ctrg->ctr[NS_CTR_INV_NSEI]);
			LOGP(DNS, LOGL_ERROR,
			     "NS RESET ACK Unknown NSEI %d (NS-VCI=%u) from %s\n",
			     nsei, nsvci, gprs_ns_ll_str(*nsvc));
			return -EINVAL;
		}

		/* NSEI has changed */
		rate_ctr_inc(&(*nsvc)->ctrg->ctr[NS_CTR_NSEI_CHG]);
		(*nsvc)->nsei = nsei;
	}

	/* Mark NS-VC as blocked and alive */
	ns_set_state(*nsvc, NSE_S_BLOCKED | NSE_S_ALIVE);
	ns_set_remote_state(*nsvc, NSE_S_BLOCKED | NSE_S_ALIVE);
	rate_ctr_inc(&(*nsvc)->ctrg->ctr[NS_CTR_BLOCKED]);
	if ((*nsvc)->persistent || (*nsvc)->remote_end_is_sgsn) {
		/* stop RESET timer */
		osmo_timer_del(&(*nsvc)->timer);
	}
	/* Initiate TEST proc.: Send ALIVE and start timer */
	gprs_nsvc_start_test(*nsvc);

	return 0;
}

static int gprs_ns_rx_block(struct gprs_nsvc *nsvc, struct msgb *msg)
{
	struct gprs_ns_hdr *nsh = (struct gprs_ns_hdr *) msg->l2h;
	struct tlv_parsed tp;
	uint8_t *cause;
	int rc;

	LOGP(DNS, LOGL_INFO, "NSEI=%u Rx NS BLOCK\n", nsvc->nsei);

	ns_mark_blocked(nsvc);

	rc = tlv_parse(&tp, &ns_att_tlvdef, nsh->data,
			msgb_l2len(msg) - sizeof(*nsh), 0, 0);
	if (rc < 0) {
		LOGP(DNS, LOGL_ERROR, "NSEI=%u Rx NS BLOCK "
			"Error during TLV Parse\n", nsvc->nsei);
		return rc;
	}

	if (!TLVP_PRESENT(&tp, NS_IE_CAUSE) ||
	    !TLVP_PRESENT(&tp, NS_IE_VCI)) {
		LOGP(DNS, LOGL_ERROR, "NS RESET Missing mandatory IE\n");
		gprs_ns_tx_status(nsvc, NS_CAUSE_MISSING_ESSENT_IE, 0, msg);
		return -EINVAL;
	}

	cause = (uint8_t *) TLVP_VAL(&tp, NS_IE_CAUSE);
	//nsvci = (uint16_t *) TLVP_VAL(&tp, NS_IE_VCI);

	ns_osmo_signal_dispatch(nsvc, S_NS_BLOCK, *cause);
	rate_ctr_inc(&nsvc->ctrg->ctr[NS_CTR_BLOCKED]);

	return gprs_ns_tx_block_ack(nsvc);
}

int gprs_ns_vc_create(struct gprs_ns_inst *nsi, struct msgb *msg,
		      struct gprs_nsvc *fallback_nsvc,
		      struct gprs_nsvc **new_nsvc);

int gprs_ns_process_msg(struct gprs_ns_inst *nsi, struct msgb *msg,
		      struct gprs_nsvc **nsvc);

/*! Receive incoming NS message from underlying transport layer
 *  \param nsi NS instance to which the data belongs
 *  \param[in] msg message buffer containing newly-received data
 *  \param[in] saddr socketaddr from which data was received
 *  \param[in] ll link-layer type in which data was received
 *  \returns 0 in case of success, < 0 in case of error
 *
 * This is the main entry point int othe NS imlementation where frames
 * from the underlying transport (normally UDP) enter.
 */
int gprs_ns_rcvmsg(struct gprs_ns_inst *nsi, struct msgb *msg,
		   struct sockaddr_in *saddr, enum gprs_ns_ll ll)
{
	struct gprs_nsvc *nsvc;
	int rc = 0;

	/* look up the NSVC based on source address */
	nsvc = gprs_nsvc_by_rem_addr(nsi, saddr);

	if (!nsvc) {
		struct gprs_nsvc *fallback_nsvc;

		fallback_nsvc = nsi->unknown_nsvc;
		log_set_context(LOG_CTX_GB_NSVC, fallback_nsvc);
		fallback_nsvc->ip.bts_addr = *saddr;
		fallback_nsvc->ll = ll;

		rc = gprs_ns_vc_create(nsi, msg, fallback_nsvc, &nsvc);

		if (rc < 0)
			return rc;

		rc = 0;
	}

	if (nsvc)
		rc = gprs_ns_process_msg(nsi, msg, &nsvc);

	return rc;
}

char *gprs_ns_ll_str_buf(char *buf, size_t buf_len, const struct gprs_nsvc *nsvc)
{
	switch(nsvc->ll) {
	case GPRS_NS_LL_UDP:
		snprintf(buf, buf_len, "%s:%u",
			 inet_ntoa(nsvc->ip.bts_addr.sin_addr), osmo_ntohs(nsvc->ip.bts_addr.sin_port));
		break;
	case GPRS_NS_LL_FR_GRE:
		snprintf(buf, buf_len, "%s:%u",
			 inet_ntoa(nsvc->frgre.bts_addr.sin_addr), osmo_ntohs(nsvc->frgre.bts_addr.sin_port));
		break;
	default:
		buf[0] = '\0';
		break;
	}

	buf[buf_len - 1] = '\0';

	return buf;
}

const char *gprs_ns_ll_str(const struct gprs_nsvc *nsvc)
{
	static __thread char buf[80];
	return gprs_ns_ll_str_buf(buf, sizeof(buf), nsvc);
}

char *gprs_ns_ll_str_c(const void *ctx, const struct gprs_nsvc *nsvc)
{
	char *buf = talloc_size(ctx, INET6_ADDRSTRLEN+10);
	if (!buf)
		return buf;
	return gprs_ns_ll_str_buf(buf, INET6_ADDRSTRLEN+10, nsvc);
}

void gprs_ns_ll_copy(struct gprs_nsvc *nsvc, struct gprs_nsvc *other)
{
	nsvc->ll = other->ll;

	switch (nsvc->ll) {
	case GPRS_NS_LL_UDP:
		nsvc->ip = other->ip;
		break;
	case GPRS_NS_LL_FR_GRE:
		nsvc->frgre = other->frgre;
		break;
	default:
		break;
	}
}

void gprs_ns_ll_clear(struct gprs_nsvc *nsvc)
{
	switch (nsvc->ll) {
	case GPRS_NS_LL_UDP:
		nsvc->ip.bts_addr.sin_addr.s_addr = INADDR_ANY;
		nsvc->ip.bts_addr.sin_port        = 0;
		break;
	case GPRS_NS_LL_FR_GRE:
		nsvc->frgre.bts_addr.sin_addr.s_addr = INADDR_ANY;
		nsvc->frgre.bts_addr.sin_port        = 0;
		break;
	default:
		break;
	}
}

/*! Create/get NS-VC independently from underlying transport layer
 *  \param nsi NS instance to which the data belongs
 *  \param[in] msg message buffer containing newly-received data
 *  \param[in] fallback_nsvc is used to send error messages back to the peer
 *             and to initialise the ll info of a created NS-VC object
 *  \param[out] new_nsvc contains a pointer to a NS-VC object if one has
 *              been created or found
 *  \returns < 0 in case of error, GPRS_NS_CS_SKIPPED if a message has been
 *           skipped, GPRS_NS_CS_REJECTED if a message has been rejected and
 *           answered accordingly, GPRS_NS_CS_CREATED if a new NS-VC object
 *           has been created and registered, and GPRS_NS_CS_FOUND if an
 *           existing NS-VC object has been found with the same NSEI.
 *
 * This contains the initial NS automaton state (NS-VC not yet attached).
 */
int gprs_ns_vc_create(struct gprs_ns_inst *nsi, struct msgb *msg,
		      struct gprs_nsvc *fallback_nsvc,
		      struct gprs_nsvc **new_nsvc)
{
	struct gprs_ns_hdr *nsh = (struct gprs_ns_hdr *)msg->l2h;
	struct gprs_nsvc *existing_nsvc;

	struct tlv_parsed tp;
	uint16_t nsvci;
	uint16_t nsei;

	int rc;

	if (nsh->pdu_type == NS_PDUT_STATUS) {
		/* Do not respond, see 3GPP TS 08.16, 7.5.1 */
		LOGP(DNS, LOGL_INFO, "Ignoring NS STATUS from %s "
		     "for non-existing NS-VC\n",
		     gprs_ns_ll_str(fallback_nsvc));
		return GPRS_NS_CS_SKIPPED;
	}

	if (nsh->pdu_type == NS_PDUT_ALIVE_ACK) {
		/* Ignore this, see 3GPP TS 08.16, 7.4.1 */
		LOGP(DNS, LOGL_INFO, "Ignoring NS ALIVE ACK from %s "
		     "for non-existing NS-VC\n",
		     gprs_ns_ll_str(fallback_nsvc));
		return GPRS_NS_CS_SKIPPED;
	}

	if (nsh->pdu_type == NS_PDUT_RESET_ACK) {
		/* Ignore this, see 3GPP TS 08.16, 7.3.1 */
		LOGP(DNS, LOGL_INFO, "Ignoring NS RESET ACK from %s "
		     "for non-existing NS-VC\n",
		     gprs_ns_ll_str(fallback_nsvc));
		return GPRS_NS_CS_SKIPPED;
	}

	/* Only the RESET procedure creates a new NSVC */
	if (nsh->pdu_type != NS_PDUT_RESET) {
		/* Since we have no NSVC, we have to use a fake */
		log_set_context(LOG_CTX_GB_NSVC, fallback_nsvc);
		LOGP(DNS, LOGL_INFO, "Rejecting NS PDU type %s "
		     "from %s for non-existing NS-VC\n",
		     get_value_string(gprs_ns_pdu_strings, nsh->pdu_type), gprs_ns_ll_str(fallback_nsvc));
		fallback_nsvc->nsvci = fallback_nsvc->nsei = 0xfffe;
		fallback_nsvc->nsvci_is_valid = 0;
		ns_set_state(fallback_nsvc, NSE_S_ALIVE);

		rc = gprs_ns_tx_status(fallback_nsvc,
				       NS_CAUSE_PDU_INCOMP_PSTATE, 0, msg);
		if (rc < 0) {
			LOGP(DNS, LOGL_ERROR, "TX failed (%d) to peer %s\n",
				rc, gprs_ns_ll_str(fallback_nsvc));
			return rc;
		}
		return GPRS_NS_CS_REJECTED;
	}

	rc = tlv_parse(&tp, &ns_att_tlvdef, nsh->data,
		       msgb_l2len(msg) - sizeof(*nsh), 0, 0);
	if (rc < 0) {
		LOGP(DNS, LOGL_ERROR, "Rx NS RESET Error %d during "
		     "TLV Parse\n", rc);
		return rc;
	}
	if (!TLVP_PRESENT(&tp, NS_IE_CAUSE) ||
	    !TLVP_PRESENT(&tp, NS_IE_VCI) || !TLVP_PRESENT(&tp, NS_IE_NSEI)) {
		LOGP(DNS, LOGL_ERROR, "NS RESET Missing mandatory IE\n");
		rc = gprs_ns_tx_status(fallback_nsvc, NS_CAUSE_MISSING_ESSENT_IE, 0,
				  msg);
		CHECK_TX_RC(rc, fallback_nsvc);
		return -EINVAL;
	}
	nsvci = tlvp_val16be(&tp, NS_IE_VCI);
	nsei  = tlvp_val16be(&tp, NS_IE_NSEI);
	/* Check if we already know this NSVCI, the remote end might
	 * simply have changed addresses, or it is a SGSN */
	existing_nsvc = gprs_nsvc_by_nsvci(nsi, nsvci);
	if (!existing_nsvc) {
		*new_nsvc = gprs_nsvc_create(nsi, 0xffff);
		(*new_nsvc)->nsvci_is_valid = 0;
		log_set_context(LOG_CTX_GB_NSVC, *new_nsvc);
		gprs_ns_ll_copy(*new_nsvc, fallback_nsvc);
		LOGP(DNS, LOGL_INFO, "Creating NS-VC for BSS at %s\n",
		     gprs_ns_ll_str(fallback_nsvc));

		return GPRS_NS_CS_CREATED;
	}

	/* Check NSEI */
	if (existing_nsvc->nsei != nsei) {
		LOGP(DNS, LOGL_NOTICE,
			"NS-VC changed NSEI (NSVCI=%u) from %u to %u\n",
			nsvci, existing_nsvc->nsei, nsei);

		/* Override old NSEI */
		existing_nsvc->nsei  = nsei;

		/* Do statistics */
		rate_ctr_inc(&existing_nsvc->ctrg->ctr[NS_CTR_NSEI_CHG]);
	}

	*new_nsvc = existing_nsvc;
	gprs_ns_ll_copy(*new_nsvc, fallback_nsvc);
	return GPRS_NS_CS_FOUND;
}

/*! Process NS message independently from underlying transport layer
 *  \param nsi NS instance to which the data belongs
 *  \param[in] msg message buffer containing newly-received data
 *  \param[inout] nsvc refers to the virtual connection, may be modified when
 *                     processing a NS_RESET
 *  \returns 0 in case of success, < 0 in case of error
 *
 * This contains the main NS automaton.
 */
int gprs_ns_process_msg(struct gprs_ns_inst *nsi, struct msgb *msg,
			struct gprs_nsvc **nsvc)
{
	struct gprs_ns_hdr *nsh = (struct gprs_ns_hdr *) msg->l2h;
	struct tlv_parsed tp;
	int rc = 0;

	msgb_nsei(msg) = (*nsvc)->nsei;

	log_set_context(LOG_CTX_GB_NSVC, *nsvc);

	/* Increment number of Incoming bytes */
	rate_ctr_inc(&(*nsvc)->ctrg->ctr[NS_CTR_PKTS_IN]);
	rate_ctr_add(&(*nsvc)->ctrg->ctr[NS_CTR_BYTES_IN], msgb_l2len(msg));

	if (nsvc_is_not_used(*nsvc) && !ns_is_sns(nsh->pdu_type) && nsh->pdu_type != NS_PDUT_STATUS) {
		LOGP(DNS, LOGL_NOTICE, "NSEI=%u Rx %s on unused/pre-configured endpoint, discarding\n",
			(*nsvc)->nsei, get_value_string(gprs_ns_pdu_strings, nsh->pdu_type));
		gprs_ns_tx_status(*nsvc, NS_CAUSE_PROTO_ERR_UNSPEC, 0, msg);
		return 0;
	}

	switch (nsh->pdu_type) {
	case NS_PDUT_ALIVE:
		/* If we're dead and blocked and suddenly receive a
		 * NS-ALIVE out of the blue, we might have been re-started
		 * and should send a NS-RESET to make sure everything recovers
		 * fine. */
		if ((*nsvc)->state == NSE_S_BLOCKED)
			rc = gprs_nsvc_reset((*nsvc), NS_CAUSE_PDU_INCOMP_PSTATE);
		else if (!((*nsvc)->state & NSE_S_RESET))
			rc = gprs_ns_tx_alive_ack(*nsvc);
		break;
	case NS_PDUT_ALIVE_ACK:
		ns_mark_alive(*nsvc);
		if ((*nsvc)->timer_mode == NSVC_TIMER_TNS_ALIVE)
			osmo_stat_item_set((*nsvc)->statg->items[NS_STAT_ALIVE_DELAY],
				nsvc_timer_elapsed_ms(*nsvc));
		/* stop Tns-alive and start Tns-test */
		nsvc_start_timer(*nsvc, NSVC_TIMER_TNS_TEST);
		if ((*nsvc)->remote_end_is_sgsn) {
			/* FIXME: this should be one level higher */
			if ((*nsvc)->state & NSE_S_BLOCKED)
				rc = gprs_ns_tx_unblock(*nsvc);
		}
		break;
	case NS_PDUT_UNITDATA:
		/* actual user data */
		rc = gprs_ns_rx_unitdata(*nsvc, msg);
		break;
	case NS_PDUT_STATUS:
		rc = gprs_ns_rx_status(*nsvc, msg);
		break;
	case NS_PDUT_RESET:
		rc = gprs_ns_rx_reset(nsvc, msg);
		break;
	case NS_PDUT_RESET_ACK:
		rc = gprs_ns_rx_reset_ack(nsvc, msg);
		break;
	case NS_PDUT_UNBLOCK:
		/* Section 7.2: unblocking procedure */
		LOGP(DNS, LOGL_INFO, "NSEI=%u Rx NS UNBLOCK\n", (*nsvc)->nsei);
		ns_mark_unblocked(*nsvc);
		/* This UNBLOCK_ACK message will cause our peer to move us into NS_UNBLOCKED state. */
		rc = gprs_ns_tx_simple(*nsvc, NS_PDUT_UNBLOCK_ACK);
		if (rc < 0)
			break;
		/*
		 * UNBLOCK_ACK has been transmitted.
		 * Signal handlers may send additional messages following UNBLOCK_ACK under
		 * the assumption that NS is now in UNBLOCKED state at our peer's end.
		 */
		ns_osmo_signal_dispatch(*nsvc, S_NS_UNBLOCK, 0);
		break;
	case NS_PDUT_UNBLOCK_ACK:
		LOGP(DNS, LOGL_INFO, "NSEI=%u Rx NS UNBLOCK ACK\n", (*nsvc)->nsei);
		/* mark NS-VC as unblocked + active */
		ns_set_state(*nsvc, NSE_S_ALIVE);
		ns_set_remote_state(*nsvc, NSE_S_ALIVE);
		ns_osmo_signal_dispatch(*nsvc, S_NS_UNBLOCK, 0);
		break;
	case NS_PDUT_BLOCK:
		rc = gprs_ns_rx_block(*nsvc, msg);
		break;
	case NS_PDUT_BLOCK_ACK:
		LOGP(DNS, LOGL_INFO, "NSEI=%u Rx NS BLOCK ACK\n", (*nsvc)->nsei);
		/* mark remote NS-VC as blocked + active */
		ns_set_remote_state(*nsvc, NSE_S_BLOCKED | NSE_S_ALIVE);
		break;
	case SNS_PDUT_CONFIG:
		if (!nsi->bss_sns_fi)
			goto unexpected_sns;
		/* one additional byte ('end flag') before the TLV part starts */
		rc = tlv_parse(&tp, &ns_att_tlvdef, nsh->data+1,
				msgb_l2len(msg) - sizeof(*nsh)-1, 0, 0);
		if (rc < 0) {
			LOGPC(DNS, LOGL_NOTICE, "Error during TLV Parse in %s\n", msgb_hexdump(msg));
			return rc;
		}
		/* All sub-network service related message types */
		rc = gprs_ns_rx_sns(nsi, msg, &tp);
		break;
	case SNS_PDUT_ACK:
	case SNS_PDUT_ADD:
	case SNS_PDUT_CHANGE_WEIGHT:
	case SNS_PDUT_DELETE:
		if (!nsi->bss_sns_fi)
			goto unexpected_sns;
		/* weird layout: NSEI TLV, then value-only transaction IE, then TLV again */
		rc = tlv_parse(&tp, &ns_att_tlvdef, nsh->data+5,
				msgb_l2len(msg) - sizeof(*nsh)-5, 0, 0);
		if (rc < 0) {
			LOGPC(DNS, LOGL_NOTICE, "Error during TLV Parse in %s\n", msgb_hexdump(msg));
			return rc;
		}
		tp.lv[NS_IE_NSEI].val = nsh->data+2;
		tp.lv[NS_IE_NSEI].len = 2;
		tp.lv[NS_IE_TRANS_ID].val = nsh->data+4;
		tp.lv[NS_IE_TRANS_ID].len = 1;
		rc = gprs_ns_rx_sns(nsi, msg, &tp);
		break;
	case SNS_PDUT_CONFIG_ACK:
	case SNS_PDUT_SIZE:
	case SNS_PDUT_SIZE_ACK:
		if (!nsi->bss_sns_fi)
			goto unexpected_sns;
		rc = tlv_parse(&tp, &ns_att_tlvdef, nsh->data,
				msgb_l2len(msg) - sizeof(*nsh), 0, 0);
		if (rc < 0) {
			LOGPC(DNS, LOGL_NOTICE, "Error during TLV Parse in %s\n", msgb_hexdump(msg));
			return rc;
		}
		/* All sub-network service related message types */
		rc = gprs_ns_rx_sns(nsi, msg, &tp);
		break;
	default:
		LOGP(DNS, LOGL_NOTICE, "NSEI=%u Rx Unknown NS PDU type 0x%02x\n",
			(*nsvc)->nsei, nsh->pdu_type);
		rc = -EINVAL;
		break;
unexpected_sns:
		LOGP(DNS, LOGL_NOTICE, "NSEI=%u Rx %s for NS Instance that has no SNS!\n",
			(*nsvc)->nsei, get_value_string(gprs_ns_pdu_strings, nsh->pdu_type));
		rc = -EINVAL;
		break;
	}
	return rc;
}

static bool gprs_sns_fsm_registered = false;

/*! Create a new GPRS NS instance
 *  \param[in] cb Call-back function for incoming BSSGP data
 *  \returns dynamically allocated gprs_ns_inst
 */
struct gprs_ns_inst *gprs_ns_instantiate(gprs_ns_cb_t *cb, void *ctx)
{
	struct gprs_ns_inst *nsi;

	if (!gprs_sns_fsm_registered) {
		int rc = gprs_sns_init();
		if (rc < 0)
			return NULL;
		gprs_sns_fsm_registered = true;
	}

	nsi = talloc_zero(ctx, struct gprs_ns_inst);
	if (!nsi)
		return NULL;
	nsi->cb = cb;
	INIT_LLIST_HEAD(&nsi->gprs_nsvcs);
	nsi->timeout[NS_TOUT_TNS_BLOCK] = 3;
	nsi->timeout[NS_TOUT_TNS_BLOCK_RETRIES] = 3;
	nsi->timeout[NS_TOUT_TNS_RESET] = 3;
	nsi->timeout[NS_TOUT_TNS_RESET_RETRIES] = 3;
	nsi->timeout[NS_TOUT_TNS_TEST] = 30;
	nsi->timeout[NS_TOUT_TNS_ALIVE] = 3;
	nsi->timeout[NS_TOUT_TNS_ALIVE_RETRIES] = 10;
	nsi->timeout[NS_TOUT_TSNS_PROV] = 3; /* 1..10 */

	/* Create the dummy NSVC that we use for sending
	 * messages to non-existant/unknown NS-VC's */
	nsi->unknown_nsvc = gprs_nsvc_create(nsi, 0xfffe);
	nsi->unknown_nsvc->nsvci_is_valid = 0;
	llist_del(&nsi->unknown_nsvc->list);
	INIT_LLIST_HEAD(&nsi->unknown_nsvc->list);

	return nsi;
}

void gprs_ns_close(struct gprs_ns_inst *nsi)
{
	struct gprs_nsvc *nsvc, *nsvc2;

	gprs_nsvc_delete(nsi->unknown_nsvc);

	/* delete all NSVCs and clear their timers */
	llist_for_each_entry_safe(nsvc, nsvc2, &nsi->gprs_nsvcs, list)
		gprs_nsvc_delete(nsvc);

	/* close socket and unregister */
	if (nsi->nsip.fd.data) {
		close(nsi->nsip.fd.fd);
		osmo_fd_unregister(&nsi->nsip.fd);
		nsi->nsip.fd.data = NULL;
	}
}

/*! Destroy an entire NS instance
 *  \param nsi gprs_ns_inst that is to be destroyed
 *
 *  This function releases all resources associated with the
 *  NS-instance.
 */
void gprs_ns_destroy(struct gprs_ns_inst *nsi)
{
	gprs_ns_close(nsi);
	/* free the NSI */
	talloc_free(nsi);
}


/* NS-over-IP code, according to 3GPP TS 48.016 Chapter 6.2
 * We don't support Size Procedure, Configuration Procedure, ChangeWeight Procedure */

/* Read a single NS-over-IP message */
static struct msgb *read_nsip_msg(struct osmo_fd *bfd, int *error,
				  struct sockaddr_in *saddr)
{
	struct msgb *msg = gprs_ns_msgb_alloc();
	int ret = 0;
	socklen_t saddr_len = sizeof(*saddr);

	if (!msg) {
		*error = -ENOMEM;
		return NULL;
	}

	ret = recvfrom(bfd->fd, msg->data, NS_ALLOC_SIZE - NS_ALLOC_HEADROOM, 0,
			(struct sockaddr *)saddr, &saddr_len);
	if (ret < 0) {
		LOGP(DNS, LOGL_ERROR, "recv error %s during NSIP recvfrom %s\n",
		     strerror(errno), osmo_sock_get_name2(bfd->fd));
		msgb_free(msg);
		*error = ret;
		return NULL;
	} else if (ret == 0) {
		msgb_free(msg);
		*error = ret;
		return NULL;
	}

	msg->l2h = msg->data;
	msgb_put(msg, ret);

	return msg;
}

static int handle_nsip_read(struct osmo_fd *bfd)
{
	int error;
	struct sockaddr_in saddr;
	struct gprs_ns_inst *nsi = bfd->data;
	struct msgb *msg = read_nsip_msg(bfd, &error, &saddr);

	if (!msg)
		return error;

	error = gprs_ns_rcvmsg(nsi, msg, &saddr, GPRS_NS_LL_UDP);

	msgb_free(msg);

	return error;
}

static int handle_nsip_write(struct osmo_fd *bfd)
{
	/* FIXME: actually send the data here instead of nsip_sendmsg() */
	return -EIO;
}

static int nsip_sendmsg(struct gprs_nsvc *nsvc, struct msgb *msg)
{
	int rc;
	struct gprs_ns_inst *nsi = nsvc->nsi;
	struct sockaddr_in *daddr = &nsvc->ip.bts_addr;

	rc = sendto(nsi->nsip.fd.fd, msg->data, msg->len, 0,
		  (struct sockaddr *)daddr, sizeof(*daddr));

	msgb_free(msg);

	return rc;
}

/* UDP Port 23000 carries the LLC-in-BSSGP-in-NS protocol stack */
static int nsip_fd_cb(struct osmo_fd *bfd, unsigned int what)
{
	int rc = 0;

	if (what & OSMO_FD_READ)
		rc = handle_nsip_read(bfd);
	if (what & OSMO_FD_WRITE)
		rc = handle_nsip_write(bfd);

	return rc;
}

/*! Create a listening socket for GPRS NS/UDP/IP
 *  \param[in] nsi NS protocol instance to listen
 *  \returns >=0 (fd) in case of success, negative in case of error
 *
 *  A call to this function will create a UDP socket bound to the port
 *  number and IP address specified in the NS protocol instance. The
 *  file descriptor of the socket will be stored in nsi->nsip.fd.
 */
int gprs_ns_nsip_listen(struct gprs_ns_inst *nsi)
{
	struct in_addr in;
	struct in_addr remote;
	char remote_str[INET_ADDRSTRLEN];
	int ret;

	in.s_addr = osmo_htonl(nsi->nsip.local_ip);
	remote.s_addr = osmo_htonl(nsi->nsip.remote_ip);

	nsi->nsip.fd.cb = nsip_fd_cb;
	nsi->nsip.fd.data = nsi;

	if (nsi->nsip.remote_ip && nsi->nsip.remote_port) {
		/* connect to ensure only we only accept packets from the
		 * configured remote end/peer */
		snprintf(remote_str, sizeof(remote_str), "%s", inet_ntoa(remote));
		ret =
		    osmo_sock_init2_ofd(&nsi->nsip.fd, AF_INET, SOCK_DGRAM,
					IPPROTO_UDP, inet_ntoa(in),
					nsi->nsip.local_port, remote_str,
					nsi->nsip.remote_port, OSMO_SOCK_F_BIND | OSMO_SOCK_F_CONNECT);

		LOGP(DNS, LOGL_NOTICE,
		     "Listening for nsip packets from %s:%u on %s:%u\n",
		     remote_str, nsi->nsip.remote_port, inet_ntoa(in), nsi->nsip.local_port);
	} else {
		/* Accept UDP packets from any source IP/Port */
		ret = osmo_sock_init_ofd(&nsi->nsip.fd, AF_INET, SOCK_DGRAM,
					 IPPROTO_UDP, inet_ntoa(in), nsi->nsip.local_port, OSMO_SOCK_F_BIND);

		LOGP(DNS, LOGL_NOTICE, "Listening for nsip packets on %s:%u\n", inet_ntoa(in), nsi->nsip.local_port);
	}

	if (ret < 0) {
		nsi->nsip.fd.cb = NULL;
		nsi->nsip.fd.data = NULL;
		return ret;
	}

	ret = setsockopt(nsi->nsip.fd.fd, IPPROTO_IP, IP_TOS,
				&nsi->nsip.dscp, sizeof(nsi->nsip.dscp));
	if (ret < 0)
		LOGP(DNS, LOGL_ERROR,
			"Failed to set the DSCP to %d with ret(%d) errno(%d)\n",
			nsi->nsip.dscp, ret, errno);

	LOGP(DNS, LOGL_NOTICE, "NS UDP socket at %s:%d\n", inet_ntoa(in), nsi->nsip.local_port);

	return ret;
}

/*! Initiate a RESET procedure
 *  \param[in] nsvc NS-VC in which to start the procedure
 *  \param[in] cause Numeric NS cause value
 *
 * This is a high-level function initiating a NS-RESET procedure. It
 * will not only send a NS-RESET, but also set the state to BLOCKED and
 * start the Tns-reset timer.
 */
int gprs_nsvc_reset(struct gprs_nsvc *nsvc, uint8_t cause)
{
	int rc;

	ERR_IF_NSVC_USES_SNS(nsvc, "RESET procedure based on API request");

	LOGP(DNS, LOGL_INFO, "NSEI=%u RESET procedure based on API request\n",
		nsvc->nsei);

	/* Mark NS-VC locally as blocked and dead */
	ns_set_state(nsvc, NSE_S_BLOCKED | NSE_S_RESET);

	/* Send NS-RESET PDU */
	rc = gprs_ns_tx_reset(nsvc, cause);
	if (rc < 0) {
		LOGP(DNS, LOGL_ERROR, "NSEI=%u, error resetting NS-VC\n",
			nsvc->nsei);
	}
	/* Start Tns-reset */
	nsvc_start_timer(nsvc, NSVC_TIMER_TNS_RESET);

	return rc;
}

/*! Establish a NS connection (from the BSS) to the SGSN
 *  \param nsi NS-instance
 *  \param[in] dest Destination IP/Port
 *  \param[in] nsei NSEI of the to-be-established NS-VC
 *  \param[in] nsvci NSVCI of the to-be-established NS-VC
 *  \returns struct gprs_nsvc representing the new NS-VC
 *
 * This function will establish a single NS/UDP/IP connection in uplink
 * (BSS to SGSN) direction.
 */
struct gprs_nsvc *gprs_ns_nsip_connect(struct gprs_ns_inst *nsi,
				struct sockaddr_in *dest, uint16_t nsei,
				uint16_t nsvci)
{
	struct gprs_nsvc *nsvc;

	nsvc = gprs_nsvc_by_rem_addr(nsi, dest);
	if (!nsvc)
		nsvc = gprs_nsvc_create(nsi, nsvci);
	nsvc->ip.bts_addr = *dest;
	nsvc->nsei = nsei;
	nsvc->remote_end_is_sgsn = 1;

	gprs_nsvc_reset(nsvc, NS_CAUSE_OM_INTERVENTION);
	return nsvc;
}

/*! Establish a NS connection (from the BSS) to the SGSN using SNS auto-configuration
 *  \param nsi NS-instance
 *  \param[in] dest Destination IP/Port
 *  \param[in] nsei NSEI of the to-be-established NS-VC
 *  \param[in] nsvci NSVCI of the to-be-established NS-VC
 *  \returns struct gprs_nsvc representing the new NS-VC
 *
 * This function will establish a single NS/UDP/IP connection in uplink
 * (BSS to SGSN) direction.  It will start with the SNS-SIZE procedure,
 * followed by BSS-originated SNS-CONFIG, then SGSN-originated SNS-CONFIG.
 *
 * Once configuration completes, the user will be notified by the S_SNS_CONFIGURED signal,
 * at which point he typically would want to initiate NS-RESET by means of gprs_nsvc_reset().
 */
struct gprs_nsvc *gprs_ns_nsip_connect_sns(struct gprs_ns_inst *nsi,
				struct sockaddr_in *dest, uint16_t nsei,
				uint16_t nsvci)
{
	struct gprs_nsvc *nsvc;

	/* FIXME: We are getting the order wrong here.  Normally, one would want
	 * to start the SNS FSM *before* creating any NS-VC and then create the NS-VC
	 * after the SNS layer has established the IP/port/etc.  However, this would
	 * require some massive code and API changes compared to existing libosmogb,
	 * so let's keep the old logic. */
	nsvc = gprs_nsvc_by_rem_addr(nsi, dest);
	if (!nsvc) {
		/* create NSVC with 0 data + signalling weight. This is illegal in SNS
		 * and can hence only be created locally and serves as indication that
		 * this NS-VC shall not be used for anything except SNS _unless_ it is
		 * modified via SNS-{CONFIG,CHANGEWEIGHT,ADD} to become part of the
		 * active NS-VCs */
		nsvc = gprs_nsvc_create2(nsi, nsvci, 0, 0);
	}
	nsvc->ip.bts_addr = *dest;
	nsvc->nsei = nsei;
	nsvc->remote_end_is_sgsn = 1;
	/* NSVCs are always UNBLOCKED in IP-SNS */
	ns_set_state(nsvc, 0);

	if (nsi->bss_sns_fi)
		osmo_fsm_inst_term(nsi->bss_sns_fi, OSMO_FSM_TERM_REQUEST, NULL);
	nsi->bss_sns_fi = gprs_sns_bss_fsm_alloc(nsi, nsvc, "NSIP");
	gprs_sns_bss_fsm_start(nsi);
	return nsvc;
}

void gprs_ns_set_log_ss(int ss)
{
	DNS = ss;
}

/*! Append the nsvc state to a talloc string
 * \param s The string to append to (allocated with talloc)
 * \param[in] nsvc The NS-VC to print the state of
 * \returns The new string with state information appended to it
 *
 * This function will append a comma-separated state of the NS-VC to the
 * string. The string needs to be allocated with talloc (e.g. talloc_strdup)
 */
char *gprs_nsvc_state_append(char *s, struct gprs_nsvc *nsvc)
{
	s = talloc_asprintf_append(s,
		"%u,%u,%s,%s,%s,%s,%s\n",
		nsvc->nsei, nsvc->nsvci,
		NS_DESC_A(nsvc->state),
		NS_DESC_B(nsvc->state),
		nsvc->remote_end_is_sgsn ? "SGSN" : "BSS",
		NS_DESC_A(nsvc->remote_state),
		NS_DESC_B(nsvc->remote_state));

	return s;
}

/*! Start the ALIVE timer procedure in all NS-VCs part of this NS Instance */
void gprs_nsvc_start_test(struct gprs_nsvc *nsvc)
{
	/* skip the initial NS-VC unless it has explicitly been configured
	 * via SNS-CONFIG from the SGSN */
	if (nsvc_is_not_used(nsvc))
		return;
	gprs_ns_tx_alive(nsvc);
	nsvc_start_timer(nsvc, NSVC_TIMER_TNS_TEST);
}

void gprs_start_alive_all_nsvcs(struct gprs_ns_inst *nsi)
{
	struct gprs_nsvc *nsvc;
	llist_for_each_entry(nsvc, &nsi->gprs_nsvcs, list) {
		/* start the test procedure */
		gprs_nsvc_start_test(nsvc);
	}
}

/*! @} */
